flow: ui
This commit is contained in:
parent
8015c9ea06
commit
987551e975
1
attribution.txt
Normal file
1
attribution.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"Document" icon made by Becris from www.flaticon.com
|
|
@ -4,7 +4,9 @@ import {hot} from 'react-hot-loader';
|
||||||
import React, {useState} from 'react';
|
import React, {useState} from 'react';
|
||||||
|
|
||||||
import TypeRenderersContext from './context/typeRenderers';
|
import TypeRenderersContext from './context/typeRenderers';
|
||||||
import Resource from './resource';
|
import Resources from './resources';
|
||||||
|
import Sidebar from './sidebar';
|
||||||
|
import SidebarIcons from './sidebar-icons';
|
||||||
import {all as allTypeRenderers} from './type-renderers.scwp';
|
import {all as allTypeRenderers} from './type-renderers.scwp';
|
||||||
|
|
||||||
const typeRenderMap = () => Object.values(allTypeRenderers()).reduce((r, M) => {
|
const typeRenderMap = () => Object.values(allTypeRenderers()).reduce((r, M) => {
|
||||||
|
@ -15,9 +17,21 @@ const typeRenderMap = () => Object.values(allTypeRenderers()).reduce((r, M) => {
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [typeRenderers] = useState(typeRenderMap());
|
const [typeRenderers] = useState(typeRenderMap());
|
||||||
return (
|
return (
|
||||||
<TypeRenderersContext.Provider value={typeRenderers}>
|
<div className="app">
|
||||||
<Resource uri="/resources/cha0s/initial/mama-kitty.entity.json" />
|
<TypeRenderersContext.Provider value={typeRenderers}>
|
||||||
</TypeRenderersContext.Provider>
|
<div className="panes horizontal">
|
||||||
|
<div className="sidebar-icons-wrapper pane">
|
||||||
|
<SidebarIcons />
|
||||||
|
</div>
|
||||||
|
<div className="sidebar-wrapper pane">
|
||||||
|
<Sidebar />
|
||||||
|
</div>
|
||||||
|
<div className="resources-wrapper pane">
|
||||||
|
<Resources />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TypeRenderersContext.Provider>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
.app {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panes {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
&.horizontal .pane {
|
||||||
|
float: left;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
&.vertical .pane {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-icons-wrapper {
|
||||||
|
width: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-wrapper {
|
||||||
|
width: 24em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resources-wrapper {
|
||||||
|
width: calc(100% - 28em);
|
||||||
|
}
|
|
@ -144,3 +144,81 @@ select {
|
||||||
outline: none;
|
outline: none;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.react-tabs {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-tabs__tab-list {
|
||||||
|
background-color: #272727;
|
||||||
|
font-family: Ubuntu, "Droid Sans", sans-serif;
|
||||||
|
font-size: 0.9em;
|
||||||
|
overflow-x: hidden;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background: #2e1d1d;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #777;
|
||||||
|
border-radius: 0;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-tabs__tab {
|
||||||
|
background-color: #2d2d2d;
|
||||||
|
color: #aaaaaa;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
height: 3em;
|
||||||
|
&:not(:last-of-type) {
|
||||||
|
border-right: 1px solid #282828;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
.wrapper {
|
||||||
|
align-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
padding: 0.75em;
|
||||||
|
}
|
||||||
|
.close {
|
||||||
|
color: #999999;
|
||||||
|
padding: 0.25em;
|
||||||
|
visibility: hidden;
|
||||||
|
&:hover {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover .close {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-tabs__tab--selected[class] {
|
||||||
|
background-color: #212121;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-tabs__tab-panel {
|
||||||
|
display: none;
|
||||||
|
overflow-y: auto;
|
||||||
|
height: calc(100% - 3em);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-tabs__tab-panel--selected {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
import './app.scss';
|
import {compose} from '@avocado/core';
|
||||||
|
import contempo from 'contempo';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {registerHooks} from 'scwp';
|
import {registerHooks} from 'scwp';
|
||||||
|
|
||||||
import {all} from './resources.scwp';
|
import {all} from './resources.scwp';
|
||||||
|
|
||||||
|
const decorate = compose(
|
||||||
|
contempo(require('./resource.raw.scss')),
|
||||||
|
);
|
||||||
|
|
||||||
const resources = Object.values(all()).map((M) => M.default);
|
const resources = Object.values(all()).map((M) => M.default);
|
||||||
|
|
||||||
const Resource = (props) => {
|
const Resource = (props) => {
|
||||||
|
@ -29,7 +33,7 @@ Resource.propTypes = {
|
||||||
uri: PropTypes.string.isRequired,
|
uri: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Resource;
|
export default decorate(Resource);
|
||||||
|
|
||||||
if (module.hot) {
|
if (module.hot) {
|
||||||
registerHooks({
|
registerHooks({
|
||||||
|
|
4
src/client/resource.raw.scss
Normal file
4
src/client/resource.raw.scss
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
:scope {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
53
src/client/resources.jsx
Normal file
53
src/client/resources.jsx
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import {compose} from '@avocado/core';
|
||||||
|
import contempo from 'contempo';
|
||||||
|
import React, {useState} from 'react';
|
||||||
|
import {
|
||||||
|
Tab,
|
||||||
|
Tabs,
|
||||||
|
TabList,
|
||||||
|
TabPanel,
|
||||||
|
} from 'react-tabs';
|
||||||
|
|
||||||
|
import Resource from './resource';
|
||||||
|
|
||||||
|
const decorate = compose(
|
||||||
|
contempo(require('./resources.raw.scss')),
|
||||||
|
);
|
||||||
|
|
||||||
|
const Sidebar = (props) => {
|
||||||
|
const [tabIndex, setTabIndex] = useState(0);
|
||||||
|
const uris = [
|
||||||
|
'/resources/cha0s/initial/kitty.entity.json',
|
||||||
|
'/resources/cha0s/initial/mama-kitty.entity.json',
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<div className="resources">
|
||||||
|
<Tabs
|
||||||
|
selectedIndex={tabIndex}
|
||||||
|
onSelect={(index) => setTabIndex(index)}
|
||||||
|
>
|
||||||
|
<TabList>
|
||||||
|
{uris.map((uri) => (
|
||||||
|
<Tab key={uri}>
|
||||||
|
<span className="wrapper">
|
||||||
|
<span className="icon" />
|
||||||
|
<span className="text">{uri}</span>
|
||||||
|
<span className="close">✕</span>
|
||||||
|
</span>
|
||||||
|
</Tab>
|
||||||
|
))}
|
||||||
|
</TabList>
|
||||||
|
{uris.map((uri) => (
|
||||||
|
<TabPanel>
|
||||||
|
<Resource key={uri} uri={uri} />
|
||||||
|
</TabPanel>
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Sidebar.propTypes = {
|
||||||
|
};
|
||||||
|
|
||||||
|
export default decorate(Sidebar);
|
17
src/client/resources.raw.scss
Normal file
17
src/client/resources.raw.scss
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
:scope {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-tabs__tab .wrapper {
|
||||||
|
padding: 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-tabs__tab .wrapper .text {
|
||||||
|
padding: 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
// :scope > .react-tabs > .react-tabs__tab-list {
|
||||||
|
// margin-left: 4em;
|
||||||
|
// width: calc(100% - 3em);
|
||||||
|
// }
|
|
@ -1,65 +1,4 @@
|
||||||
%tabs {
|
%tabs {
|
||||||
|
|
||||||
.react-tabs__tab-list {
|
|
||||||
background-color: #272727;
|
|
||||||
font-family: Ubuntu, "Droid Sans", sans-serif;
|
|
||||||
font-size: 0.9em;
|
|
||||||
overflow-x: hidden;
|
|
||||||
scrollbar-width: thin;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: 100%;
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
}
|
|
||||||
&::-webkit-scrollbar-track {
|
|
||||||
background: #2e1d1d;
|
|
||||||
}
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #777;
|
|
||||||
border-radius: 0;
|
|
||||||
border-width: 1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.react-tabs__tab {
|
|
||||||
background-color: #2d2d2d;
|
|
||||||
color: #aaaaaa;
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
&:not(:last-of-type) {
|
|
||||||
border-right: 1px solid #282828;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
color: #ddd;
|
|
||||||
}
|
|
||||||
.wrapper {
|
|
||||||
align-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
height: 3em;
|
|
||||||
width: 10em;
|
|
||||||
}
|
|
||||||
.icon {
|
|
||||||
padding: 0.75em;
|
|
||||||
}
|
|
||||||
.close {
|
|
||||||
color: #999999;
|
|
||||||
padding: 0.25em;
|
|
||||||
visibility: hidden;
|
|
||||||
&:hover {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:hover .close {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.react-tabs__tab--selected[class] {
|
|
||||||
background-color: #212121;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
39
src/client/sidebar-icons.jsx
Normal file
39
src/client/sidebar-icons.jsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import {compose} from '@avocado/core';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import contempo from 'contempo';
|
||||||
|
import React, {useState} from 'react';
|
||||||
|
|
||||||
|
const decorate = compose(
|
||||||
|
contempo(require('./sidebar-icons.raw.scss')),
|
||||||
|
);
|
||||||
|
|
||||||
|
const SidebarIcons = () => {
|
||||||
|
const [opened, setOpened] = useState(false);
|
||||||
|
return (
|
||||||
|
<div className="sidebar-icons">
|
||||||
|
<button
|
||||||
|
className={classnames(
|
||||||
|
'icon',
|
||||||
|
'files',
|
||||||
|
{opened},
|
||||||
|
)}
|
||||||
|
onClick={() => setOpened(!opened)}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 477.867 477.867"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M421.649,90.317L336.316,4.983c-1.589-1.593-3.481-2.852-5.564-3.703c-2.059-0.841-4.261-1.276-6.485-1.28H102.4 C74.123,0,51.2,22.923,51.2,51.2v375.467c0,28.277,22.923,51.2,51.2,51.2h273.067c28.277,0,51.2-22.923,51.2-51.2V102.4 C426.643,97.87,424.841,93.531,421.649,90.317z M341.333,58.266l27.068,27.068h-27.068V58.266z M392.533,426.667 c0,9.426-7.641,17.067-17.067,17.067H102.4c-9.426,0-17.067-7.641-17.067-17.067V51.2c0-9.426,7.641-17.067,17.067-17.067h204.8 V102.4c0,9.426,7.641,17.067,17.067,17.067h68.267V426.667z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
SidebarIcons.propTypes = {
|
||||||
|
};
|
||||||
|
|
||||||
|
export default decorate(SidebarIcons);
|
29
src/client/sidebar-icons.raw.scss
Normal file
29
src/client/sidebar-icons.raw.scss
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
:scope {
|
||||||
|
background-color: #333333;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
align-items: center;
|
||||||
|
background-color: inherit;
|
||||||
|
border: none;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
height: 4em;
|
||||||
|
width: 4em;
|
||||||
|
svg {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
path {
|
||||||
|
fill: #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover svg path {
|
||||||
|
fill: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.files {
|
||||||
|
padding: 0.75em;
|
||||||
|
}
|
20
src/client/sidebar.jsx
Normal file
20
src/client/sidebar.jsx
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import {compose} from '@avocado/core';
|
||||||
|
// import classnames from 'classnames';
|
||||||
|
import contempo from 'contempo';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const decorate = compose(
|
||||||
|
contempo(require('./sidebar.raw.scss')),
|
||||||
|
);
|
||||||
|
|
||||||
|
const Sidebar = () => {
|
||||||
|
// const [active, setActive] = useState(false);
|
||||||
|
return (
|
||||||
|
<div className="sidebar" />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Sidebar.propTypes = {
|
||||||
|
};
|
||||||
|
|
||||||
|
export default decorate(Sidebar);
|
5
src/client/sidebar.raw.scss
Normal file
5
src/client/sidebar.raw.scss
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
:scope {
|
||||||
|
background-color: #272727;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
|
@ -1,12 +1,19 @@
|
||||||
|
:scope {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.document-pane {
|
.document-pane {
|
||||||
border-right: 1px solid #1a1a1a;
|
border-right: 1px solid #1a1a1a;
|
||||||
display: none;
|
display: none;
|
||||||
float: left;
|
float: left;
|
||||||
width: calc(100% - 36em);
|
width: calc(100% - 58em);
|
||||||
height: 100vh;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-pane {
|
.settings-pane {
|
||||||
width: 100vw;
|
float: left;
|
||||||
height: 100vh;
|
// width: 58em;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,12 @@
|
||||||
@import '~/client/scss/tabs.scss';
|
|
||||||
@import '~/client/scss/trait.scss';
|
@import '~/client/scss/trait.scss';
|
||||||
|
|
||||||
.react-tabs {
|
:scope {
|
||||||
@extend %tabs;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-tabs__tab-panel {
|
.react-tabs__tab .wrapper {
|
||||||
display: none;
|
width: 10em;
|
||||||
}
|
|
||||||
|
|
||||||
.react-tabs__tab-panel--selected {
|
|
||||||
display: block;
|
|
||||||
height: calc(100vh - 2.7em);
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-tabs__tab-panel input {
|
.react-tabs__tab-panel input {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user