Implemented basic Flipper theme, [Flipper] Setup initial layout and siderail
Summary:
This setups the first bits of the Sandy Layout, and has a styled siderail according to the design, that does absolutely nothing.
{gif:0sa60r8c}
Reviewed By: cekkaewnumchai
Differential Revision: D23655313
fbshipit-source-id: e30278aeae0913e231ad105a9afb55c74c6a3370
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2d2a8bd675
commit
ef4379e847
@@ -10,6 +10,7 @@
|
||||
"privileged": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.2.2",
|
||||
"@emotion/core": "^10.0.22",
|
||||
"@emotion/styled": "^10.0.23",
|
||||
"@iarna/toml": "^2.2.5",
|
||||
|
||||
132
desktop/app/src/sandy-chrome/LeftRail.tsx
Normal file
132
desktop/app/src/sandy-chrome/LeftRail.tsx
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* 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, {cloneElement} from 'react';
|
||||
import {styled, FlexColumn} from 'flipper';
|
||||
import {Button, Divider, Badge, Tooltip} from 'antd';
|
||||
import {
|
||||
MobileFilled,
|
||||
AppstoreOutlined,
|
||||
BellOutlined,
|
||||
FileExclamationOutlined,
|
||||
LoginOutlined,
|
||||
BugOutlined,
|
||||
SettingOutlined,
|
||||
QuestionCircleOutlined,
|
||||
MedicineBoxOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import {SidebarLeft, SidebarRight} from './SandyIcons';
|
||||
|
||||
const LeftRailContainer = styled(FlexColumn)({
|
||||
width: 48,
|
||||
boxShadow: 'inset -1px 0px 0px rgba(0, 0, 0, 0.1)',
|
||||
justifyContent: 'space-between',
|
||||
});
|
||||
LeftRailContainer.displayName = 'LeftRailContainer';
|
||||
|
||||
const LeftRailSection = styled(FlexColumn)({
|
||||
padding: '8px 0px',
|
||||
alignItems: 'center',
|
||||
});
|
||||
LeftRailSection.displayName = 'LeftRailSection';
|
||||
|
||||
const LeftRailButtonElem = styled(Button)<{small?: boolean}>(({small}) => ({
|
||||
width: 36,
|
||||
height: 36,
|
||||
margin: small ? 2 : 6,
|
||||
padding: '5px 0',
|
||||
border: 'none',
|
||||
}));
|
||||
LeftRailButtonElem.displayName = 'LeftRailButtonElem';
|
||||
|
||||
function LeftRailButton({
|
||||
icon,
|
||||
small,
|
||||
active,
|
||||
count,
|
||||
title,
|
||||
}: {
|
||||
icon?: React.ReactElement;
|
||||
small?: boolean;
|
||||
active?: boolean;
|
||||
count?: number;
|
||||
title: string;
|
||||
}) {
|
||||
let iconElement =
|
||||
icon && cloneElement(icon, {style: {fontSize: small ? 16 : 24}});
|
||||
if (count !== undefined) {
|
||||
iconElement = <Badge count={count}>{iconElement}</Badge>;
|
||||
}
|
||||
return (
|
||||
<Tooltip title={title} placement="right">
|
||||
<LeftRailButtonElem
|
||||
small={small}
|
||||
type={active ? 'primary' : 'ghost'}
|
||||
icon={iconElement}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
const LeftRailDivider = styled(Divider)({
|
||||
margin: 10,
|
||||
width: 36,
|
||||
minWidth: 36,
|
||||
});
|
||||
LeftRailDivider.displayName = 'LeftRailDividier';
|
||||
|
||||
export function LeftRail() {
|
||||
return (
|
||||
<LeftRailContainer>
|
||||
<LeftRailSection>
|
||||
<LeftRailButton icon={<MobileFilled />} active title="App Inspect" />
|
||||
<LeftRailButton icon={<AppstoreOutlined />} title="Plugin Manager" />
|
||||
<LeftRailButton
|
||||
count={8}
|
||||
icon={<BellOutlined />}
|
||||
title="Notifications"
|
||||
/>
|
||||
<LeftRailDivider />
|
||||
<LeftRailButton
|
||||
icon={<FileExclamationOutlined />}
|
||||
title="Flipper Logs"
|
||||
/>
|
||||
</LeftRailSection>
|
||||
<LeftRailSection>
|
||||
<LeftRailButton
|
||||
icon={<MedicineBoxOutlined />}
|
||||
small
|
||||
title="Setup Doctor"
|
||||
/>
|
||||
<LeftRailButton
|
||||
icon={<QuestionCircleOutlined />}
|
||||
small
|
||||
title="Help / Start Screen"
|
||||
/>
|
||||
<LeftRailButton icon={<SettingOutlined />} small title="Settings" />
|
||||
<LeftRailButton
|
||||
icon={<BugOutlined />}
|
||||
small
|
||||
title="Feedback / Bug Reporter"
|
||||
/>
|
||||
<LeftRailButton
|
||||
icon={<SidebarLeft />}
|
||||
small
|
||||
title="Right Sidebar Toggle"
|
||||
/>
|
||||
<LeftRailButton
|
||||
icon={<SidebarRight />}
|
||||
small
|
||||
title="Left Sidebar Toggle"
|
||||
/>
|
||||
<LeftRailButton icon={<LoginOutlined />} title="Log In" />
|
||||
</LeftRailSection>
|
||||
</LeftRailContainer>
|
||||
);
|
||||
}
|
||||
139
desktop/app/src/sandy-chrome/SandyApp.tsx
Normal file
139
desktop/app/src/sandy-chrome/SandyApp.tsx
Normal file
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* 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 {connect} from 'react-redux';
|
||||
import {State as Store} from '../reducers';
|
||||
import {Settings, updateSettings} from '../reducers/settings';
|
||||
import {styled, FlexColumn, colors, Text} from 'flipper';
|
||||
import {DatePicker, Button} from 'antd';
|
||||
import {Layout, FlexBox} from '../ui';
|
||||
|
||||
import {LeftRail} from './LeftRail';
|
||||
import {CloseCircleOutlined} from '@ant-design/icons';
|
||||
|
||||
type StateFromProps = {settings: Settings};
|
||||
type DispatchFromProps = {disableSandy: (settings: Settings) => void};
|
||||
type OwnProps = {};
|
||||
|
||||
type Props = StateFromProps & DispatchFromProps & OwnProps;
|
||||
|
||||
const Container = styled(FlexColumn)({
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: colors.light02,
|
||||
});
|
||||
|
||||
const Box = styled(FlexColumn)({
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
background: colors.white,
|
||||
borderRadius: 10,
|
||||
boxShadow: '0 1px 3px rgba(0,0,0,0.25)',
|
||||
paddingBottom: 16,
|
||||
});
|
||||
|
||||
const AnnoucementText = styled(Text)({
|
||||
fontSize: 24,
|
||||
fontWeight: 300,
|
||||
textAlign: 'center',
|
||||
margin: 16,
|
||||
});
|
||||
|
||||
const LeftContainer = styled(FlexBox)({
|
||||
height: '100% ',
|
||||
});
|
||||
|
||||
// This component should be dropped, and insetTitlebar should be removed from Electron startup once Sandy is the default
|
||||
const TemporarilyTitlebar = styled('div')<{focused?: boolean}>(({focused}) => ({
|
||||
textAlign: 'center',
|
||||
userSelect: 'none',
|
||||
height: '38px',
|
||||
lineHeight: '38px',
|
||||
fontSize: '10pt',
|
||||
color: colors.macOSTitleBarIcon,
|
||||
background: true
|
||||
? `linear-gradient(to bottom, ${colors.macOSTitleBarBackgroundTop} 0%, ${colors.macOSTitleBarBackgroundBottom} 100%)`
|
||||
: colors.macOSTitleBarBackgroundBlur,
|
||||
borderBottom: `1px solid ${
|
||||
focused ? colors.macOSTitleBarBorder : colors.macOSTitleBarBorderBlur
|
||||
}`,
|
||||
WebkitAppRegion: 'drag',
|
||||
}));
|
||||
|
||||
function SandyApp(props: Props) {
|
||||
return (
|
||||
<Layout.Top>
|
||||
<TemporarilyTitlebar focused /*TODO: make dynamic */>
|
||||
[Sandy] Flipper{' '}
|
||||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
icon={<CloseCircleOutlined />}
|
||||
onClick={() => props.disableSandy(props.settings)}></Button>
|
||||
</TemporarilyTitlebar>
|
||||
<Layout.Left>
|
||||
<LeftContainer>
|
||||
<LeftRail />
|
||||
<LeftMenu />
|
||||
</LeftContainer>
|
||||
<Layout.Right>
|
||||
<MainContainer>
|
||||
<TemporarilyContent {...props} />
|
||||
</MainContainer>
|
||||
<RightMenu />
|
||||
</Layout.Right>
|
||||
</Layout.Left>
|
||||
</Layout.Top>
|
||||
);
|
||||
}
|
||||
|
||||
function LeftMenu() {
|
||||
return <div>LeftMenu</div>;
|
||||
}
|
||||
|
||||
function RightMenu() {
|
||||
return <div>RightMenu</div>;
|
||||
}
|
||||
|
||||
function MainContainer({children}: any) {
|
||||
return (
|
||||
<div>
|
||||
MainContainer
|
||||
<br />
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function TemporarilyContent(props: Props) {
|
||||
return (
|
||||
<Container>
|
||||
<Box>
|
||||
<AnnoucementText>
|
||||
New UI for Flipper, Sandy Project! Nothing to see now. Go back to
|
||||
current Flipper
|
||||
</AnnoucementText>
|
||||
<DatePicker />
|
||||
</Box>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect<StateFromProps, DispatchFromProps, OwnProps, Store>(
|
||||
({settingsState}) => ({settings: settingsState}),
|
||||
(dispatch) => ({
|
||||
disableSandy: (settings: Settings) => {
|
||||
console.log(settings);
|
||||
dispatch(updateSettings({...settings, enableSandy: false}));
|
||||
},
|
||||
}),
|
||||
)(SandyApp);
|
||||
40
desktop/app/src/sandy-chrome/SandyIcons.tsx
Normal file
40
desktop/app/src/sandy-chrome/SandyIcons.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 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';
|
||||
|
||||
export const SidebarLeft = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg width={16} height={16} viewBox="0 0 16 16" fill="none" {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M14.667 1.333H1.333v13.334h13.334V1.333zM1.333 0C.597 0 0 .597 0 1.333v13.334C0 15.403.597 16 1.333 16h13.334c.736 0 1.333-.597 1.333-1.333V1.333C16 .597 15.403 0 14.667 0H1.333z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M9.778 1.333h1.333v13.334H9.778V1.333zM11.556 3c0-.184.149-.333.333-.333h2c.184 0 .333.149.333.333v.667c0 .184-.149.333-.333.333h-2a.333.333 0 01-.333-.333V3zM11.556 5c0-.184.149-.333.333-.333h2c.184 0 .333.149.333.333v.667c0 .184-.149.333-.333.333h-2a.333.333 0 01-.333-.333V5zM11.556 7c0-.184.149-.333.333-.333h2c.184 0 .333.149.333.333v.667c0 .184-.149.333-.333.333h-2a.333.333 0 01-.333-.333V7zM11.556 9c0-.184.149-.333.333-.333h2c.184 0 .333.149.333.333v.667c0 .184-.149.333-.333.333h-2a.333.333 0 01-.333-.333V9z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const SidebarRight = (props: React.SVGProps<SVGSVGElement>) => (
|
||||
<svg width={16} height={16} viewBox="0 0 16 16" fill="none" {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M14.667 1.333H1.333v13.334h13.334V1.333zM1.333 0C.597 0 0 .597 0 1.333v13.334C0 15.403.597 16 1.333 16h13.334c.736 0 1.333-.597 1.333-1.333V1.333C16 .597 15.403 0 14.667 0H1.333z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M4.889 1.333h1.333v13.334H4.89V1.333zM1.778 3c0-.184.149-.333.333-.333h2c.184 0 .333.149.333.333v.667c0 .184-.149.333-.333.333h-2a.333.333 0 01-.333-.333V3zM1.778 5c0-.184.149-.333.333-.333h2c.184 0 .333.149.333.333v.667c0 .184-.149.333-.333.333h-2a.333.333 0 01-.333-.333V5zM1.778 7c0-.184.149-.333.333-.333h2c.184 0 .333.149.333.333v.667c0 .184-.149.333-.333.333h-2a.333.333 0 01-.333-.333V7zM1.778 9c0-.184.149-.333.333-.333h2c.184 0 .333.149.333.333v.667c0 .184-.149.333-.333.333h-2a.333.333 0 01-.333-.333V9z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,4 +1,64 @@
|
||||
@import '../node_modules/antd/lib/style/themes/dark.less';
|
||||
@import '../node_modules/antd/dist/antd.less';
|
||||
|
||||
@primary-color: yellow;
|
||||
/* Based on: https://www.figma.com/file/4e6BMdm2SuZ1L7FSuOPQVC/Flipper?node-id=620%3A84636 */
|
||||
@border-radius-base: 6px;
|
||||
|
||||
@font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
|
||||
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
@code-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier,
|
||||
monospace;
|
||||
|
||||
// Link Text & Icon
|
||||
@primary-color: @purple-8;
|
||||
// Success
|
||||
@success-color: @green-7;
|
||||
// Negative
|
||||
@error-color: @red-6;
|
||||
@highlight-color: @red-6;
|
||||
@badge-color: @red-6;
|
||||
// Warning
|
||||
@warning-color: @gold-6;
|
||||
|
||||
// Primary Text & Icon
|
||||
@text-color: @white;
|
||||
// Secondary Text & Icon
|
||||
@text-color-secondary: fade(@white, 60%);
|
||||
// Placeholder Text & Icon
|
||||
@input-placeholder-color: fade(@white, 45%);
|
||||
// Disabled & Icon
|
||||
@disabled-color: fade(@white, 25%);
|
||||
// Background - default
|
||||
@body-background: @black; // Background color for `<body>`
|
||||
// @component-background: @black; // Base background color for most components
|
||||
// Background - Wash
|
||||
@normal-color:fade(
|
||||
@white,
|
||||
5%
|
||||
);
|
||||
// @background-color-light: fade(
|
||||
// @white,
|
||||
// 5%
|
||||
// ); // background of header and selected item
|
||||
// Background - Wash
|
||||
// @background-color-base: fade(@white, 10%); // Default grey background color
|
||||
// Background - Primary Button
|
||||
// @btn-primary-bg: @primary-color;
|
||||
// Background - Primary Hoever
|
||||
// ??? : @purple-7
|
||||
// Background - Default Button
|
||||
// @btn-default-bg: fade(@white, 10%);
|
||||
// Background - Default Hover
|
||||
// @btn-text-hover-bg: fade(@white, 15%);
|
||||
// Background - Button Disabled
|
||||
// @btn-disable-bg: fade(@white, 10%);
|
||||
// Background - Transparent Hover
|
||||
// @btn-link-hover-bg: fade(@white, 10%);
|
||||
// Background - Navigation Active
|
||||
// ???: fade(@white, 8%)
|
||||
// Dividers and Borders
|
||||
@divider-color: fade(@white, 10%);
|
||||
|
||||
@tooltip-color: @black;
|
||||
@tooltip-bg: @white;
|
||||
|
||||
@@ -1,4 +1,63 @@
|
||||
@import '../node_modules/antd/lib/style/themes/default.less';
|
||||
@import '../node_modules/antd/dist/antd.less';
|
||||
|
||||
@primary-color: red;
|
||||
/* Based on: https://www.figma.com/file/4e6BMdm2SuZ1L7FSuOPQVC/Flipper?node-id=620%3A84636 */
|
||||
@border-radius-base: 6px;
|
||||
|
||||
@font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
|
||||
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
@code-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier,
|
||||
monospace;
|
||||
|
||||
// Link Text & Icon
|
||||
@primary-color: @purple-7;
|
||||
// Success
|
||||
@success-color: @green-7;
|
||||
// Negative
|
||||
@error-color: @red-6;
|
||||
@highlight-color: @red-6;
|
||||
// Warning
|
||||
@warning-color: @gold-6;
|
||||
|
||||
// Primary Text & Icon
|
||||
@text-color: @black;
|
||||
// Secondary Text & Icon
|
||||
@text-color-secondary: fade(@black, 60%);
|
||||
// Placeholder Text & Icon
|
||||
@input-placeholder-color: fade(@black, 45%);
|
||||
// Disabled & Icon
|
||||
@disabled-color: fade(@black, 25%);
|
||||
// Background - default
|
||||
@body-background: @white; // Background color for `<body>`
|
||||
// @component-background: @white; // Base background color for most components
|
||||
// Background - Wash
|
||||
@normal-color:fade(
|
||||
@black,
|
||||
5%
|
||||
);
|
||||
// @background-color-light: fade(
|
||||
// @black,
|
||||
// 5%
|
||||
// ); // background of header and selected item
|
||||
// Background - Wash
|
||||
// @background-color-base: fade(@black, 10%); // Default grey background color
|
||||
// Background - Primary Button
|
||||
// @btn-primary-bg: @primary-color;
|
||||
// Background - Primary Hoever
|
||||
// ??? : @purple-7
|
||||
// Background - Default Button
|
||||
// @btn-default-bg: fade(@black, 10%);
|
||||
// Background - Default Hover
|
||||
// @btn-text-hover-bg: fade(@black, 15%);
|
||||
// Background - Button Disabled
|
||||
// @btn-disable-bg: fade(@black, 10%);
|
||||
// Background - Transparent Hover
|
||||
// @btn-link-hover-bg: fade(@black, 10%);
|
||||
// Background - Navigation Active
|
||||
// ???: fade(@black, 8%)
|
||||
// Dividers and Borders
|
||||
@divider-color: fade(@black, 10%);
|
||||
|
||||
@tooltip-color: @white;
|
||||
@tooltip-bg: @black;
|
||||
|
||||
Reference in New Issue
Block a user