Introduce AppInspect
Summary: This diff introduces the AppInspect pane. I didn't get very fare, and it is markup only, but while at it made a bunch of other improvement in the component lib, so figured to prematurely submit to don't make the diffs too big. Improvements - Separated sidebar and Layout.X, as it was to much responsibility for one component, and made customization hard. Also caused state loss when switching between resizable and not. - Setup a basic top level selection. Maybe will move it into redux in the future, but for now it suffices. - Introduced Layout.Horizontal and `Layout.Vertical` as alternative to Ant design's space. The reason is that the latter can't stretching children, which we use quite frequently. (that is because they use wrappers to create spacing, but since we run on Electron, we can use CSS `gap` instead, which handles that much more elegantly). - Fixed issue where gutter handle could disappear when dragging to far. Reviewed By: cekkaewnumchai Differential Revision: D23867265 fbshipit-source-id: e872b7f48b868e255f2c34d45e811b8ed93d0b00
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2cbcbd1480
commit
aaabe1cc82
@@ -9,20 +9,16 @@
|
||||
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import {Sidebar} from '..';
|
||||
|
||||
type Props = {
|
||||
type SplitLayoutProps = {
|
||||
/**
|
||||
* If set, the dynamically sized pane will get scrollbars when needed
|
||||
*/
|
||||
scrollable?: boolean;
|
||||
/**
|
||||
* If set, the 'fixed' child will no longer be sized based on it's own dimensions,
|
||||
* but rather it will be possible to resize it
|
||||
* If set, items will be centered over the orthogonal direction, if false (the default) items will be stretched.
|
||||
*/
|
||||
initialSize?: number;
|
||||
minSize?: number;
|
||||
|
||||
center?: boolean;
|
||||
children: [React.ReactNode, React.ReactNode];
|
||||
};
|
||||
|
||||
@@ -42,18 +38,21 @@ const ScrollContainer = styled('div')<{scrollable: boolean}>(
|
||||
);
|
||||
ScrollContainer.displayName = 'Layout:ScrollContainer';
|
||||
|
||||
const Container = styled('div')<{horizontal: boolean}>(({horizontal}) => ({
|
||||
display: 'flex',
|
||||
flex: 'auto',
|
||||
flexDirection: horizontal ? 'row' : 'column',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
}));
|
||||
const Container = styled('div')<{horizontal: boolean; center?: boolean}>(
|
||||
({horizontal, center}) => ({
|
||||
display: 'flex',
|
||||
flex: 'auto',
|
||||
flexDirection: horizontal ? 'row' : 'column',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
alignItems: center ? 'center' : undefined,
|
||||
}),
|
||||
);
|
||||
Container.displayName = 'Layout:Container';
|
||||
|
||||
function renderLayout(
|
||||
{children, scrollable, initialSize, minSize}: Props,
|
||||
{children, scrollable, center}: SplitLayoutProps,
|
||||
horizontal: boolean,
|
||||
reverse: boolean,
|
||||
) {
|
||||
@@ -62,44 +61,45 @@ function renderLayout(
|
||||
}
|
||||
const fixedChild = reverse ? children[1] : children[0];
|
||||
|
||||
const fixedElement =
|
||||
initialSize === undefined ? (
|
||||
<FixedContainer>{fixedChild}</FixedContainer>
|
||||
) : horizontal ? (
|
||||
<Sidebar
|
||||
position={reverse ? 'right' : 'left'}
|
||||
width={initialSize}
|
||||
minWidth={minSize}
|
||||
gutter>
|
||||
{fixedChild}
|
||||
</Sidebar>
|
||||
) : (
|
||||
<Sidebar
|
||||
position={reverse ? 'bottom' : 'top'}
|
||||
height={initialSize}
|
||||
minHeight={minSize}
|
||||
gutter>
|
||||
{fixedChild}
|
||||
</Sidebar>
|
||||
);
|
||||
const fixedElement = <FixedContainer>{fixedChild}</FixedContainer>;
|
||||
|
||||
const dynamicElement = (
|
||||
<ScrollContainer scrollable={!!scrollable}>
|
||||
{reverse ? children[0] : children[1]}
|
||||
</ScrollContainer>
|
||||
);
|
||||
return reverse ? (
|
||||
<Container horizontal={horizontal}>
|
||||
<Container horizontal={horizontal} center={center}>
|
||||
{dynamicElement}
|
||||
{fixedElement}
|
||||
</Container>
|
||||
) : (
|
||||
<Container horizontal={horizontal}>
|
||||
<Container horizontal={horizontal} center={center}>
|
||||
{fixedElement}
|
||||
{dynamicElement}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
type DistributionProps = {
|
||||
/**
|
||||
* Gab between individual items
|
||||
*/
|
||||
gap?: number;
|
||||
/**
|
||||
* If set, items will be aligned in the center, if false (the default) items will be stretched.
|
||||
*/
|
||||
center?: boolean;
|
||||
/**
|
||||
* If set, the layout will fill out to maximum width
|
||||
*/
|
||||
fillx?: boolean;
|
||||
/**
|
||||
* If set, the layout will fill out to maximum height
|
||||
*/
|
||||
filly?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* The Layout component divides all available screenspace over two components:
|
||||
* A fixed top (or left) component, and all remaining space to a bottom component.
|
||||
@@ -111,7 +111,11 @@ function renderLayout(
|
||||
*
|
||||
* Use Layout.Top / Right / Bottom / Left to indicate where the fixed element should live.
|
||||
*/
|
||||
const Layout: Record<'Left' | 'Right' | 'Top' | 'Bottom', React.FC<Props>> = {
|
||||
const Layout: Record<
|
||||
'Left' | 'Right' | 'Top' | 'Bottom',
|
||||
React.FC<SplitLayoutProps>
|
||||
> &
|
||||
Record<'Horizontal' | 'Vertical', React.FC<DistributionProps>> = {
|
||||
Top(props) {
|
||||
return renderLayout(props, false, false);
|
||||
},
|
||||
@@ -124,11 +128,26 @@ const Layout: Record<'Left' | 'Right' | 'Top' | 'Bottom', React.FC<Props>> = {
|
||||
Right(props) {
|
||||
return renderLayout(props, true, true);
|
||||
},
|
||||
Horizontal: styled.div<DistributionProps>(({gap, center, fillx, filly}) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
gap,
|
||||
alignItems: center ? 'center' : 'stretch',
|
||||
width: fillx ? '100%' : undefined,
|
||||
height: filly ? '100%' : undefined,
|
||||
})),
|
||||
Vertical: styled.div<DistributionProps>(({gap, center, fillx, filly}) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap,
|
||||
alignItems: center ? 'center' : 'stretch',
|
||||
width: fillx ? '100%' : undefined,
|
||||
height: filly ? '100%' : undefined,
|
||||
})),
|
||||
};
|
||||
|
||||
Layout.Top.displayName = 'Layout.Top';
|
||||
Layout.Left.displayName = 'Layout.Left';
|
||||
Layout.Bottom.displayName = 'Layout.Bottom';
|
||||
Layout.Right.displayName = 'Layout.Right';
|
||||
Object.keys(Layout).forEach((key) => {
|
||||
(Layout as any)[key].displayName = `Layout.${key}`;
|
||||
});
|
||||
|
||||
export default Layout;
|
||||
|
||||
Reference in New Issue
Block a user