Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
*.css*
**/.rpt2_cache
1 change: 1 addition & 0 deletions demo/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<meta name="description" content="React Spaces are a set of React components that allow you to divide a page or container into nestable, anchored, scrollable and resizable spaces." />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
Expand Down
6 changes: 1 addition & 5 deletions demo/src/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,8 @@ pre {
font-size: 18px !important;
}

::-webkit-scrollbar{
width: 5px;
}

::-webkit-scrollbar-track-piece{
background-color: #FFF;
background-color: none;
}

::-webkit-scrollbar-thumb{
Expand Down
36 changes: 36 additions & 0 deletions demo/src/ui-demo/CodeEditor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.code-editor {
.editor-main {
padding: 5px 5px 5px 10px;
font-size: 16px;
font-family: 'Courier New', Courier, monospace;
}

.sidebar-pane {
.title {
font-size: 11px;
padding-left: 5px;
font-weight: 700;
text-transform: uppercase;
}
}

.bottom-pane-container {
.spaces-resize-handle {
background-color: #333 !important;
}

button {
margin-right: 10px;
border: none;
background-color: #555;
color: white;
padding: 5px 15px;
}
}

.side-bar-container {
.resize-right {
background-color: #333 !important;
}
}
}
135 changes: 135 additions & 0 deletions demo/src/ui-demo/CodeEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import * as React from 'react';
import * as Space from 'react-spaces';
import MonacoEditor from 'react-monaco-editor';
import { CenterType } from 'react-spaces';
import './CodeEditor.scss';

export const CodeEditor = () => {
return (
<Space.Fill className="code-editor">
<Header />
<Main />
</Space.Fill>
)
}

const Header = () => {
return (
<Space.Top className="title-bar" centerContent={CenterType.HorizontalVertical} size={30} style={{ backgroundColor: '#333', color: '#c5c5c5' }}>
<MenuBar />
UI Demo - Example UI interface
</Space.Top>
)
}

const Main = () => {
const [ sidebarVisible, setSidebarVisible ] = React.useState(true);
const [ sidebarWide, setSidebarWide ] = React.useState(false);

return (
<Space.Fill style={{ backgroundColor: '#1E1E1E' }}>
<Space.Fill>
<IconPane />
<SideBar wide={sidebarWide} visible={sidebarVisible} />
<Editor toggleSize={() => setSidebarWide(!sidebarWide)} toggleVisibility={() => setSidebarVisible(!sidebarVisible)} />
</Space.Fill>
</Space.Fill>
)
}

const MenuBar = () => {
return (
<Space.Left className="menu-bar" size="30%">

</Space.Left>
)
}

const Editor : React.FC<{ toggleVisibility: () => void, toggleSize: () => void }> = (props) => {
const [ code, setCode ] = React.useState('import * as React from \'react\';\r\nimport * as Space from \'react-spaces\';\r\n\r\nexport const App = () => {\r\n <Space.ViewPort>\r\n <Space.Top size={30}>\r\n Hello!\r\n </Space.Top>\r\n <Space.Fill>\r\n World!\r\n </Space.Fill>\r\n </Space.ViewPort>\r\n}');

const options = {
selectOnLineNumbers: true,
automaticLayout: true
};

return (
<Space.Fill>
<Space.Fill>
<Space.Top className="editor-tabs" size={40}>
</Space.Top>
<Space.Fill className="editor-main">
<MonacoEditor
value={code}
onChange={(newValue: string) => setCode(newValue)}
options={options}
language="javascript"
theme="vs-dark" />
</Space.Fill>
</Space.Fill>
<BottomPane toggleSize={props.toggleSize} toggleVisibility={props.toggleVisibility} />
</Space.Fill>
)
}

const IconPane = () => {
return (
<Space.Left order={1} className="side-bar-icons" size={50} style={{ backgroundColor: '#333' }}>
</Space.Left>
)
}

const SideBar : React.FC<{ wide: boolean, visible: boolean }> = (props) => {
return (
props.visible ?
<Space.LeftResizable order={2} className="side-bar" size={props.wide ? 500 : 300} handleSize={2} overlayHandle={false} style={{ backgroundColor: '#252526' }}>
<SideBarPane order={1} title="Open editors" height={200}>

</SideBarPane>
<SideBarPane order={2} title="Demo" height={300}>

</SideBarPane>
<SideBarPane fill={true} title="Outline">

</SideBarPane>
</Space.LeftResizable> :
null
)
}

const SideBarPane: React.FC<{ order?: number, title: string, height?: number, fill?: boolean }> = (props) => {
return (
props.fill ?
<Space.Fill className="sidebar-pane">
<SideBarPaneInner title={props.title}>{props.children}</SideBarPaneInner>
</Space.Fill>
:
<Space.TopResizable className="sidebar-pane" order={props.order} size={props.height!}>
<SideBarPaneInner title={props.title}>{props.children}</SideBarPaneInner>
</Space.TopResizable>
)
}

const SideBarPaneInner: React.FC<{ title: string }> = (props) => {
return (
<>
<Space.Top className="title" size={28} style={{ backgroundColor: '#383838', color: '#c5c5c5' }}>
<Space.CenteredVertically>
{props.title}
</Space.CenteredVertically>
</Space.Top>
<Space.Fill className="content">
{props.children}
</Space.Fill>
</>
)
}

const BottomPane : React.FC<{ toggleVisibility: () => void, toggleSize: () => void }> = (props) => {
return (
<Space.BottomResizable className="bottom-pane" size={60} handleSize={2} centerContent={Space.CenterType.HorizontalVertical}>
<button onClick={props.toggleVisibility}>Toggle sidebar visibility</button>
<button onClick={props.toggleSize}>Toggle sidebar size</button>
</Space.BottomResizable>
)
}
22 changes: 22 additions & 0 deletions demo/src/ui-demo/Resizable.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.resizable-demo {
.gray {
background-color: #eee;
}

.blue {
background-color: #e0eeee;
}

.red {
background-color: #eee0e0;
}

.white {
background-color: white;
}

.description {
color: black;
font-size: 120%;
}
}
95 changes: 95 additions & 0 deletions demo/src/ui-demo/Resizable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import * as React from 'react';
import * as Space from 'react-spaces';
import './Resizable.scss';
import { Button } from 'antd';

export const Resizable = () => {
const [ spaceSize, setSpaceSize ] = React.useState(20);
const [ resizingSpaces, setResizingSpaces ] = React.useState(false);

const intervalId = React.useRef<number | undefined>(undefined);
const direction = React.useRef<boolean>(true);

React.useEffect(() => {
return () => {
if (intervalId.current) {
window.clearInterval(intervalId.current);
}
}
}, [])

React.useEffect(() => {
if (resizingSpaces) {
intervalId.current = window.setInterval(() => {
setSpaceSize(prev => {
const newSize = prev + (direction.current ? 0.1 : -0.1);

if (newSize < 20 || newSize > 30) {
direction.current = !direction.current;
}

return newSize;
});
}, 21)
} else {
if (intervalId.current) {
window.clearInterval(intervalId.current);
}
}
}, [ resizingSpaces ]);

return (
<Space.Fill className="resizable-demo blue">
<AnchoredExample spaceSize={spaceSize} resizingSpaces={resizingSpaces} setResizingSpaces={setResizingSpaces}>
<AnchoredExample spaceSize={spaceSize} resizingSpaces={resizingSpaces} setResizingSpaces={setResizingSpaces} />
</AnchoredExample>
</Space.Fill>
)
}

const AnchoredExample : React.FC<{ spaceSize: number,resizingSpaces: boolean, setResizingSpaces: (state: boolean) => void }> = (props) => {
const trackSize = false;

return (
<>
<Space.LeftResizable size={`${props.spaceSize}%`} trackSize={trackSize} className={props.children ? "blue" : "gray"}>
{Description("Left")}
</Space.LeftResizable>

<Space.Fill>
<Space.TopResizable size={`${props.spaceSize}%`} trackSize={trackSize} className={props.children ? "red" : "blue"}>
{Description("Top")}
</Space.TopResizable>
<Space.Fill trackSize={trackSize} className="white">
{props.children ?
props.children :
<Space.Centered>
<div style={{ textAlign: 'center' }}>
<Button onClick={() => props.setResizingSpaces(!props.resizingSpaces)}>
{
!props.resizingSpaces ? "Dynamically resize spaces" : "Stop"
}
</Button>
</div>
</Space.Centered>
}
</Space.Fill>
<Space.BottomResizable size={`${props.spaceSize}%`} trackSize={trackSize} className={props.children ? "red" : "blue"}>
{Description("Bottom")}
</Space.BottomResizable>
</Space.Fill>

<Space.RightResizable size={`${props.spaceSize}%`} trackSize={trackSize} className={props.children ? "blue" : "gray"}>
{Description("Right")}
</Space.RightResizable>
</>
)
}

const Description = (props: string) => (
<Space.Centered>
<div className="description">
<strong>{props}</strong>
</div>
</Space.Centered>
);
15 changes: 15 additions & 0 deletions demo/src/ui-demo/Scrollable.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.scrollable-demo {
header > .spaces-space-inner {
background-color: black;
color: white;
font-size: 140%;
font-weight: 700;
padding: 15px;
}

main > .spaces-space-inner {
padding: 0 25px 25px 25px;
font-size: 130%;
color: black;
}
}
46 changes: 46 additions & 0 deletions demo/src/ui-demo/Scrollable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as React from 'react';
import * as Space from 'react-spaces';
import { Menu, Spin } from 'antd';
import './Scrollable.scss';

export const ScrollableDemo = () => {
const [ selectedKey, setSelectedKey ] = React.useState('1');
const [ html, setHtml ] = React.useState('');
const [ loading, setLoading ] = React.useState(true);

React.useEffect(() => {
(async () => {
setLoading(true);
const response = await fetch('https://baconipsum.com/api/?type=all-meat&paras=20&start-with-lorem=1&format=html');
setHtml(await response.text());
setLoading(false);
})();
}, [selectedKey]);

return (
<Space.Fill className="scrollable-demo">
<Space.Top as="header" size={50} centerContent={Space.CenterType.Vertical}>
Header
</Space.Top>
<Space.Fill>
<Space.LeftResizable as="aside" size="20%">
<Menu defaultSelectedKeys={[ selectedKey ]} onSelect={e => setSelectedKey(e.key)}>
<Menu.Item key="1">Menu item 1</Menu.Item>
<Menu.Item key="2">Menu item 2</Menu.Item>
<Menu.Item key="3">Menu item 3</Menu.Item>
</Menu>
</Space.LeftResizable>
<Space.Fill as="main" scrollable={true}>
{
loading ?
<Space.Centered><Spin size="large" /><br />Loading stuff</Space.Centered> :
<div>
<h2>Some heading</h2>
<div dangerouslySetInnerHTML={{ __html: html }} />
</div>
}
</Space.Fill>
</Space.Fill>
</Space.Fill>
)
}
Loading