closing animation in renderers
This commit is contained in:
parent
cc2cfb7c75
commit
6284a3502e
|
@ -11,6 +11,8 @@ const layoutsEqual = (a, b) => (
|
||||||
a === b || (a && b && a.width === b.width && a.height === b.height)
|
a === b || (a && b && a.width === b.width && a.height === b.height)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isFunctional = Component => !Component.prototype.render;
|
||||||
|
|
||||||
export default class MenuContext extends Component {
|
export default class MenuContext extends Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -47,14 +49,17 @@ export default class MenuContext extends Component {
|
||||||
|
|
||||||
closeMenu() {
|
closeMenu() {
|
||||||
debug('close menu');
|
debug('close menu');
|
||||||
this._menuRegistry.getAll().forEach(menu => {
|
const closeAnimation = (this.refs.menuOptions && this.refs.menuOptions.close) || Promise.resolve;
|
||||||
if (menu.instance._getOpened()) {
|
closeAnimation().then(() => {
|
||||||
menu.instance._setOpened(false);
|
this._menuRegistry.getAll().forEach(menu => {
|
||||||
// invalidate trigger layout
|
if (menu.instance._getOpened()) {
|
||||||
this._menuRegistry.updateLayoutInfo(menu.name, { triggerLayout: undefined });
|
menu.instance._setOpened(false);
|
||||||
}
|
// invalidate trigger layout
|
||||||
});
|
this._menuRegistry.updateLayoutInfo(menu.name, { triggerLayout: undefined });
|
||||||
this._notify();
|
}
|
||||||
|
});
|
||||||
|
this._notify();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleMenu(name) {
|
toggleMenu(name) {
|
||||||
|
@ -166,7 +171,11 @@ export default class MenuContext extends Component {
|
||||||
const style = [optionsContainerStyle, customStyles.optionsContainer];
|
const style = [optionsContainerStyle, customStyles.optionsContainer];
|
||||||
const layouts = { windowLayout, triggerLayout, optionsLayout };
|
const layouts = { windowLayout, triggerLayout, optionsLayout };
|
||||||
const props = { style, onLayout, layouts };
|
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 } }) {
|
_onLayout({ nativeEvent: { layout } }) {
|
||||||
|
@ -202,3 +211,4 @@ MenuContext.childContextTypes = {
|
||||||
menuRegistry: React.PropTypes.object,
|
menuRegistry: React.PropTypes.object,
|
||||||
menuActions: React.PropTypes.object,
|
menuActions: React.PropTypes.object,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ export const computePosition = ({ windowLayout, triggerLayout, optionsLayout })
|
||||||
return { top, left };
|
return { top, left };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DURATION = 80;
|
||||||
|
|
||||||
export default class ContextMenu extends React.Component {
|
export default class ContextMenu extends React.Component {
|
||||||
|
|
||||||
|
@ -45,15 +46,25 @@ export default class ContextMenu extends React.Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
scaleAnim: new Animated.Value(0.1),
|
scaleAnim: new Animated.Value(0.1),
|
||||||
};
|
};
|
||||||
|
this.close = this.close.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
Animated.timing(this.state.scaleAnim, {
|
Animated.timing(this.state.scaleAnim, {
|
||||||
duration: 80,
|
duration: DURATION,
|
||||||
toValue: 1
|
toValue: 1
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
Animated.timing(this.state.scaleAnim, {
|
||||||
|
duration: DURATION,
|
||||||
|
toValue: 0
|
||||||
|
}).start(resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { style, children, layouts, ...other } = this.props;
|
const { style, children, layouts, ...other } = this.props;
|
||||||
const animation = {
|
const animation = {
|
||||||
|
|
|
@ -9,6 +9,8 @@ export const computePosition = ({ windowLayout, optionsLayout }) => {
|
||||||
return { top, left };
|
return { top, left };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DURATION = 100;
|
||||||
|
|
||||||
export default class SlideInMenu extends React.Component {
|
export default class SlideInMenu extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -16,15 +18,25 @@ export default class SlideInMenu extends React.Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
slide: new Animated.Value(0),
|
slide: new Animated.Value(0),
|
||||||
};
|
};
|
||||||
|
this.close = this.close.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
Animated.timing(this.state.slide, {
|
Animated.timing(this.state.slide, {
|
||||||
duration: 100,
|
duration: DURATION,
|
||||||
toValue: 1
|
toValue: 1
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
Animated.timing(this.state.slide, {
|
||||||
|
duration: DURATION,
|
||||||
|
toValue: 0
|
||||||
|
}).start(resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { style, children, layouts, ...other } = this.props;
|
const { style, children, layouts, ...other } = this.props;
|
||||||
const { height: oHeight } = layouts.optionsLayout;
|
const { height: oHeight } = layouts.optionsLayout;
|
||||||
|
|
Loading…
Reference in New Issue