diff --git a/example/src/example.js b/example/src/example.js index 11070a5..2a7b38c 100644 --- a/example/src/example.js +++ b/example/src/example.js @@ -57,7 +57,9 @@ var Example = class extends React.Component { cholera, when you might eat dinner with a well man in the evening, and the next morning, if you got up early enough, you would see him being hauled by your window in the death-cart. But this new plague was quicker - than that—much quicker.

+ than that—much quicker. +

+

From the moment of the first signs of it, a man would be dead in an hour. Some lasted for several hours. Many died within ten or fifteen @@ -125,7 +127,9 @@ var Example = class extends React.Component { cholera, when you might eat dinner with a well man in the evening, and the next morning, if you got up early enough, you would see him being hauled by your window in the death-cart. But this new plague was quicker - than that—much quicker.

+ than that—much quicker. +

+

From the moment of the first signs of it, a man would be dead in an hour. Some lasted for several hours. Many died within ten or fifteen diff --git a/package.json b/package.json index 6f549e4..eb3ce6b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-animate-height", - "version": "0.9.9", + "version": "0.9.10", "description": "Lightweight, no dependency React component for animating height using CSS transitions.", "main": "lib/AnimateHeight.js", "author": "Stanko", diff --git a/src/AnimateHeight.js b/src/AnimateHeight.js index 228a5d6..6baaff4 100644 --- a/src/AnimateHeight.js +++ b/src/AnimateHeight.js @@ -31,6 +31,15 @@ function omit (obj, ...keys) { return res; } +// Start animation helper using nested requestAnimationFrames +function startAnimationHelper(callback) { + requestAnimationFrame(() => { + requestAnimationFrame(() => { + callback(); + }); + }); +} + const AnimateHeight = class extends React.Component { constructor(props) { super(props); @@ -55,6 +64,13 @@ const AnimateHeight = class extends React.Component { }; } + componentDidMount() { + const { height } = this.state; + + // Hide content if height is 0 (to prevent tabbing into it) + this.hideContent(height); + } + componentWillReceiveProps(nextProps) { const { height, @@ -62,6 +78,10 @@ const AnimateHeight = class extends React.Component { // Check if 'height' prop has changed if (this.contentElement && nextProps.height !== height) { + // Remove display: none from the content div + // if it was hidden to prevent tabbing into it + this.showContent(); + // Cache content height this.contentElement.style.overflow = 'hidden'; const contentHeight = this.contentElement.offsetHeight; @@ -73,9 +93,6 @@ const AnimateHeight = class extends React.Component { overflow: 'hidden', }; const isCurrentHeightAuto = this.state.height === 'auto'; - const FROM_AUTO_TIMEOUT_DURATION = 50; - - clearTimeout(this.timeoutID); if (this.isNumber(nextProps.height)) { // If new height is a number @@ -130,13 +147,12 @@ const AnimateHeight = class extends React.Component { // after setting fixed height above timeoutState.shouldUseTransitions = true; - this.timeoutID = setTimeout(() => { + startAnimationHelper(() => { this.setState(timeoutState); // ANIMATION STARTS, run a callback if it exists this.runCallback(nextProps.onAnimationStart); - - }, FROM_AUTO_TIMEOUT_DURATION); + }); // Set static classes and remove transitions when animation ends this.animationClassesTimeoutID = setTimeout(() => { @@ -145,8 +161,11 @@ const AnimateHeight = class extends React.Component { shouldUseTransitions: false, }); - // ANIMATION ENDS, run a callback if it exists + // ANIMATION ENDS + // Run a callback if it exists this.runCallback(nextProps.onAnimationEnd); + // Hide content if height is 0 (to prevent tabbing into it) + this.hideContent(timeoutState.height); }, nextProps.duration); } else { // ANIMATION STARTS, run a callback if it exists @@ -159,8 +178,11 @@ const AnimateHeight = class extends React.Component { this.setState(timeoutState); - // ANIMATION ENDS, run a callback if it exists + // ANIMATION ENDS + // Run a callback if it exists this.runCallback(nextProps.onAnimationEnd); + // Hide content if height is 0 (to prevent tabbing into it) + this.hideContent(newHeight); }, nextProps.duration); } } @@ -184,6 +206,18 @@ const AnimateHeight = class extends React.Component { } } + showContent() { + if (this.state.height === 0) { + this.contentElement.style.display = ''; + } + } + + hideContent(newHeight) { + if (newHeight === 0) { + this.contentElement.style.display = 'none'; + } + } + getStaticStateClasses(height) { return cx({ [this.animationStateClasses.static]: true,