Skip to content

Commit

Permalink
Fixes (#113)
Browse files Browse the repository at this point in the history
* Add more documentation

* Fix onExited callbacks
  • Loading branch information
jquense committed Jul 14, 2017
1 parent 814a970 commit 2b5b968
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/CSSTransition.js
Expand Up @@ -191,7 +191,7 @@ class CSSTransition extends React.Component {
const { className } = this.getClassNames('exit')

this.removeClasses(node, 'appear');
this.removeClasses(node, 'exit');
this.removeClasses(node, 'enter');
addClass(node, className)

if (this.props.onExit) {
Expand Down
56 changes: 40 additions & 16 deletions src/Transition.js
Expand Up @@ -13,7 +13,7 @@ export const EXITING = 'exiting';
/**
* The Transition component lets you describe a transition from one component
* state to another _over time_ with a simple declarative API. Most commonly
* It's used to animate the mounting and unmounting of Component, but can also
* it's used to animate the mounting and unmounting of a component, but can also
* be used to describe in-place transition states as well.
*
* By default the `Transition` component does not alter the behavior of the
Expand Down Expand Up @@ -50,6 +50,22 @@ export const EXITING = 'exiting';
* );
* ```
*
* As noted the `Transition` component doesn't _do_ anything by itself to its child component.
* What it does do is track transition states over time so you can adjust you
* component (such as adding styles of classes) as it changes states.
*
* There are 4 main states a Transition can be in:
* - `ENTERING`
* - `ENTERED`
* - `EXITING`
* - `EXITED`
*
* Transition state is toggled via the `in` prop. When `true` the component begins the
* "Enter" stage. During this stage, the component will shift from its current transitions state,
* to `'entering'` for the duration of the transition and then to the `'entered'` stage once
* it's complete. So in the following example: `<Transition in timeout={500} />`,
* the component will immediately shift to `'entering'` and stay there for 500ms and switch to `'entered'`.
* When `in` is `false` the same thing happens except the states are `'exiting'` to `'exited'`.
*/
class Transition extends React.Component {
static contextTypes = {
Expand Down Expand Up @@ -280,10 +296,7 @@ class Transition extends React.Component {

Transition.propTypes = {
/**
* Generally a React element to animate, all unknown props on Transition are
* transfered to the **single** child element.
*
* For advanced uses a `function` child can be used instead of a React element.
* A `function` child can be used instead of a React element.
* This function is called with the current transition status
* ('entering', 'entered', 'exiting', 'exited', 'unmounted'), which can used
* to apply context specific props to a component.
Expand All @@ -307,17 +320,25 @@ Transition.propTypes = {
in: PropTypes.bool,

/**
* Wait until the first "enter" transition to mount the component (add it to the DOM)
* By default the child component is mounted immediately along with
* the parent `Transition` component. If you want to "lazy mount" the component on the
* first `in={true}` you can set `mountOnEnter`. After the first enter transition the component will stay
* mounted even on exit unless you also specify `unmountOnExit`
*/
mountOnEnter: PropTypes.bool,

/**
* Unmount the component (remove it from the DOM) when it is not shown
* By default the child component is mounted in the DOM after it enteres the `'exited'` state.
* If you'd prefer to completely unmonut the component after it exits, set `unmountOnExit`.
*/
unmountOnExit: PropTypes.bool,

/**
* Enable or disable appear (entering on mount) transitions.
* Normally a component is not transitioned on it's initial mount. If you
* want to transition on the first mount set `appear` to `true`, and the
* component will enter the component.
*
* > Note: there are no specific "appear" states. `apprear` only an additional `enter` transition.
*/
appear: PropTypes.bool,

Expand Down Expand Up @@ -363,44 +384,47 @@ Transition.propTypes = {
addEndListener: PropTypes.func,

/**
* Callback fired before the "entering" status is applied.
* Callback fired before the "entering" status is applied. An extra parameter
* `isAppearing` is supplied to indicate if the enter stage is occuring on the initial mount
*
* @type Function(node: HtmlElement, isAppearing: bool)
* @type Function(node: HtmlElement, isAppearing: bool) -> void
*/
onEnter: PropTypes.func,

/**
* Callback fired after the "entering" status is applied.
* Callback fired after the "entering" status is applied. An extra parameter
* `isAppearing` is supplied to indicate if the enter stage is occuring on the initial mount
*
* @type Function(node: HtmlElement, isAppearing: bool)
*/
onEntering: PropTypes.func,

/**
* Callback fired after the "enter" status is applied.
* Callback fired after the "enter" status is applied. An extra parameter
* `isAppearing` is supplied to indicate if the enter stage is occuring on the initial mount
*
* @type Function(node: HtmlElement, isAppearing: bool)
* @type Function(node: HtmlElement, isAppearing: bool) -> void
*/
onEntered: PropTypes.func,

/**
* Callback fired before the "exiting" status is applied.
*
* @type Function(node: HtmlElement)
* @type Function(node: HtmlElement) -> void
*/
onExit: PropTypes.func,

/**
* Callback fired after the "exiting" status is applied.
*
* @type Function(node: HtmlElement)
* @type Function(node: HtmlElement) -> void
*/
onExiting: PropTypes.func,

/**
* Callback fired after the "exited" status is applied.
*
* @type Function(node: HtmlElement)
* @type Function(node: HtmlElement) -> void
*/
onExited: PropTypes.func,
};
Expand Down
34 changes: 25 additions & 9 deletions src/TransitionGroup.js
Expand Up @@ -37,10 +37,23 @@ const propTypes = {
* on individual children Transitions.
*/
exit: PropTypes.bool,

/**
* You may need to apply reactive updates to a child as it is exiting.
* This is generally done by using `cloneElement` however in the case of an exiting
* child the element has already been removed and not accessible to the consumer.
*
* If you do need to update a child as it leaves you can provide a `childFactory`
* to wrap every child, even the ones that are leaving.
*
* @type Function(child: ReactElement) -> ReactElement
*/
childFactory: PropTypes.func,
};

const defaultProps = {
component: 'div',
childFactory: child => child,
};

/**
Expand Down Expand Up @@ -111,11 +124,8 @@ class TransitionGroup extends React.Component {
// Initial children should all be entering, dependent on appear
this.state = {
children: getChildMapping(props.children, child => {
const onExited = () => {
if (child.props.onExited)
child.props.onExited();

this.handleExited(child.key);
const onExited = (node) => {
this.handleExited(child.key, node, child.props.onExited);
}

return cloneElement(child, {
Expand Down Expand Up @@ -156,7 +166,9 @@ class TransitionGroup extends React.Component {

if (!isValidElement(child)) return;

const onExited = () => this.handleExited(key);
const onExited = (node) => {
this.handleExited(child.key, node, child.props.onExited);
}

const hasPrev = key in prevChildMapping;
const hasNext = key in nextChildMapping;
Expand Down Expand Up @@ -195,20 +207,24 @@ class TransitionGroup extends React.Component {
this.setState({ children });
}

handleExited = (key) => {
handleExited = (key, node, originalHandler) => {
let currentChildMapping = getChildMapping(this.props.children);

if (key in currentChildMapping) return

if (originalHandler)
originalHandler(node)

this.setState((state) => {
let children = { ...state.children };

delete children[key];
return { children };
});
};

render() {
const { component: Component, ...props } = this.props;
const { component: Component, childFactory, ...props } = this.props;
const { children } = this.state;

delete props.appear;
Expand All @@ -217,7 +233,7 @@ class TransitionGroup extends React.Component {

return (
<Component {...props}>
{values(children)}
{values(children).map(childFactory)}
</Component>
);
}
Expand Down
15 changes: 7 additions & 8 deletions www/package.json
Expand Up @@ -13,14 +13,13 @@
"license": "MIT",
"dependencies": {
"bootstrap": "^4.0.0-alpha.6",
"gatsby": "^1.0.0-beta.7",
"gatsby-link": "^1.0.0-beta.6",
"gatsby-plugin-sass": "^1.0.0-beta.1",
"gatsby-remark-prismjs": "^1.0.0-beta.6",
"gatsby-source-filesystem": "^1.0.0-beta.6",
"gatsby-transformer-react-docgen": "^1.0.0-beta.6",
"gatsby-transformer-remark": "^1.0.0-beta.6",
"graphql-type-json": "^0.1.4",
"gatsby": "^1.0.0",
"gatsby-link": "^1.0.0",
"gatsby-plugin-sass": "^1.0.0",
"gatsby-remark-prismjs": "^1.0.0",
"gatsby-source-filesystem": "^1.0.0",
"gatsby-transformer-react-docgen": "^1.0.0",
"gatsby-transformer-remark": "^1.0.0",
"lodash": "^4.17.4"
},
"devDependencies": {
Expand Down

0 comments on commit 2b5b968

Please sign in to comment.