refactor: icons and actions
|
@ -1,4 +1,4 @@
|
|||
$sidebar-basis: 10rem;
|
||||
$sidebar-basis: 12rem;
|
||||
|
||||
.project {
|
||||
display: flex;
|
||||
|
|
37
packages/core/src/components/project/sidebar/actions.jsx
Normal 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;
|
|
@ -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>
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 |
BIN
packages/core/src/components/project/sidebar/svg/image.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
packages/core/src/components/project/sidebar/svg/joystick.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/core/src/components/project/sidebar/svg/music.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
|
@ -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 |
|
@ -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 |
BIN
packages/core/src/components/project/sidebar/svg/note.png
Normal file
After Width: | Height: | Size: 832 B |
BIN
packages/core/src/components/project/sidebar/svg/question.png
Normal file
After Width: | Height: | Size: 429 B |
BIN
packages/core/src/components/project/sidebar/svg/sound.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
|
@ -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;
|
|
@ -1,4 +0,0 @@
|
|||
.resource {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|