diff --git a/.travis.yml b/.travis.yml
index 3115098..3f0af57 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,3 +8,5 @@ env:
-
- PREACT_VERSION=5.7.0
- PREACT_VERSION=6.0.2
+ - PREACT_VERSION=7.2.1
+ - PREACT_VERSION=8.1.0
diff --git a/src/CSSTransitionGroup.js b/src/CSSTransitionGroup.js
index 6b4213a..d8fb4e1 100644
--- a/src/CSSTransitionGroup.js
+++ b/src/CSSTransitionGroup.js
@@ -12,7 +12,7 @@
import { h, cloneElement, Component } from 'preact';
-import { getKey } from './util';
+import { getKey, filterNullChildren } from './util';
import { mergeChildMappings, isShownInChildren, isShownInChildrenByKey, inChildren, inChildrenByKey } from './TransitionChildMapping';
import { CSSTransitionGroupChild } from './CSSTransitionGroupChild';
@@ -42,10 +42,10 @@ export class CSSTransitionGroup extends Component {
}
componentWillReceiveProps({ children, exclusive, showProp }) {
- let nextChildMapping = (children || []).slice();
+ let nextChildMapping = filterNullChildren(children || []).slice();
// last props children if exclusive
- let prevChildMapping = exclusive ? this.props.children : this.state.children;
+ let prevChildMapping = filterNullChildren(exclusive ? this.props.children : this.state.children);
let newChildren = mergeChildMappings(
prevChildMapping,
@@ -118,7 +118,7 @@ export class CSSTransitionGroup extends Component {
_handleDoneEntering(key) {
delete this.currentlyTransitioningKeys[key];
- let currentChildMapping = this.props.children,
+ let currentChildMapping = filterNullChildren(this.props.children),
showProp = this.props.showProp;
if (!currentChildMapping || (
!showProp && !inChildrenByKey(currentChildMapping, key)
@@ -157,7 +157,7 @@ export class CSSTransitionGroup extends Component {
_handleDoneLeaving(key) {
delete this.currentlyTransitioningKeys[key];
let showProp = this.props.showProp,
- currentChildMapping = this.props.children;
+ currentChildMapping = filterNullChildren(this.props.children);
if (showProp && currentChildMapping &&
isShownInChildrenByKey(currentChildMapping, key, showProp)) {
this.performEnter(key);
@@ -200,7 +200,7 @@ export class CSSTransitionGroup extends Component {
render({ component:Component, transitionName, transitionEnter, transitionLeave, children:c, ...props }, { children }) {
return (
- { children.map(this.renderChild) }
+ { filterNullChildren(children).map(this.renderChild) }
);
}
diff --git a/src/util.js b/src/util.js
index e581a66..df8943f 100644
--- a/src/util.js
+++ b/src/util.js
@@ -9,3 +9,7 @@ export function getComponentBase(component) {
export function onlyChild(children) {
return children && children[0];
}
+
+export function filterNullChildren(children) {
+ return children && children.filter(i => i !== null);
+}
diff --git a/tests/index.js b/tests/index.js
index 349b051..2774923 100644
--- a/tests/index.js
+++ b/tests/index.js
@@ -83,6 +83,40 @@ class SVGList extends Component {
}
}
+class NullChildren extends Component {
+
+ state = {
+ items: [
+ { displayed: true, item: 'hello'},
+ { displayed: true, item: 'world'},
+ { displayed: false, item: 'click'},
+ { displayed: true, item: 'me'}
+ ]
+ };
+
+ toggleDisplay(i) {
+ let { items } = this.state;
+ const item = items[i];
+ item.displayed = !item.displayed;
+ this.setState({ items });
+ }
+
+ render(_, { items }) {
+ return (
+
+
+ {null}
+
+ { items.map( ({displayed, item}, i) => (
+ displayed ?
+ {item}
+ : null
+ )) }
+
+
+ );
+ }
+}
const Nothing = () => null;
@@ -204,3 +238,63 @@ describe('CSSTransitionGroup: SVG', () => {
}, 1400);
});
});
+
+describe('CSSTransitionGroup: NullChildren', () => {
+ let container = document.createElement('div'),
+ list, root;
+ document.body.appendChild(container);
+
+ let $ = s => [].slice.call(container.querySelectorAll(s));
+
+ beforeEach( () => {
+ root = render(
, container, root);
+ root = render( list=c} />
, container, root);
+ });
+
+ afterEach( () => {
+ list = null;
+ });
+
+ it('create works', () => {
+ expect($('.item')).to.have.length(3);
+ });
+
+ it('transitionLeave works', done => {
+ // this.timeout(5999);
+ list.toggleDisplay(1);
+
+ // make sure -leave class was added
+ setTimeout( () => {
+ expect($('.item')).to.have.length(3);
+
+ expect($('.item')[1].className).to.contain('example-leave');
+ expect($('.item')[1].className).to.contain('example-leave-active');
+ }, 100);
+
+ // then make sure it's gone
+ setTimeout( () => {
+ expect($('.item')).to.have.length(2);
+ done();
+ }, 1400);
+ });
+
+ it('transitionEnter works', done => {
+ // this.timeout(5999);
+ list.toggleDisplay(2);
+
+ setTimeout( () => {
+ expect($('.item')).to.have.length(4);
+ expect($('.item')[2].className).to.contain('example-enter');
+ expect($('.item')[2].className).to.contain('example-enter-active');
+ }, 500);
+
+ setTimeout( () => {
+ expect($('.item')).to.have.length(4);
+
+ expect($('.item')[3].className).not.to.contain('example-enter');
+ expect($('.item')[3].className).not.to.contain('example-enter-active');
+
+ done();
+ }, 1400);
+ });
+});