Summary: This converts the index file to TypeScript which is used as an export for all plugins. Alongside, I had to fix a couple of errors in various files to make sure everything works correctly. For plugins using flow, we define an interface which uses the type definition for FlipperPlugin and types all UI components as `any`. Reviewed By: passy Differential Revision: D16936890 fbshipit-source-id: dacd9a63a82b9f0bbb530b06072186874cba7b6f
126 lines
3.1 KiB
TypeScript
126 lines
3.1 KiB
TypeScript
/**
|
|
* Copyright 2018-present Facebook.
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
* @format
|
|
*/
|
|
|
|
import React, {Component} from 'react';
|
|
import {Transition} from 'react-transition-group';
|
|
import {TransitionStatus} from 'react-transition-group/Transition';
|
|
import {setActiveSheet} from '../reducers/application';
|
|
import {connect} from 'react-redux';
|
|
import {styled} from 'flipper';
|
|
import {PLUGIN_SHEET_ELEMENT_ID} from '../ui/components/Sheet';
|
|
import {ACTIVE_SHEET_PLUGIN_SHEET} from '../reducers/application';
|
|
import {State as Store} from '../reducers';
|
|
|
|
import {ActiveSheet} from '../reducers/application';
|
|
|
|
const DialogContainer = styled('div')(({state}: {state: TransitionStatus}) => ({
|
|
transform: `translate(-50%, ${
|
|
state === 'entering' || state === 'exiting' || state === 'exited'
|
|
? 'calc(-100% - 20px)'
|
|
: '0%'
|
|
})`,
|
|
opacity: state === 'exited' ? 0 : 1,
|
|
transition: '.3s transform',
|
|
position: 'absolute',
|
|
left: '50%',
|
|
top: 38,
|
|
zIndex: 5,
|
|
backgroundColor: '#EFEEEF',
|
|
border: '1px solid #C6C6C6',
|
|
borderTop: 'none',
|
|
borderBottomLeftRadius: 2,
|
|
borderBottomRightRadius: 2,
|
|
boxShadow: '0 5px 13px rgba(0, 0, 0, 0.2)',
|
|
}));
|
|
|
|
type OwnProps = {
|
|
children: (onHide: () => any) => any;
|
|
};
|
|
|
|
type StateFromProps = {
|
|
activeSheet: ActiveSheet;
|
|
};
|
|
|
|
type DispatchFromProps = {
|
|
onHideSheet: () => void;
|
|
};
|
|
|
|
type State = {
|
|
isVisible: boolean;
|
|
};
|
|
|
|
type Props = OwnProps & StateFromProps & DispatchFromProps;
|
|
class Sheet extends Component<Props, State> {
|
|
state = {
|
|
isVisible: Boolean(this.props.activeSheet),
|
|
};
|
|
|
|
static getDerivedStateFromProps(props: Props) {
|
|
if (!props.activeSheet) {
|
|
return {
|
|
isVisible: true,
|
|
};
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
componentDidMount() {
|
|
document.addEventListener('keydown', this.onKeyDown);
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
document.removeEventListener('keydown', this.onKeyDown);
|
|
}
|
|
|
|
onKeyDown = (e: KeyboardEvent) => {
|
|
if (e.key === 'Escape') {
|
|
this.onHide();
|
|
}
|
|
};
|
|
|
|
onHide = () => {
|
|
this.setState({isVisible: false});
|
|
};
|
|
|
|
render() {
|
|
return (
|
|
<Transition
|
|
in={Boolean(this.props.activeSheet) && this.state.isVisible}
|
|
timeout={300}
|
|
onExited={() => this.props.onHideSheet()}>
|
|
{state => (
|
|
<DialogContainer state={state}>
|
|
<div
|
|
/* This is the target for React.portal, it should not be
|
|
* unmounted, therefore it's hidden, when another sheet
|
|
* is presented. */
|
|
id={PLUGIN_SHEET_ELEMENT_ID}
|
|
style={{
|
|
display:
|
|
this.props.activeSheet === ACTIVE_SHEET_PLUGIN_SHEET
|
|
? 'block'
|
|
: 'none',
|
|
}}
|
|
/>
|
|
{this.props.children(this.onHide)}
|
|
</DialogContainer>
|
|
)}
|
|
</Transition>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default connect<StateFromProps, DispatchFromProps, OwnProps, Store>(
|
|
({application: {activeSheet}}) => ({
|
|
activeSheet,
|
|
}),
|
|
{
|
|
onHideSheet: () => setActiveSheet(null),
|
|
},
|
|
)(Sheet);
|