refactor: icons and actions

This commit is contained in:
cha0s 2021-04-02 19:39:09 -05:00
parent 6b9b0469fd
commit ec231bb041
15 changed files with 144 additions and 40 deletions

View File

@ -1,4 +1,4 @@
$sidebar-basis: 10rem;
$sidebar-basis: 12rem;
.project {
display: flex;

View File

@ -0,0 +1,37 @@
import {PropTypes, React} from '@latus/react';
const SidebarActions = ({
collapseAll,
}) => (
<div className="sidebar-actions">
<button
className="button new-file"
label="New resource"
title="New resource"
type="button"
/>
<button
className="button new-folder"
label="New directory"
title="New directory"
type="button"
/>
<button
className="button collapse-all"
label="Collapse all"
onMouseDown={collapseAll}
title="Collapse all"
type="button"
/>
</div>
);
SidebarActions.defaultProps = {};
SidebarActions.propTypes = {
collapseAll: PropTypes.func.isRequired,
};
SidebarActions.displayName = 'SidebarActions';
export default SidebarActions;

View File

@ -6,15 +6,23 @@ import {Tree} from '@avocado/react';
import {
PropTypes,
React,
useLatus,
useState,
} from '@latus/react';
import {createNextState} from '@latus/redux';
import {useHistory, useLocation} from 'react-router-dom';
import SidebarActions from './actions';
const Sidebar = ({label, resourcePaths, uuid}) => {
const history = useHistory();
const latus = useLatus();
const location = useLocation();
const [collapsed, setCollapsed] = useState(JSON.parse(window.localStorage['@persea/core/explorer'] || '{}'));
const [collapsed, __setCollapsed] = useState(JSON.parse(window.localStorage['@persea/core/explorer'] || '{}'));
const setCollapsed = (next) => {
window.localStorage['@persea/core/explorer'] = JSON.stringify(next);
__setCollapsed(next);
};
const treeFromResourcePath = (tree, uuid, [isFile, resourcePath]) => {
const parts = resourcePath.split('/');
parts.shift();
@ -38,11 +46,12 @@ const Sidebar = ({label, resourcePaths, uuid}) => {
});
};
const nodesFromResourcePaths = (label, uuid, resourcePaths) => {
const tree = {label, nodes: []};
const tree = {nodes: []};
resourcePaths
.forEach((resourcePath) => treeFromResourcePath(tree, uuid, resourcePath));
return tree.nodes;
};
const path = join('/project', uuid);
return (
<div className="sidebar">
<Tree
@ -64,11 +73,35 @@ const Sidebar = ({label, resourcePaths, uuid}) => {
/* eslint-enable no-param-reassign */
});
setCollapsed(next);
window.localStorage['@persea/core/explorer'] = JSON.stringify(next);
}
}}
classNames={{
active: location.pathname === path,
collapsed: undefined === collapsed[path] ? true : collapsed[path],
}}
indent={0.5}
label={label}
nodes={nodesFromResourcePaths(label, uuid, resourcePaths)}
renderLabel={({label, nodes, value}) => {
const {displayName} = latus
.get('%resource-controllers')
.find(({matcher}) => value.match(matcher))
.Component;
return (
<div className="label">
{!nodes && <div className={`icon ${displayName}`} />}
<span className="text">{label}</span>
{value === uuid && (
<SidebarActions
collapseAll={(event) => {
event.stopPropagation();
setCollapsed({});
}}
/>
)}
</div>
);
}}
value={uuid}
/>
</div>

View File

@ -1,4 +1,4 @@
$sidebar-basis: 10rem;
$sidebar-basis: 12rem;
.sidebar {
height: 100%;
@ -7,3 +7,62 @@ $sidebar-basis: 10rem;
overflow-y: auto;
width: 100%;
}
.sidebar-actions {
display: none;
line-height: 0;
min-width: 4em;
.sidebar:hover & {
display: block;
}
button {
background-color: transparent;
background-size: cover;
background-repeat: no-repeat;
border: none;
margin: 0;
margin-right: 0.25em;
width: 1em;
height: 1em;
&.collapse-all {
background-image: url('./svg/collapse-all.svg');
}
&.new-file {
background-image: url('./svg/new-file.svg');
}
&.new-folder {
background-image: url('./svg/new-folder.svg');
}
}
}
.sidebar > .tree > .node > .item .label > .text {
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.label > .icon {
background-size: cover;
margin-right: 0.125em;
width: 1em;
height: 1em;
&.AudioComponent {
background-image: url('./svg/sound.png');
}
&.Binary {
background-image: url('./svg/question.png');
}
&.EntityComponent {
background-image: url('./svg/joystick.png');
}
&.ImageComponent {
background-image: url('./svg/image.png');
}
&.SoundComponent {
background-image: url('./svg/music.png');
}
&.TextComponent {
background-image: url('./svg/note.png');
}
}

View File

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 9H4V10H9V9Z" fill="#C5C5C5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 3L6 2H13L14 3V10L13 11H11V13L10 14H3L2 13V6L3 5H5V3ZM6 5H10L11 6V10H13V3H6V5ZM10 6H3V13H10V6Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 7H3V4H0V3H3V0H4V3H7V4H4V7ZM10.5 1.09998L13.9 4.59998L14 5V13.5L13.5 14H3.5L3 13.5V8H4V13H13V6H9V2H5V1H10.2L10.5 1.09998ZM10 2V5H12.9L10 2Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 312 B

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 3H4V0H3V3H0V4H3V7H4V4H7V3ZM5.5 7H5V6H5.3L6.1 5.1L6.5 5H14V4H8V3H14.5L15 3.5V13.5L14.5 14H1.5L1 13.5V6.5V6V5H2V6V6.5V13H14V7V6H6.7L5.9 6.9L5.5 7Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,31 +0,0 @@
import './index.scss';
import {
PropTypes,
React,
useLatus,
} from '@latus/react';
import {useSelector} from '@latus/redux';
import {resourceSelector, UriContext} from '@persea/core';
const Resource = ({uri, uuid}) => {
const latus = useLatus();
const resource = useSelector((state) => resourceSelector(state, `${uuid}${uri}`));
const {Component} = latus.get('%resource-controllers')(uri);
return (
<div className="resource">
<UriContext.Provider value={uri}>
<Component resource={resource} />
</UriContext.Provider>
</div>
);
};
Resource.displayName = 'Resource';
Resource.propTypes = {
uri: PropTypes.string.isRequired,
uuid: PropTypes.string.isRequired,
};
export default Resource;

View File

@ -1,4 +0,0 @@
.resource {
width: 100%;
height: 100%;
}