diff --git a/desktop/app/src/ui/components/Layout.tsx b/desktop/app/src/ui/components/Layout.tsx index a0e11b75b..605fd07a5 100644 --- a/desktop/app/src/ui/components/Layout.tsx +++ b/desktop/app/src/ui/components/Layout.tsx @@ -12,24 +12,26 @@ import styled from '@emotion/styled'; type Props = { scrollable?: boolean; - horizontal?: boolean; + children: [React.ReactNode, React.ReactNode]; }; const FixedContainer = styled('div')({ flex: 'none', height: 'auto', - overflow: 'none', + overflow: 'hidden', }); FixedContainer.displayName = 'Layout:FixedContainer'; -const ScrollContainer = styled('div')(({scrollable}) => ({ - overflow: scrollable ? 'auto' : 'hidden', - flex: 'auto', - display: 'flex', -})); +const ScrollContainer = styled('div')<{scrollable: boolean}>( + ({scrollable}) => ({ + overflow: scrollable ? 'auto' : 'hidden', + flex: 'auto', + display: 'flex', + }), +); ScrollContainer.displayName = 'Layout:ScrollContainer'; -const Container = styled('div')(({horizontal}) => ({ +const Container = styled('div')<{horizontal: boolean}>(({horizontal}) => ({ display: 'flex', flex: 'auto', flexDirection: horizontal ? 'row' : 'column', @@ -39,35 +41,62 @@ const Container = styled('div')(({horizontal}) => ({ })); Container.displayName = 'Layout:Container'; +function renderLayout( + {children, scrollable}: Props, + horizontal: boolean, + reverse: boolean, +) { + if (children.length !== 2) { + throw new Error('Layout expects exactly 2 children'); + } + const fixedElement = ( + {reverse ? children[1] : children[0]} + ); + const dynamicElement = ( + + {reverse ? children[0] : children[1]} + + ); + return reverse ? ( + + {dynamicElement} + {fixedElement} + + ) : ( + + {fixedElement} + {dynamicElement} + + ); +} + /** * 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}` + * + * Use Layout.Top / Right / Bottom / Left to indicate where the fixed element should live. */ -const Layout: React.FC< - { - children: [React.ReactNode, React.ReactNode]; - } & Props -> = ({children, ...props}) => { - if (children.length !== 2) { - throw new Error('Layout expects exactly 2 children'); - } - const top = children[0]; - const main = children[1]; - return ( - - {top} - {main} - - ); +const Layout: Record<'Left' | 'Right' | 'Top' | 'Bottom', React.FC> = { + Top(props) { + return renderLayout(props, false, false); + }, + Bottom(props) { + return renderLayout(props, false, true); + }, + Left(props) { + return renderLayout(props, true, false); + }, + Right(props) { + return renderLayout(props, true, true); + }, }; -Layout.displayName = 'Layout'; -Layout.defaultProps = { - scrollable: false, - horizontal: false, -}; +Layout.Top.displayName = 'Layout.Top'; +Layout.Left.displayName = 'Layout.Left'; +Layout.Bottom.displayName = 'Layout.Bottom'; +Layout.Right.displayName = 'Layout.Right'; export default Layout; diff --git a/desktop/app/src/ui/components/searchable/Searchable.tsx b/desktop/app/src/ui/components/searchable/Searchable.tsx index a9266875b..987252328 100644 --- a/desktop/app/src/ui/components/searchable/Searchable.tsx +++ b/desktop/app/src/ui/components/searchable/Searchable.tsx @@ -472,7 +472,7 @@ const Searchable = ( render() { const {placeholder, actions, ...props} = this.props; return ( - + - + ); } };