Removed some old ui/ components
Summary: Removing old components that are no longer used, and cleaning up index.tsx to prevent future for some of those Reviewed By: nikoant Differential Revision: D29428621 fbshipit-source-id: 78ae51c09510738cf2d75982fdae35b9ef6d2d7e
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1dafe351f7
commit
8e0d3cf779
@@ -49,7 +49,6 @@
|
||||
"p-map": "^4.0.0",
|
||||
"promise-retry": "^2.0.1",
|
||||
"promisify-child-process": "^4.1.0",
|
||||
"prop-types": "^15.6.0",
|
||||
"react": "17.0.2",
|
||||
"react-async": "^10.0.0",
|
||||
"react-debounce-render": "^7.0.0",
|
||||
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
ACTIVE_SHEET_CHANGELOG,
|
||||
} from './reducers/application';
|
||||
import {setStaticView} from './reducers/connections';
|
||||
import SupportRequestFormV2 from './fb-stubs/SupportRequestFormV2';
|
||||
import {Store} from './reducers/';
|
||||
import electron, {MenuItemConstructorOptions} from 'electron';
|
||||
import {notNull} from './utils/typeUtils';
|
||||
@@ -270,7 +269,9 @@ function getTemplate(
|
||||
label: 'Create...',
|
||||
click: function () {
|
||||
// Dispatch an action to open the export screen of Support Request form
|
||||
store.dispatch(setStaticView(SupportRequestFormV2));
|
||||
store.dispatch(
|
||||
setStaticView(require('./fb-stubs/SupportRequestFormV2').default),
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -10,13 +10,11 @@
|
||||
import React, {
|
||||
Component,
|
||||
ReactElement,
|
||||
RefObject,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import {
|
||||
Glyph,
|
||||
FlexColumn,
|
||||
FlexRow,
|
||||
Button,
|
||||
@@ -25,7 +23,6 @@ import {
|
||||
Input,
|
||||
Link,
|
||||
} from '../ui';
|
||||
import LegacyPopover from '../ui/components/Popover2';
|
||||
import {LeftRailButton} from '../sandy-chrome/LeftRail';
|
||||
import GK from '../fb-stubs/GK';
|
||||
import * as UserFeedback from '../fb-stubs/UserFeedback';
|
||||
@@ -36,16 +33,6 @@ import {useStore} from '../utils/useStore';
|
||||
import {isLoggedIn} from '../fb-stubs/user';
|
||||
import {useValue} from 'flipper-plugin';
|
||||
|
||||
type PropsFromState = {
|
||||
sessionId: string | null;
|
||||
};
|
||||
|
||||
type State = {
|
||||
promptData: FeedbackPrompt | null;
|
||||
isShown: boolean;
|
||||
hasTriggered: boolean;
|
||||
};
|
||||
|
||||
type NextAction = 'select-rating' | 'leave-comment' | 'finished';
|
||||
|
||||
class PredefinedComment extends Component<{
|
||||
@@ -277,100 +264,6 @@ class FeedbackComponent extends Component<
|
||||
}
|
||||
}
|
||||
|
||||
class RatingButton extends Component<PropsFromState, State> {
|
||||
state: State = {
|
||||
promptData: null,
|
||||
isShown: false,
|
||||
hasTriggered: false,
|
||||
};
|
||||
|
||||
glyphRef: RefObject<HTMLDivElement> = React.createRef();
|
||||
|
||||
constructor(props: PropsFromState) {
|
||||
super(props);
|
||||
if (GK.get('flipper_enable_star_ratiings')) {
|
||||
UserFeedback.getPrompt().then((prompt) => {
|
||||
this.setState({promptData: prompt});
|
||||
setTimeout(this.triggerPopover.bind(this), 30000);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onClick() {
|
||||
const willBeShown = !this.state.isShown;
|
||||
this.setState({isShown: willBeShown, hasTriggered: true});
|
||||
if (!willBeShown) {
|
||||
UserFeedback.dismiss(this.props.sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
submitRating(rating: number) {
|
||||
UserFeedback.submitRating(rating, this.props.sessionId);
|
||||
}
|
||||
|
||||
submitComment(
|
||||
rating: number,
|
||||
comment: string,
|
||||
selectedPredefinedComments: Array<string>,
|
||||
allowUserInfoSharing: boolean,
|
||||
) {
|
||||
UserFeedback.submitComment(
|
||||
rating,
|
||||
comment,
|
||||
selectedPredefinedComments,
|
||||
allowUserInfoSharing,
|
||||
this.props.sessionId,
|
||||
);
|
||||
}
|
||||
|
||||
triggerPopover() {
|
||||
if (!this.state.hasTriggered) {
|
||||
this.setState({isShown: true, hasTriggered: true});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const promptData = this.state.promptData;
|
||||
if (!promptData) {
|
||||
return null;
|
||||
}
|
||||
if (
|
||||
!promptData.shouldPopup ||
|
||||
(this.state.hasTriggered && !this.state.isShown)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div style={{position: 'relative'}}>
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={this.onClick.bind(this)}
|
||||
ref={this.glyphRef}>
|
||||
<Glyph
|
||||
name="star"
|
||||
color="grey"
|
||||
variant={this.state.isShown ? 'filled' : 'outline'}
|
||||
/>
|
||||
</div>
|
||||
{this.state.isShown ? (
|
||||
<LegacyPopover id="rating-button" targetRef={this.glyphRef}>
|
||||
<FeedbackComponent
|
||||
submitRating={this.submitRating.bind(this)}
|
||||
submitComment={this.submitComment.bind(this)}
|
||||
close={() => {
|
||||
this.setState({isShown: false});
|
||||
}}
|
||||
dismiss={this.onClick.bind(this)}
|
||||
promptData={promptData}
|
||||
/>
|
||||
</LegacyPopover>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function SandyRatingButton() {
|
||||
const [promptData, setPromptData] =
|
||||
useState<UserFeedback.FeedbackPrompt | null>(null);
|
||||
|
||||
@@ -12,7 +12,7 @@ import Client from '../../Client';
|
||||
import {TableBodyRow} from '../../ui/components/table/types';
|
||||
import React, {Component, Fragment} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Text, ManagedTable, styled, colors, Link, Bordered} from '../../ui';
|
||||
import {Text, ManagedTable, styled, colors, Link} from '../../ui';
|
||||
import StatusIndicator from '../../ui/components/StatusIndicator';
|
||||
import {State as Store} from '../../reducers';
|
||||
import {PluginDefinition} from '../../plugin';
|
||||
@@ -28,7 +28,7 @@ const Ellipsis = styled(Text)({
|
||||
whiteSpace: 'nowrap',
|
||||
});
|
||||
|
||||
const TableContainer = styled(Bordered)({
|
||||
const TableContainer = styled.div({
|
||||
marginTop: 10,
|
||||
height: 400,
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ export {keyframes} from '@emotion/css';
|
||||
export {produce} from 'immer';
|
||||
|
||||
export * from './ui/index';
|
||||
export {getStringFromErrorLike, textContent, sleep} from './utils/index';
|
||||
export {textContent, sleep} from './utils/index';
|
||||
export * from './utils/jsonTypes';
|
||||
export {default as GK, loadGKs, loadDistilleryGK} from './fb-stubs/GK';
|
||||
export {default as createPaste} from './fb-stubs/createPaste';
|
||||
@@ -22,48 +22,32 @@ export {
|
||||
graphQLQuery,
|
||||
isLoggedIn,
|
||||
} from './fb-stubs/user';
|
||||
export {
|
||||
FlipperBasePlugin,
|
||||
FlipperPlugin,
|
||||
FlipperDevicePlugin,
|
||||
callClient,
|
||||
BaseAction,
|
||||
} from './plugin';
|
||||
export {FlipperPlugin, FlipperDevicePlugin, BaseAction} from './plugin';
|
||||
export {PluginClient, Props} from './plugin';
|
||||
export {default as Client} from './Client';
|
||||
export {reportUsage} from './utils/metrics';
|
||||
export {default as promiseTimeout} from './utils/promiseTimeout';
|
||||
export {clipboard, remote, OpenDialogOptions} from 'electron';
|
||||
export {default as SupportRequestFormV2} from './fb-stubs/SupportRequestFormV2';
|
||||
export {default as constants} from './fb-stubs/constants';
|
||||
export {connect} from 'react-redux';
|
||||
export {selectPlugin, StaticView} from './reducers/connections';
|
||||
export {writeBufferToFile, bufferToBlob} from './utils/screenshot';
|
||||
export {bufferToBlob} from './utils/screenshot';
|
||||
export {getPluginKey} from './utils/pluginUtils';
|
||||
export {Notification, Idler} from 'flipper-plugin';
|
||||
export {IdlerImpl} from './utils/Idler';
|
||||
export {Store, MiddlewareAPI, State as ReduxState} from './reducers/index';
|
||||
export {Store, State as ReduxState} from './reducers/index';
|
||||
export {default as BaseDevice} from './devices/BaseDevice';
|
||||
export {DeviceLogEntry, LogLevel, DeviceLogListener} from 'flipper-plugin';
|
||||
export {deconstructClientId} from './utils/clientUtils';
|
||||
export {default as isProduction} from './utils/isProduction';
|
||||
export {DetailSidebar} from 'flipper-plugin';
|
||||
export {default as Device} from './devices/BaseDevice';
|
||||
export {default as AndroidDevice} from './devices/AndroidDevice';
|
||||
export {default as MetroDevice} from './devices/MetroDevice';
|
||||
export {default as ArchivedDevice} from './devices/ArchivedDevice';
|
||||
export {default as IOSDevice} from './devices/IOSDevice';
|
||||
export {default as KaiOSDevice} from './devices/KaiOSDevice';
|
||||
export {OS} from './devices/BaseDevice';
|
||||
export {default as Button} from './ui/components/Button';
|
||||
export {default as ToggleButton} from './ui/components/ToggleSwitch';
|
||||
export {default as ButtonNavigationGroup} from './ui/components/ButtonNavigationGroup';
|
||||
export {default as ButtonGroup} from './ui/components/ButtonGroup';
|
||||
export {default as ButtonGroupChain} from './ui/components/ButtonGroupChain';
|
||||
export {colors, darkColors, brandColors} from './ui/components/colors';
|
||||
export {colors, brandColors} from './ui/components/colors';
|
||||
export {default as Glyph} from './ui/components/Glyph';
|
||||
export {default as LoadingIndicator} from './ui/components/LoadingIndicator';
|
||||
export {default as Popover} from './ui/components/Popover';
|
||||
export {
|
||||
TableColumns,
|
||||
TableRows,
|
||||
@@ -72,20 +56,13 @@ export {
|
||||
TableHighlightedRows,
|
||||
TableRowSortOrder,
|
||||
TableColumnOrder,
|
||||
TableColumnOrderVal,
|
||||
TableColumnSizes,
|
||||
} from './ui/components/table/types';
|
||||
export {
|
||||
default as ManagedTable,
|
||||
ManagedTable as ManagedTableClass,
|
||||
} from './ui/components/table/ManagedTable';
|
||||
export {default as ManagedTable} from './ui/components/table/ManagedTable';
|
||||
export {ManagedTableProps} from './ui/components/table/ManagedTable';
|
||||
export {
|
||||
DataValueExtractor,
|
||||
DataInspectorExpanded,
|
||||
DataDescriptionType,
|
||||
DataDescription,
|
||||
DataInspector,
|
||||
MarkerTimeline,
|
||||
} from 'flipper-plugin';
|
||||
export {DataInspector as ManagedDataInspector} from 'flipper-plugin';
|
||||
@@ -96,35 +73,13 @@ export {default as Input} from './ui/components/Input';
|
||||
export {default as Textarea} from './ui/components/Textarea';
|
||||
export {default as Select} from './ui/components/Select';
|
||||
export {default as Checkbox} from './ui/components/Checkbox';
|
||||
export {default as CodeBlock} from './ui/components/CodeBlock';
|
||||
export {default as ErrorBlock} from './ui/components/ErrorBlock';
|
||||
export {ErrorBlockContainer} from './ui/components/ErrorBlock';
|
||||
export {default as ErrorBoundary} from './ui/components/ErrorBoundary';
|
||||
export {OrderableOrder} from './ui/components/Orderable';
|
||||
export {_Interactive as Interactive} from 'flipper-plugin';
|
||||
export {default as Orderable} from './ui/components/Orderable';
|
||||
export {default as VirtualList} from './ui/components/VirtualList';
|
||||
export {Component, PureComponent} from 'react';
|
||||
export {default as ContextMenuProvider} from './ui/components/ContextMenuProvider';
|
||||
export {
|
||||
default as ContextMenu,
|
||||
MenuTemplate,
|
||||
} from './ui/components/ContextMenu';
|
||||
export {FileListFile, FileListFiles} from './ui/components/FileList';
|
||||
export {default as ContextMenu} from './ui/components/ContextMenu';
|
||||
export {FileListFiles} from './ui/components/FileList';
|
||||
export {default as FileList} from './ui/components/FileList';
|
||||
export {default as File} from './ui/components/File';
|
||||
export {
|
||||
DesktopDropdownItem,
|
||||
DesktopDropdownSelectedItem,
|
||||
DesktopDropdown,
|
||||
} from './ui/components/desktop-toolbar';
|
||||
export {default as View} from './ui/components/View';
|
||||
export {default as ViewWithSize} from './ui/components/ViewWithSize';
|
||||
export {default as Block} from './ui/components/Block';
|
||||
export {default as FocusableBox} from './ui/components/FocusableBox';
|
||||
export {default as Sidebar} from './ui/components/Sidebar';
|
||||
export {default as SidebarLabel} from './ui/components/SidebarLabel';
|
||||
export {default as Box} from './ui/components/Box';
|
||||
export {default as FlexBox} from './ui/components/FlexBox';
|
||||
export {default as FlexRow} from './ui/components/FlexRow';
|
||||
export {default as FlexColumn} from './ui/components/FlexColumn';
|
||||
@@ -134,16 +89,10 @@ export {Spacer} from './ui/components/Toolbar';
|
||||
export {default as ToolbarIcon} from './ui/components/ToolbarIcon';
|
||||
export {default as Panel} from './ui/components/Panel';
|
||||
export {default as Text} from './ui/components/Text';
|
||||
export {default as TextParagraph} from './ui/components/TextParagraph';
|
||||
export {default as Link} from './ui/components/Link';
|
||||
export {default as PathBreadcrumbs} from './ui/components/PathBreadcrumbs';
|
||||
export {default as ModalOverlay} from './ui/components/ModalOverlay';
|
||||
export {default as Tooltip} from './ui/components/Tooltip';
|
||||
export {default as TooltipProvider} from './ui/components/TooltipProvider';
|
||||
export {default as ResizeSensor} from './ui/components/ResizeSensor';
|
||||
export {default as StatusIndicator} from './ui/components/StatusIndicator';
|
||||
export {default as HorizontalRule} from './ui/components/HorizontalRule';
|
||||
export {default as VerticalRule} from './ui/components/VerticalRule';
|
||||
export {default as Label} from './ui/components/Label';
|
||||
export {default as Heading} from './ui/components/Heading';
|
||||
export {Filter} from './ui/components/filter/types';
|
||||
@@ -164,7 +113,6 @@ export {
|
||||
ElementsInspectorElement as Element,
|
||||
// TODO: clean up or create namespace
|
||||
ElementsInspectorProps,
|
||||
ElementExtraInfo,
|
||||
ElementAttribute,
|
||||
ElementData,
|
||||
ElementSearchResultSet,
|
||||
@@ -179,8 +127,7 @@ export {getFlipperMediaCDN, appendAccessTokenToUrl} from './fb-stubs/user';
|
||||
export {Rect} from './utils/geometry';
|
||||
export {Logger} from './fb-interfaces/Logger';
|
||||
export {getInstance as getLogger} from './fb-stubs/Logger';
|
||||
export {callVSCode, getVSCodeUrl} from './utils/vscodeUtils';
|
||||
export {useLocalStorageState as useLocalStorage} from 'flipper-plugin';
|
||||
export {callVSCode} from './utils/vscodeUtils';
|
||||
export {checkIdbIsInstalled} from './utils/iOSContainerUtility';
|
||||
export {IDEFileResolver, IDEType} from './fb-stubs/IDEFileResolver';
|
||||
export {renderMockFlipperWithPlugin} from './test-utils/createMockFlipperWithPlugin';
|
||||
|
||||
@@ -29,7 +29,6 @@ import {cache} from '@emotion/css';
|
||||
import {CacheProvider} from '@emotion/react';
|
||||
import {enableMapSet} from 'immer';
|
||||
import os from 'os';
|
||||
import {PopoverProvider} from './ui/components/PopoverProvider';
|
||||
import {initializeFlipperLibImplementation} from './utils/flipperLibImplementation';
|
||||
import {enableConsoleHook} from './chrome/ConsoleLogs';
|
||||
import {sideEffect} from './utils/sideEffect';
|
||||
@@ -131,13 +130,11 @@ class AppFrame extends React.Component<
|
||||
<PersistGate persistor={persistor}>
|
||||
<CacheProvider value={cache}>
|
||||
<TooltipProvider>
|
||||
<PopoverProvider>
|
||||
<ContextMenuProvider>
|
||||
<_NuxManagerContext.Provider value={_createNuxManager()}>
|
||||
<SandyApp />
|
||||
</_NuxManagerContext.Provider>
|
||||
</ContextMenuProvider>
|
||||
</PopoverProvider>
|
||||
</TooltipProvider>
|
||||
</CacheProvider>
|
||||
</PersistGate>
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* 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 from 'react';
|
||||
|
||||
import Bordered from './Bordered';
|
||||
import {colors} from './colors';
|
||||
|
||||
/**
|
||||
* Displays all children in a bordered, zebra styled vertical layout
|
||||
* @deprecated use Layout.Container gap
|
||||
*/
|
||||
const AlternatingRows: React.FC<{
|
||||
children: React.ReactNode[] | React.ReactNode;
|
||||
}> = ({children}) => (
|
||||
<Bordered style={{flexDirection: 'column'}}>
|
||||
{(Array.isArray(children) ? children : [children]).map((child, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
style={{
|
||||
padding: 8,
|
||||
background: idx % 2 === 0 ? colors.light02 : colors.white,
|
||||
}}>
|
||||
{child}
|
||||
</div>
|
||||
))}
|
||||
</Bordered>
|
||||
);
|
||||
|
||||
export default AlternatingRows;
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
/**
|
||||
* A Block styled div
|
||||
* @deprecated use Layout.Container
|
||||
*/
|
||||
const Block = styled.div({
|
||||
display: 'block',
|
||||
});
|
||||
Block.displayName = 'Block';
|
||||
|
||||
export default Block;
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
import {colors} from './colors';
|
||||
|
||||
/**
|
||||
* Puts a gray border around something
|
||||
* @deprecated use Layout.Container
|
||||
*/
|
||||
const Bordered = styled.div({
|
||||
borderRadius: 4,
|
||||
overflow: 'hidden',
|
||||
border: `1px solid ${colors.macOSTitleBarButtonBorder}`,
|
||||
backgroundColor: colors.white,
|
||||
display: 'flex',
|
||||
});
|
||||
Bordered.displayName = 'bordered';
|
||||
|
||||
export default Bordered;
|
||||
@@ -1,24 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import FlexBox from './FlexBox';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
/**
|
||||
* @deprecated use Layout.Container
|
||||
*/
|
||||
const Box = styled(FlexBox)({
|
||||
height: '100%',
|
||||
overflow: 'auto',
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
});
|
||||
Box.displayName = 'Box';
|
||||
|
||||
export default Box;
|
||||
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* 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 from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import Glyph from './Glyph';
|
||||
import {ButtonGroupContext} from './ButtonGroup';
|
||||
|
||||
const IconContainer = styled.div({
|
||||
width: 0,
|
||||
zIndex: 1,
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
pointerEvents: 'none',
|
||||
});
|
||||
IconContainer.displayName = 'ButtonGroupChain:IconContainer';
|
||||
|
||||
const ButtonGroupChainContainer = styled.div<{iconSize: number}>((props) => ({
|
||||
display: 'inline-flex',
|
||||
marginLeft: 10,
|
||||
'&:first-child>*:not(:first-child):nth-child(odd)': {
|
||||
paddingLeft: props.iconSize + 6,
|
||||
},
|
||||
'&:first-child>*': {
|
||||
borderRightStyle: 'none',
|
||||
borderLeftStyle: 'none',
|
||||
},
|
||||
'&:first-child>:first-child': {
|
||||
borderLeftStyle: 'solid',
|
||||
},
|
||||
'&:first-child>:last-child': {
|
||||
borderRightStyle: 'solid',
|
||||
},
|
||||
}));
|
||||
IconContainer.displayName = 'ButtonGroupChain:ButtonGroupChainContainer';
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
* Children.
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* Size of the button seperator icon in pixels.
|
||||
*/
|
||||
iconSize: 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32;
|
||||
/**
|
||||
* Name of the icon seperating the buttons. Defaults to 'chevron-right'.
|
||||
*/
|
||||
icon?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Groups a series of buttons together with
|
||||
* a right-chevron icon to seperate them.
|
||||
* Used to create a navigation heirarchy.
|
||||
*
|
||||
* ```jsx
|
||||
* <ButtonGroupChain iconSize={12}>
|
||||
* <Button>One</Button>
|
||||
* <Button>Two</Button>
|
||||
* <Button>Three</Button>
|
||||
* </ButtonGroupChain>
|
||||
* ```
|
||||
*
|
||||
* @deprecated use Layout.Horizontal with flags: gap pad wrap
|
||||
*/
|
||||
export default function ButtonGroupChain({children, iconSize, icon}: Props) {
|
||||
return (
|
||||
<ButtonGroupContext.Provider value>
|
||||
<ButtonGroupChainContainer iconSize={iconSize}>
|
||||
{React.Children.map(children, (child, idx) => {
|
||||
if (idx === 0) {
|
||||
return child;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<IconContainer>
|
||||
<Glyph name={icon || 'chevron-right'} size={iconSize} />
|
||||
</IconContainer>
|
||||
{child}
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</ButtonGroupChainContainer>
|
||||
</ButtonGroupContext.Provider>
|
||||
);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import ButtonGroup from './ButtonGroup';
|
||||
import Button from './Button';
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* Button group to navigate back and forth.
|
||||
* @deprecated
|
||||
*/
|
||||
export default function ButtonNavigationGroup(props: {
|
||||
/** Back button is enabled */
|
||||
canGoBack: boolean;
|
||||
/** Forwards button is enabled */
|
||||
canGoForward: boolean;
|
||||
/** Callback when back button is clicked */
|
||||
onBack: () => void;
|
||||
/** Callback when forwards button is clicked */
|
||||
onForward: () => void;
|
||||
}) {
|
||||
return (
|
||||
<ButtonGroup>
|
||||
<Button disabled={!props.canGoBack} onClick={props.onBack}>
|
||||
{'<'}
|
||||
</Button>
|
||||
|
||||
<Button disabled={!props.canGoForward} onClick={props.onForward}>
|
||||
{'<'}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
);
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
/**
|
||||
* @deprecated, use CodeBlock from flipper-plugin instead
|
||||
*/
|
||||
const CodeBlock = styled.div({
|
||||
fontFamily: 'monospace',
|
||||
});
|
||||
CodeBlock.displayName = 'CodeBlock';
|
||||
|
||||
export default CodeBlock;
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
import React from 'react';
|
||||
import CodeBlock from './CodeBlock';
|
||||
import {CodeBlock} from 'flipper-plugin';
|
||||
|
||||
export const ErrorBlockContainer = styled(CodeBlock)({
|
||||
backgroundColor: '#f2dede',
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import ErrorBlock from './ErrorBlock';
|
||||
import {CodeBlock} from 'flipper-plugin';
|
||||
import {Component} from 'react';
|
||||
import Heading from './Heading';
|
||||
import Button from './Button';
|
||||
@@ -21,7 +21,7 @@ const ErrorBoundaryContainer = styled(View)({
|
||||
});
|
||||
ErrorBoundaryContainer.displayName = 'ErrorBoundary:ErrorBoundaryContainer';
|
||||
|
||||
const ErrorBoundaryStack = styled(ErrorBlock)({
|
||||
const ErrorBoundaryStack = styled(CodeBlock)({
|
||||
marginBottom: 10,
|
||||
whiteSpace: 'pre',
|
||||
});
|
||||
@@ -79,7 +79,7 @@ export default class ErrorBoundary extends Component<
|
||||
<ErrorBoundaryContainer grow>
|
||||
<Heading>{heading}</Heading>
|
||||
{this.props.showStack !== false && (
|
||||
<ErrorBoundaryStack error={error} />
|
||||
<ErrorBoundaryStack>{error}</ErrorBoundaryStack>
|
||||
)}
|
||||
<Button onClick={this.clearError}>Clear error and try again</Button>
|
||||
</ErrorBoundaryContainer>
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* 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 fs from 'fs';
|
||||
|
||||
type FileProps = {
|
||||
/** Path to the file in the file system */
|
||||
src: string;
|
||||
/** Initial content that should be shown while the file is loading */
|
||||
buffer?: string | null | undefined;
|
||||
/** Encoding to parse the contents of the file. Defaults to UTF-8. */
|
||||
encoding: string;
|
||||
/** Content that should be rendered, when the file loading failed. */
|
||||
onError?: (err: Error) => React.ReactNode;
|
||||
/** Content that should be rendered, while the file is loaded. */
|
||||
onLoading?: () => React.ReactNode;
|
||||
/** Callback when the data is successfully loaded. */
|
||||
onData?: (content: string) => void;
|
||||
/** Content that should be rendered, when the file is successfully loaded. This ususally should render the file's contents. */
|
||||
onLoad: (content: string) => React.ReactNode;
|
||||
};
|
||||
|
||||
type FileState = {
|
||||
error: Error | null | undefined;
|
||||
loaded: boolean;
|
||||
content: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wrapper for loading file content from the file system.
|
||||
*/
|
||||
export default class File extends Component<FileProps, FileState> {
|
||||
constructor(props: FileProps, context: Object) {
|
||||
super(props, context);
|
||||
this.state = {
|
||||
content: props.buffer || '',
|
||||
error: null,
|
||||
loaded: props.buffer != null,
|
||||
};
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
encoding: 'utf8',
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(nextProps: FileProps) {
|
||||
if (nextProps.buffer != null) {
|
||||
return {content: nextProps.buffer, loaded: true};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.state.loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
fs.readFile(this.props.src, this.props.encoding, (err, content) => {
|
||||
if (err) {
|
||||
this.setState({error: err});
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({content, loaded: true});
|
||||
|
||||
if (this.props.onData) {
|
||||
this.props.onData(content);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {onError, onLoad, onLoading} = this.props;
|
||||
const {content, error, loaded} = this.state;
|
||||
|
||||
if (error && onError) {
|
||||
return onError(error);
|
||||
} else if (loaded) {
|
||||
return onLoad(content);
|
||||
} else if (onLoading) {
|
||||
return onLoading();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {Component} from 'react';
|
||||
import Box from './Box';
|
||||
import {colors} from './colors';
|
||||
import styled from '@emotion/styled';
|
||||
import React from 'react';
|
||||
|
||||
const FocusableBoxBorder = styled(Box)({
|
||||
border: `1px solid ${colors.highlight}`,
|
||||
bottom: '0',
|
||||
left: '0',
|
||||
pointerEvents: 'none',
|
||||
position: 'absolute',
|
||||
right: '0',
|
||||
top: '0',
|
||||
});
|
||||
FocusableBoxBorder.displayName = 'FocusableBox:FocusableBoxBorder';
|
||||
|
||||
type Props = {
|
||||
onBlur?: (e: React.FocusEvent) => void;
|
||||
onFocus?: (e: React.FocusEvent) => void;
|
||||
focusable?: boolean;
|
||||
};
|
||||
|
||||
export default class FocusableBox extends Component<
|
||||
Props,
|
||||
{
|
||||
focused: boolean;
|
||||
}
|
||||
> {
|
||||
constructor(props: Props, context: Object) {
|
||||
super(props, context);
|
||||
this.state = {focused: false};
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
focusable: true,
|
||||
};
|
||||
|
||||
onBlur = (e: React.FocusEvent) => {
|
||||
const {onBlur} = this.props;
|
||||
if (onBlur) {
|
||||
onBlur(e);
|
||||
}
|
||||
if (this.state.focused) {
|
||||
this.setState({focused: false});
|
||||
}
|
||||
};
|
||||
|
||||
onFocus = (e: React.FocusEvent) => {
|
||||
const {onFocus} = this.props;
|
||||
if (onFocus) {
|
||||
onFocus(e);
|
||||
}
|
||||
if (this.props.focusable) {
|
||||
this.setState({focused: true});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {props} = this;
|
||||
|
||||
return (
|
||||
<Box {...props} onFocus={this.onFocus} onBlur={this.onBlur} tabIndex={0}>
|
||||
{props.children}
|
||||
{this.state.focused && <FocusableBoxBorder />}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import PropTypes from 'prop-types';
|
||||
import {getIconURL} from '../../utils/icons';
|
||||
|
||||
export type IconSize = 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32;
|
||||
@@ -94,9 +93,6 @@ function ColoredIcon(
|
||||
}
|
||||
}
|
||||
ColoredIcon.displayName = 'Glyph:ColoredIcon';
|
||||
ColoredIcon.contextTypes = {
|
||||
glyphColor: PropTypes.string,
|
||||
};
|
||||
|
||||
export default class Glyph extends React.PureComponent<{
|
||||
name: string;
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import ButtonGroup from './ButtonGroup';
|
||||
import {Component} from 'react';
|
||||
import Button from './Button';
|
||||
import path from 'path';
|
||||
import React from 'react';
|
||||
|
||||
class PathBreadcrumbsItem extends Component<{
|
||||
name: string;
|
||||
path: string;
|
||||
isFolder: boolean;
|
||||
onClick: (path: string) => void;
|
||||
}> {
|
||||
onClick = () => {
|
||||
this.props.onClick(this.props.path);
|
||||
};
|
||||
|
||||
render() {
|
||||
return <Button onClick={this.onClick}>{this.props.name}</Button>;
|
||||
}
|
||||
}
|
||||
|
||||
export default function PathBreadcrumbs(props: {
|
||||
path: string;
|
||||
isFile?: boolean;
|
||||
onClick: (path: string) => void;
|
||||
}) {
|
||||
const parts = props.path === path.sep ? [''] : props.path.split(path.sep);
|
||||
const {onClick} = props;
|
||||
|
||||
return (
|
||||
<ButtonGroup>
|
||||
{parts.map((part, i) => {
|
||||
const fullPath = parts.slice(0, i + 1).join(path.sep) || path.sep;
|
||||
return (
|
||||
<PathBreadcrumbsItem
|
||||
key={`${i}:${part}`}
|
||||
name={part || fullPath}
|
||||
path={fullPath}
|
||||
isFolder={!(props.isFile === true && i === parts.length - 1)}
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ButtonGroup>
|
||||
);
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* 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, {PureComponent} from 'react';
|
||||
import FlexColumn from './FlexColumn';
|
||||
import styled from '@emotion/styled';
|
||||
import {colors} from './colors';
|
||||
|
||||
const Anchor = styled.img({
|
||||
zIndex: 6,
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, calc(100% + 2px))',
|
||||
});
|
||||
Anchor.displayName = 'Popover.Anchor';
|
||||
|
||||
type Opts = {
|
||||
minWidth?: number;
|
||||
skewLeft?: boolean;
|
||||
};
|
||||
|
||||
const PopoverContainer = styled(FlexColumn)<{opts?: Opts}>((props) => ({
|
||||
backgroundColor: colors.white,
|
||||
borderRadius: 7,
|
||||
border: '1px solid rgba(0,0,0,0.3)',
|
||||
boxShadow: '0 2px 10px 0 rgba(0,0,0,0.3)',
|
||||
position: 'absolute',
|
||||
zIndex: 5,
|
||||
bottom: 0,
|
||||
marginTop: 15,
|
||||
left: '50%',
|
||||
minWidth: (props.opts && props.opts.minWidth) || 'auto',
|
||||
transform:
|
||||
props.opts && props.opts.skewLeft
|
||||
? 'translate(calc(-100% + 22px), calc(100% + 15px))'
|
||||
: 'translate(-50%, calc(100% + 15px))',
|
||||
overflow: 'hidden',
|
||||
'&::before': {
|
||||
content: '""',
|
||||
display: 'block',
|
||||
position: 'absolute',
|
||||
left: '50%',
|
||||
transform:
|
||||
props.opts && props.opts.skewLeft
|
||||
? 'translateX(calc(-100% + 22px))'
|
||||
: 'translateX(-50%)',
|
||||
height: 13,
|
||||
top: -13,
|
||||
width: 26,
|
||||
backgroundColor: colors.white,
|
||||
},
|
||||
}));
|
||||
PopoverContainer.displayName = 'Popover:PopoverContainer';
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
onDismiss: Function;
|
||||
forceOpts?: Opts;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated use Popover from antd
|
||||
*/
|
||||
export default class Popover extends PureComponent<Props> {
|
||||
_ref?: Element | null;
|
||||
|
||||
componentDidMount() {
|
||||
window.document.addEventListener('click', this.handleClick);
|
||||
window.document.addEventListener('keydown', this.handleKeydown);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.document.addEventListener('click', this.handleClick);
|
||||
window.document.addEventListener('keydown', this.handleKeydown);
|
||||
}
|
||||
|
||||
handleClick = (e: MouseEvent) => {
|
||||
if (this._ref && !this._ref.contains(e.target as Node)) {
|
||||
this.props.onDismiss();
|
||||
}
|
||||
};
|
||||
|
||||
handleKeydown = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') {
|
||||
this.props.onDismiss();
|
||||
}
|
||||
};
|
||||
|
||||
_setRef = (ref: Element | null) => {
|
||||
this._ref = ref;
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<Anchor src="./anchor.svg" key="anchor" />
|
||||
<PopoverContainer
|
||||
ref={this._setRef}
|
||||
key="popup"
|
||||
opts={this.props.forceOpts || {}}>
|
||||
{this.props.children}
|
||||
</PopoverContainer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* 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, {useEffect, ReactNode} from 'react';
|
||||
import {useContext} from 'react';
|
||||
import {PopoverContext} from './PopoverProvider';
|
||||
|
||||
/**
|
||||
* Popover element to be used as a stopgap until we adopt a
|
||||
* UI framework.
|
||||
* I don't recommend using this, as it will likely be removed in future.
|
||||
* Must be nested under a PopoverProvider at some level, usually it is at the top level app so you shouldn't need to add it.
|
||||
* @deprecated use Popover from Antd
|
||||
*/
|
||||
export default function Popover2(props: {
|
||||
id: string;
|
||||
targetRef: React.RefObject<HTMLElement | null>;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
const popoverManager = useContext(PopoverContext);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.targetRef.current) {
|
||||
popoverManager.open(props.id, props.targetRef, props.children);
|
||||
return () => {
|
||||
popoverManager.close(props.id);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {
|
||||
createContext,
|
||||
useMemo,
|
||||
useState,
|
||||
ReactNode,
|
||||
useEffect,
|
||||
useRef,
|
||||
RefObject,
|
||||
} from 'react';
|
||||
import React from 'react';
|
||||
import {colors, styled} from '../../ui';
|
||||
import {useWindowSize} from '../../utils/useWindowSize';
|
||||
|
||||
type PopoverManager = {
|
||||
open(
|
||||
id: string,
|
||||
targetRef: RefObject<HTMLElement | null>,
|
||||
content: ReactNode,
|
||||
): void;
|
||||
close(id: string): void;
|
||||
};
|
||||
type Popover = {
|
||||
id: string;
|
||||
targetRef: RefObject<HTMLElement | null>;
|
||||
content: ReactNode;
|
||||
};
|
||||
|
||||
const Anchor = styled.img((props: {top: number; left: number}) => ({
|
||||
zIndex: 9999999,
|
||||
position: 'absolute',
|
||||
top: props.top,
|
||||
left: props.left,
|
||||
}));
|
||||
Anchor.displayName = 'Popover.Anchor';
|
||||
const ANCHOR_WIDTH = 34;
|
||||
|
||||
const PopoverContainer = styled('div')(
|
||||
(props: {left: number; top: number; hidden: boolean}) => ({
|
||||
position: 'absolute',
|
||||
top: props.top,
|
||||
left: props.left,
|
||||
zIndex: 9999998,
|
||||
backgroundColor: colors.white,
|
||||
borderRadius: 7,
|
||||
border: '1px solid rgba(0,0,0,0.3)',
|
||||
boxShadow: '0 2px 10px 0 rgba(0,0,0,0.3)',
|
||||
display: props.hidden ? 'none' : 'visible',
|
||||
}),
|
||||
);
|
||||
PopoverContainer.displayName = 'Popover.PopoverContainer';
|
||||
|
||||
const PopoverElement = (props: {
|
||||
targetRef: RefObject<HTMLElement | null>;
|
||||
children: ReactNode;
|
||||
}) => {
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
const [dimensions, setDimensions] = useState<{
|
||||
width: number;
|
||||
height: number;
|
||||
} | null>(null);
|
||||
useEffect(() => {
|
||||
if (!ref.current) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
dimensions?.width !== ref.current.clientWidth ||
|
||||
dimensions?.height !== ref.current.clientHeight
|
||||
) {
|
||||
setDimensions({
|
||||
width: ref.current?.clientWidth,
|
||||
height: ref.current?.clientHeight,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const windowSize = useWindowSize();
|
||||
if (
|
||||
windowSize.height == null ||
|
||||
windowSize.width == null ||
|
||||
props.targetRef.current?.getBoundingClientRect() == null
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// target is the point that the anchor points to.
|
||||
// It is defined as the center of the bottom edge of the target element.
|
||||
const targetXCoord =
|
||||
props.targetRef.current?.getBoundingClientRect().left +
|
||||
props.targetRef.current?.getBoundingClientRect().width / 2;
|
||||
const targetYCoord = props.targetRef.current?.getBoundingClientRect().bottom;
|
||||
return (
|
||||
<>
|
||||
<Anchor
|
||||
top={targetYCoord}
|
||||
left={targetXCoord - ANCHOR_WIDTH / 2}
|
||||
src="./anchor.svg"
|
||||
key="anchor"
|
||||
/>
|
||||
<PopoverContainer
|
||||
ref={ref}
|
||||
hidden={ref.current === null}
|
||||
top={
|
||||
Math.min(
|
||||
targetYCoord,
|
||||
windowSize.height - (dimensions?.height ?? 0),
|
||||
) + 13
|
||||
}
|
||||
left={Math.min(
|
||||
targetXCoord - (dimensions?.width ?? 0) / 2,
|
||||
windowSize.width - (dimensions?.width ?? 0),
|
||||
)}>
|
||||
{props.children}
|
||||
</PopoverContainer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const PopoverContext = createContext<PopoverManager>(undefined as any);
|
||||
|
||||
export function PopoverProvider({children}: {children: React.ReactNode}) {
|
||||
const [popovers, setPopovers] = useState<Popover[]>([]);
|
||||
const popoverManager = useMemo(
|
||||
() => ({
|
||||
open: (
|
||||
id: string,
|
||||
targetRef: RefObject<HTMLElement | null>,
|
||||
content: ReactNode,
|
||||
) => {
|
||||
setPopovers((s) => [...s, {id, targetRef: targetRef, content}]);
|
||||
},
|
||||
close: (id: string) => {
|
||||
setPopovers((s) => s.filter((p) => p.id !== id));
|
||||
},
|
||||
}),
|
||||
[],
|
||||
);
|
||||
return (
|
||||
<>
|
||||
{popovers.map((p, index) => (
|
||||
<PopoverElement key={index} targetRef={p.targetRef}>
|
||||
{p.content}
|
||||
</PopoverElement>
|
||||
))}
|
||||
<PopoverContext.Provider value={popoverManager}>
|
||||
{children}
|
||||
</PopoverContext.Provider>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
import {Component} from 'react';
|
||||
import React from 'react';
|
||||
|
||||
const IFrame = styled.iframe({
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
border: 'none',
|
||||
background: 'transparent',
|
||||
position: 'absolute',
|
||||
zIndex: -1,
|
||||
top: 0,
|
||||
left: 0,
|
||||
});
|
||||
IFrame.displayName = 'ResizeSensor:IFrame';
|
||||
|
||||
/**
|
||||
* Listener for resize events.
|
||||
*/
|
||||
export default class ResizeSensor extends Component<{
|
||||
/** Callback when resize happened */
|
||||
onResize: (e: UIEvent) => void;
|
||||
}> {
|
||||
iframe: HTMLIFrameElement | undefined | null;
|
||||
|
||||
setRef = (ref: HTMLIFrameElement | null) => {
|
||||
this.iframe = ref;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <IFrame ref={this.setRef} />;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const {iframe} = this;
|
||||
if (iframe && iframe.contentWindow != null) {
|
||||
iframe.contentWindow.addEventListener('resize', this.handleResize);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const {iframe} = this;
|
||||
if (iframe && iframe.contentWindow != null) {
|
||||
iframe.contentWindow.removeEventListener('resize', this.handleResize);
|
||||
}
|
||||
}
|
||||
|
||||
handleResize = (e: UIEvent) => {
|
||||
window.requestAnimationFrame(() => this.props.onResize(e));
|
||||
};
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {colors} from './colors';
|
||||
import Label from './Label';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
const SidebarLabel = styled(Label)({
|
||||
color: colors.blackAlpha30,
|
||||
fontSize: 12,
|
||||
padding: 10,
|
||||
});
|
||||
SidebarLabel.displayName = 'SidebarLabel';
|
||||
|
||||
export default SidebarLabel;
|
||||
@@ -1,24 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
/**
|
||||
* A TextParagraph component.
|
||||
*/
|
||||
const TextParagraph = styled.div({
|
||||
marginBottom: 10,
|
||||
|
||||
'&:last-child': {
|
||||
marginBottom: 0,
|
||||
},
|
||||
});
|
||||
TextParagraph.displayName = 'TextParagraph';
|
||||
|
||||
export default TextParagraph;
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
const VerticalRule = styled.div({
|
||||
backgroundColor: '#c9ced4',
|
||||
width: 3,
|
||||
margin: '0',
|
||||
flexShrink: 0,
|
||||
});
|
||||
VerticalRule.displayName = 'VerticalRule';
|
||||
|
||||
export default VerticalRule;
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {Component} from 'react';
|
||||
|
||||
type ViewWithSizeProps = {
|
||||
onSize: (width: number, height: number) => any;
|
||||
};
|
||||
|
||||
type ViewWithSizeState = {
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
|
||||
export default class ViewWithSize extends Component<
|
||||
ViewWithSizeProps,
|
||||
ViewWithSizeState
|
||||
> {
|
||||
constructor(props: ViewWithSizeProps, context: Object) {
|
||||
super(props, context);
|
||||
this.state = {height: window.innerHeight, width: window.innerWidth};
|
||||
}
|
||||
|
||||
_onResize = () => {
|
||||
this.setState({height: window.innerHeight, width: window.innerWidth});
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', this._onResize);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', this._onResize);
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.props.onSize(this.state.width, this.state.height);
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import FlexColumn from './FlexColumn';
|
||||
import {Component} from 'react';
|
||||
import View from './View';
|
||||
import styled from '@emotion/styled';
|
||||
import React from 'react';
|
||||
import {Property} from 'csstype';
|
||||
|
||||
const Inner = styled(FlexColumn)<{height: Property.Height<number>}>(
|
||||
({height}) => ({
|
||||
alignItems: 'flex-start',
|
||||
height,
|
||||
minHeight: '100%',
|
||||
minWidth: '100%',
|
||||
overflow: 'visible',
|
||||
width: '100%',
|
||||
}),
|
||||
);
|
||||
Inner.displayName = 'VirtualList:Inner';
|
||||
|
||||
const Content = styled(FlexColumn)<{top: Property.Top<number>}>(({top}) => ({
|
||||
alignItems: 'flex-start',
|
||||
height: '100%',
|
||||
marginTop: top,
|
||||
minWidth: '100%',
|
||||
overflow: 'visible',
|
||||
}));
|
||||
Content.displayName = 'VirtualList:Content';
|
||||
|
||||
type VirtualListProps = {
|
||||
data: Array<any>;
|
||||
renderRow: (data: any, i: number) => any;
|
||||
rowHeight: number;
|
||||
overscanCount: number;
|
||||
sync?: boolean;
|
||||
wrapInner?: (data: any) => any;
|
||||
};
|
||||
|
||||
type VirtualListState = {
|
||||
offset: number;
|
||||
height: number;
|
||||
};
|
||||
|
||||
export default class VirtualList extends Component<
|
||||
VirtualListProps,
|
||||
VirtualListState
|
||||
> {
|
||||
constructor(props: VirtualListProps, context: Object) {
|
||||
super(props, context);
|
||||
this.state = {
|
||||
height: 0,
|
||||
offset: 0,
|
||||
};
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
overscanCount: 10,
|
||||
};
|
||||
|
||||
ref: HTMLElement | undefined | null;
|
||||
|
||||
setRef = (ref: HTMLElement | null) => {
|
||||
this.ref = ref;
|
||||
};
|
||||
|
||||
resize = () => {
|
||||
if (this.ref && this.state.height !== this.ref.offsetHeight) {
|
||||
this.setState({height: this.ref.offsetHeight});
|
||||
}
|
||||
};
|
||||
|
||||
handleScroll = () => {
|
||||
this.setState({offset: this.ref ? this.ref.scrollTop : 0});
|
||||
if (this.props.sync === true) {
|
||||
this.forceUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
componentDidUpdate() {
|
||||
this.resize();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.resize();
|
||||
window.addEventListener('resize', this.resize);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', this.resize);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {data, overscanCount, renderRow, rowHeight, wrapInner} = this.props;
|
||||
const {height, offset} = this.state;
|
||||
|
||||
// first visible row index
|
||||
// eslint-disable-next-line no-bitwise
|
||||
let start = (offset / rowHeight) | 0;
|
||||
|
||||
// actual number of visible rows (without overscan)
|
||||
// eslint-disable-next-line no-bitwise
|
||||
let visibleRowCount = (height / rowHeight) | 0;
|
||||
|
||||
// Overscan: render blocks of rows modulo an overscan row count
|
||||
// This dramatically reduces DOM writes during scrolling
|
||||
if (overscanCount) {
|
||||
start = Math.max(0, start - (start % overscanCount));
|
||||
visibleRowCount += overscanCount;
|
||||
}
|
||||
|
||||
// last visible + overscan row index
|
||||
const end = start + 1 + visibleRowCount;
|
||||
|
||||
// data slice currently in viewport plus overscan items
|
||||
const selection = data.slice(start, end);
|
||||
|
||||
let inner = (
|
||||
<Inner height={data.length * rowHeight}>
|
||||
<Content top={start * rowHeight}>{selection.map(renderRow)}</Content>
|
||||
</Inner>
|
||||
);
|
||||
|
||||
if (wrapInner) {
|
||||
inner = wrapInner(inner);
|
||||
}
|
||||
|
||||
return (
|
||||
<View grow onScroll={this.handleScroll} ref={this.setRef} scrollable>
|
||||
{inner}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
import {colors, darkColors} from './colors';
|
||||
import React from 'react';
|
||||
|
||||
const DesktopDropdownContainer = styled.div({
|
||||
borderBottom: `1px solid ${darkColors.dividers}`,
|
||||
lineHeight: '25px',
|
||||
marginTop: 5,
|
||||
maxHeight: 600,
|
||||
minWidth: 180,
|
||||
overflow: 'auto',
|
||||
padding: 0,
|
||||
paddingBottom: 5,
|
||||
textAlign: 'left',
|
||||
width: 'auto',
|
||||
|
||||
'&:last-child': {
|
||||
borderBottom: 'none',
|
||||
},
|
||||
});
|
||||
DesktopDropdownContainer.displayName =
|
||||
'DesktopDropdown:DesktopDropdownContainer';
|
||||
|
||||
export function DesktopDropdown(props: {
|
||||
deactivate?: () => void;
|
||||
children?: any;
|
||||
}) {
|
||||
return (
|
||||
<DesktopDropdownContainer>
|
||||
{React.Children.map(props.children, (child) => {
|
||||
return (
|
||||
child &&
|
||||
React.cloneElement(child, {
|
||||
deactivate: props.deactivate,
|
||||
})
|
||||
);
|
||||
})}
|
||||
</DesktopDropdownContainer>
|
||||
);
|
||||
}
|
||||
|
||||
const DesktopDropdownItemContainer = styled.div(
|
||||
(props: {onClick?: Function; onHover?: Function}) => ({
|
||||
listStyle: 'none',
|
||||
opacity: props.onClick || props.onHover ? 1 : 0.5,
|
||||
padding: '0 20px',
|
||||
'&:hover': {
|
||||
backgroundColor: props.onClick || props.onHover ? colors.highlight : '',
|
||||
color: props.onClick || props.onHover ? '#fff' : 'inherit',
|
||||
},
|
||||
}),
|
||||
);
|
||||
DesktopDropdownItemContainer.displayName =
|
||||
'DesktopDropdownItem:DesktopDropdownItemContainer';
|
||||
|
||||
type DesktopDropdownItemState = {hovered: boolean};
|
||||
|
||||
type DesktopDropdownItemProps = {
|
||||
onClick?: false | ((event: React.MouseEvent) => void);
|
||||
onHover?: false | (() => React.ReactNode);
|
||||
children?: React.ReactNode;
|
||||
deactivate?: () => void;
|
||||
};
|
||||
|
||||
export class DesktopDropdownItem extends React.Component<
|
||||
DesktopDropdownItemProps,
|
||||
DesktopDropdownItemState
|
||||
> {
|
||||
constructor(props: DesktopDropdownItemProps, context: Object) {
|
||||
super(props, context);
|
||||
this.state = {hovered: false};
|
||||
}
|
||||
|
||||
onMouseEnter = () => {
|
||||
this.setState({hovered: true});
|
||||
};
|
||||
|
||||
onMouseLeave = () => {
|
||||
this.setState({hovered: false});
|
||||
};
|
||||
|
||||
onClick = (event: React.MouseEvent) => {
|
||||
const {deactivate, onClick} = this.props;
|
||||
if (typeof onClick === 'function') {
|
||||
if (deactivate) {
|
||||
deactivate();
|
||||
}
|
||||
onClick(event);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {hovered} = this.state;
|
||||
const {
|
||||
children,
|
||||
deactivate: _deactivate,
|
||||
onClick,
|
||||
onHover,
|
||||
...props
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<DesktopDropdownItemContainer
|
||||
{...props}
|
||||
onMouseEnter={this.onMouseEnter}
|
||||
onMouseLeave={this.onMouseLeave}
|
||||
onClick={typeof onClick === 'function' ? this.onClick : undefined}>
|
||||
{children}
|
||||
{hovered && typeof onHover === 'function' && onHover()}
|
||||
</DesktopDropdownItemContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const DesktopDropdownSelectedItem = styled(DesktopDropdownItem)({
|
||||
position: 'relative',
|
||||
|
||||
'&::before': {
|
||||
content: "'✔'",
|
||||
marginLeft: '-15px',
|
||||
position: 'absolute',
|
||||
},
|
||||
});
|
||||
DesktopDropdownSelectedItem.displayName = 'DesktopDropdownSelectedItem';
|
||||
@@ -10,9 +10,7 @@
|
||||
export {default as styled} from '@emotion/styled';
|
||||
export {default as Button} from './components/Button';
|
||||
export {default as ToggleButton} from './components/ToggleSwitch';
|
||||
export {default as ButtonNavigationGroup} from './components/ButtonNavigationGroup';
|
||||
export {default as ButtonGroup} from './components/ButtonGroup';
|
||||
export {default as ButtonGroupChain} from './components/ButtonGroupChain';
|
||||
|
||||
export {colors, darkColors, brandColors} from './components/colors';
|
||||
|
||||
@@ -20,8 +18,6 @@ export {default as Glyph, IconSize} from './components/Glyph';
|
||||
|
||||
export {default as LoadingIndicator} from './components/LoadingIndicator';
|
||||
|
||||
export {default as Popover} from './components/Popover';
|
||||
|
||||
// tables
|
||||
export {
|
||||
TableColumns,
|
||||
@@ -53,18 +49,12 @@ export {default as Select} from './components/Select';
|
||||
export {default as Checkbox} from './components/Checkbox';
|
||||
export {default as Radio} from './components/Radio';
|
||||
|
||||
// code
|
||||
export {default as CodeBlock} from './components/CodeBlock';
|
||||
|
||||
// error
|
||||
export {default as ErrorBlock} from './components/ErrorBlock';
|
||||
export {ErrorBlockContainer} from './components/ErrorBlock';
|
||||
export {default as ErrorBoundary} from './components/ErrorBoundary';
|
||||
|
||||
// interactive components
|
||||
export {OrderableOrder} from './components/Orderable';
|
||||
export {default as Orderable} from './components/Orderable';
|
||||
export {default as VirtualList} from './components/VirtualList';
|
||||
|
||||
// base components
|
||||
export {Component, PureComponent} from 'react';
|
||||
@@ -76,23 +66,9 @@ export {default as ContextMenu} from './components/ContextMenu';
|
||||
// file
|
||||
export {FileListFile, FileListFiles} from './components/FileList';
|
||||
export {default as FileList} from './components/FileList';
|
||||
export {default as File} from './components/File';
|
||||
|
||||
// context menu items
|
||||
export {
|
||||
DesktopDropdownItem,
|
||||
DesktopDropdownSelectedItem,
|
||||
DesktopDropdown,
|
||||
} from './components/desktop-toolbar';
|
||||
|
||||
// utility elements
|
||||
export {default as View} from './components/View';
|
||||
export {default as ViewWithSize} from './components/ViewWithSize';
|
||||
export {default as Block} from './components/Block';
|
||||
export {default as FocusableBox} from './components/FocusableBox';
|
||||
export {default as Sidebar} from './components/Sidebar';
|
||||
export {default as SidebarLabel} from './components/SidebarLabel';
|
||||
export {default as Box} from './components/Box';
|
||||
export {default as FlexBox} from './components/FlexBox';
|
||||
export {default as FlexRow} from './components/FlexRow';
|
||||
export {default as FlexColumn} from './components/FlexColumn';
|
||||
@@ -101,18 +77,14 @@ export {Spacer} from './components/Toolbar';
|
||||
export {default as ToolbarIcon} from './components/ToolbarIcon';
|
||||
export {default as Panel} from './components/Panel';
|
||||
export {default as Text} from './components/Text';
|
||||
export {default as TextParagraph} from './components/TextParagraph';
|
||||
export {default as Link} from './components/Link';
|
||||
export {default as PathBreadcrumbs} from './components/PathBreadcrumbs';
|
||||
export {default as ModalOverlay} from './components/ModalOverlay';
|
||||
export {default as Tooltip} from './components/Tooltip';
|
||||
export {default as TooltipProvider} from './components/TooltipProvider';
|
||||
export {default as ResizeSensor} from './components/ResizeSensor';
|
||||
export {default as StatusIndicator} from './components/StatusIndicator';
|
||||
export {default as Line} from './components/Line';
|
||||
// typography
|
||||
export {default as HorizontalRule} from './components/HorizontalRule';
|
||||
export {default as VerticalRule} from './components/VerticalRule';
|
||||
export {default as Label} from './components/Label';
|
||||
export {default as Heading} from './components/Heading';
|
||||
|
||||
@@ -137,7 +109,6 @@ export {InspectorSidebar} from './components/elements-inspector/sidebar';
|
||||
export {VisualizerPortal} from './components/elements-inspector/Visualizer';
|
||||
|
||||
export {default as Sheet} from './components/Sheet';
|
||||
export {StarButton} from './components/StarButton';
|
||||
export {Markdown} from './components/Markdown';
|
||||
|
||||
export {default as VBox} from './components/VBox';
|
||||
@@ -147,8 +118,6 @@ export {default as Labeled} from './components/Labeled';
|
||||
export {default as RoundedSection} from './components/RoundedSection';
|
||||
export {default as CenteredView} from './components/CenteredView';
|
||||
export {default as Info} from './components/Info';
|
||||
export {default as Bordered} from './components/Bordered';
|
||||
export {default as AlternatingRows} from './components/AlternatingRows';
|
||||
export {Layout} from 'flipper-plugin';
|
||||
|
||||
export {default as Scrollable} from './components/Scrollable';
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {PluginDefinition} from '../plugin';
|
||||
import type {PluginDefinition} from '../plugin';
|
||||
import type {State} from '../reducers';
|
||||
import type {State as PluginsState} from '../reducers/plugins';
|
||||
import type BaseDevice from '../devices/BaseDevice';
|
||||
|
||||
@@ -11051,7 +11051,7 @@ prompts@^2.0.1:
|
||||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.4"
|
||||
|
||||
prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
|
||||
Reference in New Issue
Block a user