From 4665bcf2186c080f0051072bb4fd4ba3dc336f3d Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Thu, 23 Apr 2020 03:45:43 -0700 Subject: [PATCH] Introduced Layout component Summary: This diff introduces a Layout component. Layout is now quite randomly build up by using panels, sidebars, flex columns, flexrow and view components. They all have slight different scrolling, overflow, and grow behavior. Which causes issues with areas not being srcollable, double scrollbars or simply the wrong area scrolling. Too make things worse to design, many components by default display hidden content, and show scrollbars automatically rather than deliberately. To work towards a consist, and especially simple layout model, over time I want to build a consistent outside-in layout model, where always parents reserve space for children, and children fill the available space and device it even further. Note that this approaches better how 'applications' typically organize their layout, which is opposite from the classic 'document', where the contents is allowed to grow and is used to push things down / aside where they want. However, such a model fits an application with toolbars, sidebars and scroll regions badly, and currently those two philosophies are mixed throughout the application. This component is a very small first step to organizing our layout consistently. By using a new component there is less risk to break existing layouts. The `Layout` component takes up all available space, both horizontally and vertically, and gives the first child what it needs based on its own size (typically, a toolbar or (resizable) sidebar), and all the remaining space to the second child. By default the space is distributed vertically, but it can also be distributed horizontally. It can provide scrollbars as well if needed so that the main content doesn't need to provide that by itself. Examples: ``` ``` Reviewed By: jknoxville Differential Revision: D21178245 fbshipit-source-id: c2d2f167d1572278e51a5b66e1cbf13c42c3b898 --- desktop/app/src/ui/components/Layout.tsx | 73 ++++++++++++++++++++++++ desktop/app/src/ui/index.tsx | 1 + 2 files changed, 74 insertions(+) create mode 100644 desktop/app/src/ui/components/Layout.tsx diff --git a/desktop/app/src/ui/components/Layout.tsx b/desktop/app/src/ui/components/Layout.tsx new file mode 100644 index 000000000..7fa40f582 --- /dev/null +++ b/desktop/app/src/ui/components/Layout.tsx @@ -0,0 +1,73 @@ +/** + * 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'; + +type Props = { + scrollable?: boolean; + horizontal?: boolean; +}; + +const FixedContainer = styled('div')({ + flex: 'none', + height: 'auto', + overflow: 'none', +}); +FixedContainer.displayName = 'Layout:FixedContainer'; + +const ScrollContainer = styled('div')(({scrollable}) => ({ + overflow: scrollable ? 'auto' : 'hidden', + flex: 'auto', + display: 'flex', +})); +ScrollContainer.displayName = 'Layout:ScrollContainer'; + +const Container = styled('div')(({horizontal}) => ({ + display: 'flex', + flex: 'auto', + flexDirection: horizontal ? 'row' : 'column', + height: '100%', + width: '100%', + overflow: 'hidden', +})); +Container.displayName = 'Layout:Container'; + +/** + * The Layout component divides all available screenspace over two components: + * A fixed top (or left) component, and all remaining space to a bottom component. + * + * The main area will be scrollable by default, but if multiple containers are nested, + * scrolling can be disabled by using `scrollable={false}` + */ +const Layout: React.FC< + { + children: [React.ReactNode, React.ReactNode]; + } & Props +> = ({children, ...props}) => { + if (children.length > 2) { + throw new Error('VerticalContainer expects exactly 2 children'); + } + const top = children[0]; + const main = children[1]; + return ( + + {top} + {main} + + ); +}; + +Layout.displayName = 'Layout'; +Layout.defaultProps = { + scrollable: false, + horizontal: false, +}; + +export default Layout; diff --git a/desktop/app/src/ui/index.tsx b/desktop/app/src/ui/index.tsx index 7f861ee44..7ca7b01d2 100644 --- a/desktop/app/src/ui/index.tsx +++ b/desktop/app/src/ui/index.tsx @@ -173,3 +173,4 @@ 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 {default as Layout} from './components/Layout';