@@ -11,7 +11,6 @@ import {
1111 parseKeys ,
1212 KeyObject ,
1313} from './util/diff' ;
14- import { ListMotionEndEventHandler } from './interface' ;
1514
1615const MOTION_PROP_NAMES = [
1716 'eventProps' ,
@@ -36,16 +35,24 @@ const MOTION_PROP_NAMES = [
3635 'onLeaveEnd' ,
3736] ;
3837
39- export interface CSSMotionListProps extends Omit < CSSMotionProps , 'onLeaveEnd' > {
38+ export interface CSSMotionListProps
39+ extends Omit < CSSMotionProps , 'onVisibleChanged' > {
4040 keys : ( React . Key | { key : React . Key ; [ name : string ] : any } ) [ ] ;
4141 component ?: string | React . ComponentType | false ;
42- onLeaveEnd ?: ListMotionEndEventHandler ;
42+
43+ /** This will always trigger after final visible changed. Even if no motion configured. */
44+ onVisibleChanged ?: ( visible : boolean , info : { key : React . Key } ) => void ;
4345}
4446
4547export interface CSSMotionListState {
4648 keyEntities : KeyObject [ ] ;
4749}
4850
51+ /**
52+ * Generate a CSSMotionList component with config
53+ * @param transitionSupport No need since CSSMotionList no longer depends on transition support
54+ * @param CSSMotion CSSMotion component
55+ */
4956export function genCSSMotionList (
5057 transitionSupport : boolean ,
5158 CSSMotion = OriginCSSMotion ,
@@ -67,31 +74,11 @@ export function genCSSMotionList(
6774 { keyEntities } : CSSMotionListState ,
6875 ) {
6976 const parsedKeyObjects = parseKeys ( keys ) ;
70-
71- // Always as keep when motion not support
72- if ( ! transitionSupport ) {
73- return {
74- keyEntities : parsedKeyObjects . map ( obj => ( {
75- ...obj ,
76- status : STATUS_KEEP ,
77- } ) ) ,
78- } ;
79- }
80-
8177 const mixedKeyEntities = diffKeys ( keyEntities , parsedKeyObjects ) ;
8278
83- const keyEntitiesLen = keyEntities . length ;
8479 return {
85- keyEntities : mixedKeyEntities . filter ( entity => {
86- // IE 9 not support Array.prototype.find
87- let prevEntity = null ;
88- for ( let i = 0 ; i < keyEntitiesLen ; i += 1 ) {
89- const currentEntity = keyEntities [ i ] ;
90- if ( currentEntity . key === entity . key ) {
91- prevEntity = currentEntity ;
92- break ;
93- }
94- }
80+ keyEntities : mixedKeyEntities . filter ( ( entity ) => {
81+ const prevEntity = keyEntities . find ( ( { key } ) => entity . key === key ) ;
9582
9683 // Remove if already mark as removed
9784 if (
@@ -108,7 +95,7 @@ export function genCSSMotionList(
10895
10996 removeKey = ( removeKey : React . Key ) => {
11097 this . setState ( ( { keyEntities } ) => ( {
111- keyEntities : keyEntities . map ( entity => {
98+ keyEntities : keyEntities . map ( ( entity ) => {
11299 if ( entity . key !== removeKey ) return entity ;
113100 return {
114101 ...entity ,
@@ -120,12 +107,17 @@ export function genCSSMotionList(
120107
121108 render ( ) {
122109 const { keyEntities } = this . state ;
123- const { component, children, onLeaveEnd, ...restProps } = this . props ;
110+ const {
111+ component,
112+ children,
113+ onVisibleChanged,
114+ ...restProps
115+ } = this . props ;
124116
125117 const Component = component || React . Fragment ;
126118
127119 const motionProps : CSSMotionProps = { } ;
128- MOTION_PROP_NAMES . forEach ( prop => {
120+ MOTION_PROP_NAMES . forEach ( ( prop ) => {
129121 motionProps [ prop ] = restProps [ prop ] ;
130122 delete restProps [ prop ] ;
131123 } ) ;
@@ -141,11 +133,12 @@ export function genCSSMotionList(
141133 key = { eventProps . key }
142134 visible = { visible }
143135 eventProps = { eventProps }
144- onLeaveEnd = { ( ...args ) => {
145- if ( onLeaveEnd ) {
146- onLeaveEnd ( ...args , { key : eventProps . key } ) ;
136+ onVisibleChanged = { ( changedVisible ) => {
137+ onVisibleChanged ?.( changedVisible , { key : eventProps . key } ) ;
138+
139+ if ( ! changedVisible ) {
140+ this . removeKey ( eventProps . key ) ;
147141 }
148- this . removeKey ( eventProps . key ) ;
149142 } }
150143 >
151144 { children }
0 commit comments