diff --git a/README.md b/README.md index 3de1bfc..ea348af 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ ReactDom.render( ## Browser Support -|![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png)| +|![IE](https://github.com/alrra/browser-logos/blob/master/src/edge/edge_48x48.png?raw=true) | ![Chrome](https://github.com/alrra/browser-logos/blob/master/src/chrome/chrome_48x48.png?raw=true) | ![Firefox](https://github.com/alrra/browser-logos/blob/master/src/firefox/firefox_48x48.png?raw=true) | ![Opera](https://github.com/alrra/browser-logos/blob/master/src/opera/opera_48x48.png?raw=true) | ![Safari](https://github.com/alrra/browser-logos/blob/master/src/safari/safari_48x48.png?raw=true)| | --- | --- | --- | --- | --- | | IE 8+ ✔ | Chrome 31.0+ ✔ | Firefox 31.0+ ✔ | Opera 30.0+ ✔ | Safari 7.0+ ✔ | @@ -71,10 +71,11 @@ ReactDom.render( | componentProps | Object | null | component is React.Element, component tag props | | animatingClassName | array | `['queue-anim-entering', 'queue-anim-leaving']` | className to every element of animating | | onEnd | function | null | animate end callback({ key, type }), type: `enter` or `leave` | +| animationAttr | string | null | alternate animation attribute to replace `key` | > Above props support array format, like `['left', 'top']`, the secord item is leave config. [Demo](http://react-component.github.io/queue-anim/examples/enter-leave.html) -You must provide the key attribute for all children of QueueAnim, children would not peform any animation without key. +### **You must provide the key attribute or the `animationAttr` value you selected for all children of QueueAnim, children would not peform any animation without this attribute.** ### animConfig diff --git a/src/QueueAnim.jsx b/src/QueueAnim.jsx index c02b70e..244ec15 100644 --- a/src/QueueAnim.jsx +++ b/src/QueueAnim.jsx @@ -31,6 +31,7 @@ class QueueAnim extends React.Component { animatingClassName: PropTypes.array, onEnd: PropTypes.func, appear: PropTypes.bool, + animationAttr: PropTypes.string, }; static defaultProps = { @@ -47,6 +48,7 @@ class QueueAnim extends React.Component { animatingClassName: ['queue-anim-entering', 'queue-anim-leaving'], onEnd: noop, appear: true, + animationAttr: null, }; constructor(props) { @@ -62,13 +64,13 @@ class QueueAnim extends React.Component { const children = toArrayChildren(getChildrenFromProps(props)); const childrenShow = {}; children.forEach(child => { - if (!child || !child.key) { + if (!child || !this.checkChildAnimationAttr(child, props)) { return; } if (this.props.appear) { - this.keysToEnter.push(child.key); + this.keysToEnter.push(this.checkChildAnimationAttr(child, props)); } else { - childrenShow[child.key] = true; + childrenShow[this.checkChildAnimationAttr(child)] = true; } }); this.keysToEnterToCallback = [...this.keysToEnter]; @@ -273,10 +275,10 @@ class QueueAnim extends React.Component { } getChildrenToRender = child => { - if (!child || !child.key) { + if (!child || !this.checkChildAnimationAttr(child, this.props)) { return child; } - const key = child.key; + const key = this.checkChildAnimationAttr(child, this.props); let i = this.keysToLeave.indexOf(key); if ((i >= 0 && this.state.childrenShow[key]) || this.state.childrenShow[key]) { @@ -402,6 +404,10 @@ class QueueAnim extends React.Component { this.props.onEnd({ key, type: 'leave' }); } + checkChildAnimationAttr(child, props) { + return props && props.animationAttr ? props.animationAttr : child.key; + } + render() { const { ...tagProps } = this.props; [ @@ -418,6 +424,7 @@ class QueueAnim extends React.Component { 'enterForcedRePlay', 'onEnd', 'appear', + 'animationAttr', ].forEach(key => delete tagProps[key]); const childrenToRender = toArrayChildren(this.state.children).map(this.getChildrenToRender); const props = { ...tagProps, ...this.props.componentProps }; diff --git a/tests/index.js b/tests/index.js index 0aaac2e..d28d1ab 100644 --- a/tests/index.js +++ b/tests/index.js @@ -76,12 +76,15 @@ describe('rc-queue-anim', () => { return removeIndex; }, render() { + const { unMount, show, items } = this.state; + const attr = 'animationAttr'; + const itemProps = (key, i) => props[attr] ? { [props[attr]]: key, key: i } : { key }; return (
- {!this.state.unMount ? + {!unMount ? { - this.state.show ? - this.state.items.map((item) =>
{item.content}
) : + show ? + items.map((item, i) =>
{item.content}
) : null } {null} @@ -135,6 +138,25 @@ describe('rc-queue-anim', () => { }, 18); }); + it('should have queue animation with dynamic animation attribute', (done) => { + const interval = defaultInterval; + const animationAttr = 'foo'; + const instance = createQueueAnimInstance({ + animationAttr, + }); + shouldAnimatingThisOne(instance, 0); + ticker.timeout(() => { + shouldAnimatingThisOne(instance, 1); + ticker.timeout(() => { + shouldAnimatingThisOne(instance, 2); + ticker.timeout(() => { + shouldAnimatingThisOne(instance, 3); + done(); + }, interval); + }, interval); + }, 18); + }); + it('should have interval', (done) => { const interval = 300; const instance = createQueueAnimInstance({