closing animation in renderers

This commit is contained in:
Martin Bielik 2017-01-05 17:52:10 +01:00
parent cc2cfb7c75
commit 6284a3502e
3 changed files with 44 additions and 11 deletions

View File

@ -11,6 +11,8 @@ const layoutsEqual = (a, b) => (
a === b || (a && b && a.width === b.width && a.height === b.height)
);
const isFunctional = Component => !Component.prototype.render;
export default class MenuContext extends Component {
constructor(props) {
@ -47,14 +49,17 @@ export default class MenuContext extends Component {
closeMenu() {
debug('close menu');
this._menuRegistry.getAll().forEach(menu => {
if (menu.instance._getOpened()) {
menu.instance._setOpened(false);
// invalidate trigger layout
this._menuRegistry.updateLayoutInfo(menu.name, { triggerLayout: undefined });
}
});
this._notify();
const closeAnimation = (this.refs.menuOptions && this.refs.menuOptions.close) || Promise.resolve;
closeAnimation().then(() => {
this._menuRegistry.getAll().forEach(menu => {
if (menu.instance._getOpened()) {
menu.instance._setOpened(false);
// invalidate trigger layout
this._menuRegistry.updateLayoutInfo(menu.name, { triggerLayout: undefined });
}
});
this._notify();
})
}
toggleMenu(name) {
@ -166,7 +171,11 @@ export default class MenuContext extends Component {
const style = [optionsContainerStyle, customStyles.optionsContainer];
const layouts = { windowLayout, triggerLayout, optionsLayout };
const props = { style, onLayout, layouts };
return React.createElement(isOutside ? MenuOutside : renderer, props, optionsRenderer(options));
const optionsType = isOutside ? MenuOutside : renderer;
if (!isFunctional(optionsType)) {
props.ref = 'menuOptions';
}
return React.createElement(optionsType, props, optionsRenderer(options));
}
_onLayout({ nativeEvent: { layout } }) {
@ -202,3 +211,4 @@ MenuContext.childContextTypes = {
menuRegistry: React.PropTypes.object,
menuActions: React.PropTypes.object,
};

View File

@ -37,6 +37,7 @@ export const computePosition = ({ windowLayout, triggerLayout, optionsLayout })
return { top, left };
};
const DURATION = 80;
export default class ContextMenu extends React.Component {
@ -45,15 +46,25 @@ export default class ContextMenu extends React.Component {
this.state = {
scaleAnim: new Animated.Value(0.1),
};
this.close = this.close.bind(this);
}
componentDidMount() {
Animated.timing(this.state.scaleAnim, {
duration: 80,
duration: DURATION,
toValue: 1
}).start();
}
close() {
return new Promise(resolve => {
Animated.timing(this.state.scaleAnim, {
duration: DURATION,
toValue: 0
}).start(resolve);
});
}
render() {
const { style, children, layouts, ...other } = this.props;
const animation = {

View File

@ -9,6 +9,8 @@ export const computePosition = ({ windowLayout, optionsLayout }) => {
return { top, left };
}
const DURATION = 100;
export default class SlideInMenu extends React.Component {
constructor(props) {
@ -16,15 +18,25 @@ export default class SlideInMenu extends React.Component {
this.state = {
slide: new Animated.Value(0),
};
this.close = this.close.bind(this);
}
componentDidMount() {
Animated.timing(this.state.slide, {
duration: 100,
duration: DURATION,
toValue: 1
}).start();
}
close() {
return new Promise(resolve => {
Animated.timing(this.state.slide, {
duration: DURATION,
toValue: 0
}).start(resolve);
});
}
render() {
const { style, children, layouts, ...other } = this.props;
const { height: oHeight } = layouts.optionsLayout;