mirror of
https://github.com/zhigang1992/devhub.git
synced 2026-06-10 06:50:12 +08:00
Improve accordion first animation
Also upgraded react-spring and removed patch
This commit is contained in:
@@ -36,7 +36,7 @@
|
||||
"react-native-splash-screen": "^3.1.1",
|
||||
"react-native-vector-icons": "^6.1.0",
|
||||
"react-redux": "6.0.0",
|
||||
"react-spring": "^8.0.2",
|
||||
"react-spring": "^8.0.4",
|
||||
"react-test-renderer": "16.8.1",
|
||||
"redux": "^4.0.1",
|
||||
"redux-devtools-extension": "^2.13.7",
|
||||
|
||||
@@ -87,7 +87,11 @@ export const ColumnOptionsRenderer = React.memo(
|
||||
zIndex: 200,
|
||||
}}
|
||||
>
|
||||
<AccordionView ref={accordionRef} property="height">
|
||||
<AccordionView
|
||||
ref={accordionRef}
|
||||
accordionKey="accordion-view-column-options-rendered"
|
||||
property="height"
|
||||
>
|
||||
{!!visible && (
|
||||
<ColumnOptions
|
||||
availableHeight={
|
||||
|
||||
@@ -208,7 +208,11 @@ export function ColumnOptionsRow(props: ColumnOptionsRowProps) {
|
||||
</View>
|
||||
</ConditionalWrap>
|
||||
|
||||
<AccordionView property="height">
|
||||
<AccordionView
|
||||
accordionKey={`accordion-view-column-options-row-${title}}`}
|
||||
property="height"
|
||||
skipFirst={opened}
|
||||
>
|
||||
{!!opened && (
|
||||
<View
|
||||
style={[
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useImperativeHandle, useRef, useState } from 'react'
|
||||
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react'
|
||||
import { ScrollView, View } from 'react-native'
|
||||
import { config, ReactSpringHook, useTransition } from 'react-spring/native'
|
||||
|
||||
@@ -8,9 +8,11 @@ import { SpringAnimatedView } from '../animated/spring/SpringAnimatedView'
|
||||
export type Transition = ReactSpringHook
|
||||
|
||||
export interface AccordionViewProps {
|
||||
accordionKey: string
|
||||
children: React.ReactNode
|
||||
fixedSize?: number
|
||||
property: 'width' | 'height'
|
||||
skipFirst?: boolean
|
||||
}
|
||||
|
||||
export interface AccordionView {
|
||||
@@ -20,18 +22,26 @@ export interface AccordionView {
|
||||
unlock: () => void
|
||||
}
|
||||
|
||||
export const AccordionView = React.forwardRef(
|
||||
(props: AccordionViewProps, ref) => {
|
||||
const { children, fixedSize, property } = props
|
||||
export const AccordionView = React.memo(
|
||||
React.forwardRef((props: AccordionViewProps, ref) => {
|
||||
const { accordionKey, children, fixedSize, property, skipFirst } = props
|
||||
|
||||
const openCountRef = useRef(0)
|
||||
const onFinishRef = useRef<null | (() => void)>(null)
|
||||
|
||||
const contentSize = useRef({ width: 0, height: 0 })
|
||||
const [size, setSize] = useState<number | 'auto'>(fixedSize || 0)
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
openCountRef.current = openCountRef.current + 1
|
||||
},
|
||||
[!!children],
|
||||
)
|
||||
|
||||
const transitions = useTransition(
|
||||
children ? [children] : [],
|
||||
() => 'accordion-view',
|
||||
() => accordionKey,
|
||||
{
|
||||
from: { [property]: 0 },
|
||||
enter: { [property]: children ? size : 0 },
|
||||
@@ -40,13 +50,9 @@ export const AccordionView = React.forwardRef(
|
||||
},
|
||||
leave: { [property]: 0 },
|
||||
config: { ...config.default, precision: 1 },
|
||||
immediate: openCountRef.current === 1 && skipFirst,
|
||||
force: false,
|
||||
unique: true,
|
||||
// TODO: API was changed on v8.
|
||||
// Reimplement this or make this hack unnecessary,
|
||||
// fix the nested accordion animation use case in a different way
|
||||
// @see https://github.com/react-spring/react-spring/issues/512
|
||||
/*
|
||||
onRest: (
|
||||
_e: any,
|
||||
state: string,
|
||||
@@ -60,25 +66,28 @@ export const AccordionView = React.forwardRef(
|
||||
onFinishRef.current()
|
||||
}
|
||||
},
|
||||
*/
|
||||
},
|
||||
)
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
setOnFinishListener: (callback: null | (() => void)) => {
|
||||
onFinishRef.current = callback
|
||||
},
|
||||
isLocked: () => {
|
||||
return size === 'auto'
|
||||
},
|
||||
lock: () => {
|
||||
if (size !== 'auto') setSize('auto')
|
||||
},
|
||||
unlock: () => {
|
||||
if (size !== contentSize.current[property])
|
||||
setSize(contentSize.current[property])
|
||||
},
|
||||
}))
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => ({
|
||||
setOnFinishListener: (callback: null | (() => void)) => {
|
||||
onFinishRef.current = callback
|
||||
},
|
||||
isLocked: () => {
|
||||
return size === 'auto'
|
||||
},
|
||||
lock: () => {
|
||||
if (size !== 'auto') setSize('auto')
|
||||
},
|
||||
unlock: () => {
|
||||
if (size !== contentSize.current[property])
|
||||
setSize(contentSize.current[property])
|
||||
},
|
||||
}),
|
||||
[size],
|
||||
)
|
||||
|
||||
const handleContentSizeChange = (width: number, height: number) => {
|
||||
contentSize.current = { width, height }
|
||||
@@ -94,10 +103,12 @@ export const AccordionView = React.forwardRef(
|
||||
{transitions.map(({ key, item, props: animatedStyle }) => (
|
||||
<SpringAnimatedView
|
||||
key={key}
|
||||
style={{
|
||||
...(animatedStyle as any),
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
style={[
|
||||
animatedStyle as any,
|
||||
{
|
||||
overflow: 'hidden',
|
||||
},
|
||||
]}
|
||||
>
|
||||
{Platform.OS === 'web' ? (
|
||||
<View
|
||||
@@ -123,5 +134,5 @@ export const AccordionView = React.forwardRef(
|
||||
))}
|
||||
</>
|
||||
)
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
patch-package
|
||||
deleted file mode 100644
|
||||
--- a/node_modules/react-spring/native-hooks.d.ts
|
||||
+++ /dev/null
|
||||
@@ -1 +0,0 @@
|
||||
-export * from './hooks'
|
||||
--- a/node_modules/react-spring/native.d.ts
|
||||
+++ b/node_modules/react-spring/native.d.ts
|
||||
@@ -1 +1 @@
|
||||
-export * from './renderprops-universal'
|
||||
+export * from './index'
|
||||
--- a/node_modules/react-spring/native.js
|
||||
+++ b/node_modules/react-spring/native.js
|
||||
@@ -2228,7 +2228,7 @@ injectCreateAnimatedStyle(function (styles) {
|
||||
injectAnimatedApi(function (node, mounted, forceUpdate) {
|
||||
return {
|
||||
setNativeProps: function setNativeProps(props) {
|
||||
- var didUpdate = ApplyAnimatedValues(node.current, props);
|
||||
+ var didUpdate = Globals.applyAnimatedValues.fn(node.current, props);
|
||||
if (!didUpdate) mounted.current && forceUpdate();
|
||||
},
|
||||
getNode: function getNode() {
|
||||
--- a/node_modules/react-spring/renderprops-universal.d.ts
|
||||
+++ b/node_modules/react-spring/renderprops-universal.d.ts
|
||||
@@ -3,14 +3,14 @@
|
||||
|
||||
import {
|
||||
Component,
|
||||
- PureComponent,
|
||||
- ReactNode,
|
||||
ComponentClass,
|
||||
+ ComponentPropsWithRef,
|
||||
ComponentType,
|
||||
+ ForwardRefExoticComponent,
|
||||
+ PureComponent,
|
||||
+ ReactNode,
|
||||
ReactType,
|
||||
Ref,
|
||||
- ForwardRefExoticComponent,
|
||||
- ComponentPropsWithRef,
|
||||
} from 'react'
|
||||
|
||||
export type SpringEasingFunc = (t: number) => number
|
||||
@@ -121,11 +121,11 @@ export class Spring<DS extends object> extends PureComponent<SpringProps<DS>> {}
|
||||
|
||||
export function interpolate(
|
||||
parent: number[],
|
||||
- config: (...args: number[]) => any
|
||||
+ config: (...args: number[]) => any,
|
||||
): any
|
||||
|
||||
export function animated<T extends ReactType>(
|
||||
- comp: T
|
||||
+ comp: T,
|
||||
): ForwardRefExoticComponent<ComponentPropsWithRef<T>>
|
||||
|
||||
export type TransitionKeyProps = string | number
|
||||
@@ -180,7 +180,7 @@ export interface TransitionProps<
|
||||
*/
|
||||
keys?:
|
||||
| ((item: TItem) => TransitionKeyProps)
|
||||
- | Array<TransitionKeyProps>
|
||||
+ | TransitionKeyProps[]
|
||||
| TransitionKeyProps
|
||||
/**
|
||||
* An array of items to be displayed, this is used by Transition as the primary means of detecting changes.
|
||||
@@ -193,7 +193,7 @@ export interface TransitionProps<
|
||||
children?: (
|
||||
item: TItem,
|
||||
state: State,
|
||||
- index: number
|
||||
+ index: number,
|
||||
) =>
|
||||
| boolean
|
||||
| null
|
||||
@@ -248,7 +248,7 @@ interface TrailProps<TItem, DS extends object = {}> extends SpringProps {
|
||||
* Item keys (the same keys you'd hand over to react in a list). If you specify items, keys can be an accessor function (item => item.key)
|
||||
* @default item => item
|
||||
*/
|
||||
- keys?: ((item: TItem) => TrailKeyProps) | Array<TrailKeyProps> | TrailKeyProps
|
||||
+ keys?: ((item: TItem) => TrailKeyProps) | TrailKeyProps[] | TrailKeyProps
|
||||
/**
|
||||
* A single function-child that receives the individual item and return a functional component (item, index) => props => view)
|
||||
*/
|
||||
@@ -268,28 +268,28 @@ export class Keyframes<
|
||||
DS extends object
|
||||
> extends PureComponent<KeyframesProps<DS> & S> {
|
||||
static create<S extends object, DS extends object>(
|
||||
- primitive: ComponentType
|
||||
+ primitive: ComponentType,
|
||||
): (states: object) => (props: object) => Keyframes<S, DS>
|
||||
static Spring<S extends object, DS extends object>(
|
||||
- states: object
|
||||
+ states: object,
|
||||
): (
|
||||
- props: object
|
||||
+ props: object,
|
||||
) => Keyframes<
|
||||
S | Pick<SpringProps<DS>, Exclude<keyof SpringProps<DS>, 'to'>>,
|
||||
DS
|
||||
>
|
||||
static Trail<S extends object, DS extends object>(
|
||||
- states: object
|
||||
+ states: object,
|
||||
): (
|
||||
- props: object
|
||||
+ props: object,
|
||||
) => Keyframes<
|
||||
S | Pick<TrailProps<DS>, Exclude<keyof TrailProps<DS>, 'to'>>,
|
||||
DS
|
||||
>
|
||||
static Transition<S extends object, DS extends object>(
|
||||
- states: object
|
||||
+ states: object,
|
||||
): (
|
||||
- props: object
|
||||
+ props: object,
|
||||
) => Keyframes<
|
||||
S | Pick<TransitionProps<S, DS>, Exclude<keyof TransitionProps<DS>, 'to'>>,
|
||||
DS
|
||||
--- a/node_modules/react-spring/web.d.ts
|
||||
+++ b/node_modules/react-spring/web.d.ts
|
||||
@@ -1,9 +1,9 @@
|
||||
import { CSSProperties, RefObject } from 'react'
|
||||
import {
|
||||
- SpringConfig,
|
||||
SpringBaseProps,
|
||||
- TransitionKeyProps,
|
||||
+ SpringConfig,
|
||||
State,
|
||||
+ TransitionKeyProps,
|
||||
} from './renderprops-universal'
|
||||
export { SpringConfig, SpringBaseProps, TransitionKeyProps, State }
|
||||
|
||||
@@ -37,7 +37,7 @@ type ExcludedProps =
|
||||
|
||||
// The config options for an interoplation. It maps out from in "in" type
|
||||
// to an "out" type.
|
||||
-export type InterpolationConfig<T, U = T> = {
|
||||
+export interface InterpolationConfig<T, U = T> {
|
||||
range: T[]
|
||||
output: U[]
|
||||
}
|
||||
@@ -76,7 +76,7 @@ type InferFrom<T extends object> = T extends { to: infer TTo }
|
||||
type Merge<A, B> = { [K in keyof A]: K extends keyof B ? B[K] : A[K] } & B
|
||||
|
||||
export type SetUpdateFn<DS extends object> = (
|
||||
- ds: Pick<DS, Exclude<keyof DS, ExcludedProps>>
|
||||
+ ds: Pick<DS, Exclude<keyof DS, ExcludedProps>>,
|
||||
) => void
|
||||
|
||||
// The hooks do emulate React's 'ref' by accepting { ref?: React.RefObject<Controller> } and
|
||||
@@ -93,11 +93,17 @@ export function useChain(refs: ReadonlyArray<RefObject<ReactSpringHook>>): void
|
||||
export function useChain(
|
||||
refs: ReadonlyArray<RefObject<ReactSpringHook>>,
|
||||
timeSteps: number[],
|
||||
- timeFrame?: number
|
||||
+ timeFrame?: number,
|
||||
): void
|
||||
|
||||
export interface HooksBaseProps
|
||||
extends Pick<SpringBaseProps, Exclude<keyof SpringBaseProps, 'config'>> {
|
||||
+ /**
|
||||
+ * Will skip rendering the component if true and write to the dom directly.
|
||||
+ * @default true
|
||||
+ * @deprecated
|
||||
+ */
|
||||
+ native?: never
|
||||
// there is an undocumented onKeyframesHalt which passes the controller instance,
|
||||
// so it also cannot be typed unless Controller types are written
|
||||
ref?: React.RefObject<ReactSpringHook>
|
||||
@@ -120,51 +126,43 @@ export type UseSpringProps<DS extends object> = Merge<
|
||||
|
||||
// there's a third value in the tuple but it's not public API (?)
|
||||
export function useSpring<DS extends CSSProperties>(
|
||||
- values: UseSpringProps<DS & CSSProperties>
|
||||
+ values: UseSpringProps<DS & CSSProperties>,
|
||||
): ForwardedProps<DS>
|
||||
export function useSpring<DS extends CSSProperties>(
|
||||
- getProps: () => UseSpringProps<DS & CSSProperties>
|
||||
+ getProps: () => UseSpringProps<DS & CSSProperties>,
|
||||
): [ForwardedProps<DS>, SetUpdateFn<DS>]
|
||||
export function useSpring<DS extends object>(
|
||||
- getProps: () => UseSpringProps<DS>
|
||||
+ getProps: () => UseSpringProps<DS>,
|
||||
): [AnimatedValue<ForwardedProps<DS>>, SetUpdateFn<DS>]
|
||||
export function useSpring<DS extends object>(
|
||||
- values: UseSpringProps<DS>
|
||||
+ values: UseSpringProps<DS>,
|
||||
): AnimatedValue<ForwardedProps<DS>>
|
||||
|
||||
// there's a third value in the tuple but it's not public API (?)
|
||||
export function useTrail<DS extends CSSProperties>(
|
||||
count: number,
|
||||
- getProps: () => UseSpringProps<DS & CSSProperties>
|
||||
-): [ForwardedProps<DS>[], SetUpdateFn<DS>]
|
||||
+ getProps: () => UseSpringProps<DS & CSSProperties>,
|
||||
+): [Array<ForwardedProps<DS>>, SetUpdateFn<DS>]
|
||||
export function useTrail<DS extends CSSProperties>(
|
||||
count: number,
|
||||
- values: UseSpringProps<DS & CSSProperties>
|
||||
-): ForwardedProps<DS>[] // safe to modify (result of .map)
|
||||
+ values: UseSpringProps<DS & CSSProperties>,
|
||||
+): Array<ForwardedProps<DS>> // safe to modify (result of .map)
|
||||
export function useTrail<DS extends object>(
|
||||
count: number,
|
||||
- getProps: () => UseSpringProps<DS>
|
||||
-): [AnimatedValue<ForwardedProps<DS>>[], SetUpdateFn<DS>]
|
||||
+ getProps: () => UseSpringProps<DS>,
|
||||
+): [Array<AnimatedValue<ForwardedProps<DS>>>, SetUpdateFn<DS>]
|
||||
export function useTrail<DS extends object>(
|
||||
count: number,
|
||||
- values: UseSpringProps<DS>
|
||||
-): AnimatedValue<ForwardedProps<DS>>[] // safe to modify (result of .map)
|
||||
+ values: UseSpringProps<DS>,
|
||||
+): Array<AnimatedValue<ForwardedProps<DS>>> // safe to modify (result of .map)
|
||||
|
||||
export interface UseTransitionProps<TItem, DS extends object>
|
||||
extends HooksBaseProps {
|
||||
- items: ReadonlyArray<TItem> | null | undefined
|
||||
/**
|
||||
* Spring config, or for individual items: fn(item => config)
|
||||
* @default config.default
|
||||
*/
|
||||
config?: SpringConfig | ((item: TItem) => SpringConfig)
|
||||
- /**
|
||||
- * The same keys you would normally hand over to React in a list. Keys can be specified as a key-accessor function, an array of keys, or a single value
|
||||
- */
|
||||
- keys?:
|
||||
- | ((item: TItem) => TransitionKeyProps)
|
||||
- | ReadonlyArray<TransitionKeyProps>
|
||||
- | TransitionKeyProps
|
||||
|
||||
/**
|
||||
* When true enforces that an item can only occur once instead of allowing two or more items with the same key to co-exist in a stack
|
||||
@@ -201,8 +199,21 @@ export interface UseTransitionResult<TItem, DS extends object> {
|
||||
}
|
||||
|
||||
export function useTransition<TItem, DS extends CSSProperties>(
|
||||
- values: Merge<DS & CSSProperties, UseTransitionProps<TItem, DS>>
|
||||
-): UseTransitionResult<TItem, ForwardedProps<DS>>[] // result array is safe to modify
|
||||
+ items: ReadonlyArray<TItem> | null | undefined,
|
||||
+ keys:
|
||||
+ | ((item: TItem) => TransitionKeyProps)
|
||||
+ | ReadonlyArray<TransitionKeyProps>
|
||||
+ | TransitionKeyProps,
|
||||
+ values: Merge<DS & CSSProperties, UseTransitionProps<TItem, DS>>,
|
||||
+): Array<UseTransitionResult<TItem, ForwardedProps<DS>>> // result array is safe to modify
|
||||
export function useTransition<TItem, DS extends object>(
|
||||
- values: Merge<DS, UseTransitionProps<TItem, DS>>
|
||||
-): UseTransitionResult<TItem, AnimatedValue<ForwardedProps<DS>>>[] // result array is safe to modify
|
||||
\ No newline at end of file
|
||||
+ items: ReadonlyArray<TItem> | null | undefined,
|
||||
+ /**
|
||||
+ * The same keys you would normally hand over to React in a list. Keys can be specified as a key-accessor function, an array of keys, or a single value
|
||||
+ */
|
||||
+ keys:
|
||||
+ | ((item: TItem) => TransitionKeyProps)
|
||||
+ | ReadonlyArray<TransitionKeyProps>
|
||||
+ | TransitionKeyProps,
|
||||
+ values: Merge<DS, UseTransitionProps<TItem, DS>>,
|
||||
+): Array<UseTransitionResult<TItem, AnimatedValue<ForwardedProps<DS>>>> // result array is safe to modify
|
||||
@@ -10650,10 +10650,10 @@ react-scripts@2.1.1:
|
||||
optionalDependencies:
|
||||
fsevents "1.2.4"
|
||||
|
||||
react-spring@^8.0.2:
|
||||
version "8.0.2"
|
||||
resolved "https://registry.npmjs.org/react-spring/-/react-spring-8.0.2.tgz#a17715908c0c0b122c9dd44aba984aa1798d66e1"
|
||||
integrity sha512-E5dVqxwYmsCwvVfp1vdaNRB1p162hSEQZZhqSZuH+9LHDREHixApHX/kQRC1zTmS8jBoqgBILKIxbzsqykqa7g==
|
||||
react-spring@^8.0.4:
|
||||
version "8.0.4"
|
||||
resolved "https://registry.npmjs.org/react-spring/-/react-spring-8.0.4.tgz#410da78ddb1f30a4567492288f9be963aa9c3d30"
|
||||
integrity sha512-cNAs+ChoA4ZcUnVzd0KjJpkZCWOQSO82FtvYS6JlCgt4aRvpg7qbeq5ySTzFnAHo02mj0vhqQWf5MVpBZexuYA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.0.0"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user