Merge pull request #833 from xodio/tweak-819-scroll-inspector

Make Inspector scrollable
This commit is contained in:
Kirill Shumilov
2017-10-24 15:35:23 +03:00
committed by GitHub
12 changed files with 149 additions and 59 deletions

View File

@@ -0,0 +1,13 @@
#App {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
position: absolute;
z-index: 1;
top: 0;
right: 0;
bottom: 0;
left: 0;
}

View File

@@ -16,7 +16,7 @@
position: absolute;
z-index: 10;
bottom: 0;
height: 200px;
height: 196px;
width: 100%;
color: $sidebar-color-text;

View File

@@ -0,0 +1,7 @@
.Editor {
flex-grow: 1;
display: flex;
flex-direction: row;
align-items: stretch;
}

View File

@@ -1,3 +1,7 @@
.Inspector-container {
min-height: 0;
min-width: 0
}
.Inspector {
display: block;
@@ -18,19 +22,19 @@
padding: 14px 17px;
color: $input-color-border; // TODO: separate color?
cursor: default;
.nodeName, .patchName {
color: $color-canvas-selected; // TODO: separate color?
}
}
.nodeType {
padding-left: 16px;
color: $sidebar-color-text;
font-size: $font-size-s;
cursor: default;
}
.nodeHelp {
display: block;
position: absolute;
@@ -40,13 +44,13 @@
height: 24px;
border-radius: 50%;
background-color: $input-color-bg;
&:hover {
background-color: #555555;
box-shadow: 0 0 3px 0 rgba(0,0,0,0.5);
}
}
.nodeHelpIcon {
display: block;
width: 24px;
@@ -177,6 +181,8 @@
.inspectorTextInput {
font-family: $font-family-condensed;
min-width: 100%;
max-width: 100%;
width: 100%;
height: 8em;
}

View File

@@ -1,6 +1,10 @@
.PatchWrapper-container {
flex-grow: 1;
position: relative;
}
.PatchWrapper {
position: absolute;
top: 30px;
top: 0;
right: 0;
bottom: 0;
left: 0;
@@ -11,4 +15,4 @@
box-shadow: none;
outline: none;
}
}
}

View File

@@ -1,11 +1,13 @@
.Sidebar {
position: absolute;
width: $sidebar-width;
height: 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
background: $sidebar-color-bg;
& > * {
flex: 1;
border-bottom: 1px solid $sidebar-color-border;
}
@@ -15,4 +17,4 @@
padding: 10px 20px 4px 0;
color: $sidebar-color-text;
}
}
}

View File

@@ -2,6 +2,7 @@
position: absolute;
left: 50%;
top: 5%;
z-index: 10;
width: 400px;
margin: 0 0 0 -200px;

View File

@@ -1,7 +1,10 @@
.Workarea {
position: absolute;
left: 0;
right: 0;
height: 100%;
margin-left: 200px;
.Workarea-container {
flex-grow: 1;
}
.Workarea {
position: relative;
height: 100%;
display: flex;
flex-direction: column;
}

View File

@@ -13,11 +13,13 @@
'base/base';
@import
'components/App',
'components/BackgroundLayer',
'components/Button',
'components/Breadcrumbs',
'components/Comment',
'components/Debugger',
'components/Editor',
'components/Inspector',
'components/Helpbar',
'components/Link',

View File

@@ -4,6 +4,7 @@ import $ from 'sanctuary-def';
import React from 'react';
import { Patch } from 'xod-project';
import { $Maybe } from 'xod-func-tools';
import CustomScroll from 'react-custom-scroll';
import { SELECTION_ENTITY_TYPE } from '../constants';
@@ -16,6 +17,12 @@ import { RenderableSelection } from '../../types';
import sanctuaryPropType from '../../utils/sanctuaryPropType';
// =============================================================================
//
// Sub-components
//
// =============================================================================
const InspectorMessage = ({ text }) => (
<div className="Inspector">
<Widgets.HintWidget
@@ -28,6 +35,55 @@ InspectorMessage.propTypes = {
text: PropTypes.string.isRequired,
};
// =============================================================================
//
// Rendering functions
//
// =============================================================================
const renderSelectedManyElements = selection => (
<InspectorMessage
text={`You have selected: ${selection.length} elements.`}
/>
);
const renderSelectedLink = () => (
<InspectorMessage
text="Links do not have any properties."
/>
);
const renderSelectedComment = () => (
<InspectorMessage
text="Comments do not have any properties."
/>
);
const renderSelectedNode = R.curry(
(onPropUpdate, selection) => (
<NodeInspector
node={selection[0].data}
onPropUpdate={onPropUpdate}
/>
)
);
const renderSelectedPatch = R.curry(
(currentPatch, onPatchDescriptionUpdate) => (
<PatchInspector
patch={currentPatch.getOrElse(null)}
onDescriptionUpdate={onPatchDescriptionUpdate}
/>
)
);
const renderDefault = () => (
<InspectorMessage
text="Open a patch to edit its properties"
/>
);
// =============================================================================
//
// Utils
//
// =============================================================================
// :: [ RenderableSelection ] -> Boolean
const isEntity = entity => R.compose(R.equals(entity), R.prop('entityType'), R.head);
@@ -35,9 +91,15 @@ const isSingleNode = R.both(isOne, isEntity(SELECTION_ENTITY_TYPE.NODE));
const isSingleLink = R.both(isOne, isEntity(SELECTION_ENTITY_TYPE.LINK));
const isSingleComment = R.both(isOne, isEntity(SELECTION_ENTITY_TYPE.COMMENT));
// :: [ RenderableSelection ] -> Patch -> Boolean
const isPatchSelected = (selection, patch) => (
const isPatchSelected = R.curry((patch, selection) => (
(R.isEmpty(selection) && patch.isJust)
);
));
// =============================================================================
//
// Main component
//
// =============================================================================
const Inspector = ({
selection,
@@ -45,44 +107,22 @@ const Inspector = ({
onPropUpdate,
onPatchDescriptionUpdate,
}) => {
if (isMany(selection)) {
return (
<InspectorMessage
text={`You have selected: ${selection.length} elements.`}
/>
);
} else if (isSingleLink(selection)) {
return (
<InspectorMessage
text="Links do not have any properties."
/>
);
} else if (isSingleComment(selection)) {
return (
<InspectorMessage
text="Comments do not have any properties."
/>
);
} else if (isSingleNode(selection)) {
return (
<NodeInspector
node={selection[0].data}
onPropUpdate={onPropUpdate}
/>
);
} else if (isPatchSelected(selection, currentPatch)) {
return (
<PatchInspector
patch={currentPatch.getOrElse(null)}
onDescriptionUpdate={onPatchDescriptionUpdate}
/>
);
}
const inspectorContent = R.cond([
[isMany, renderSelectedManyElements],
[isSingleLink, renderSelectedLink],
[isSingleComment, renderSelectedComment],
[isSingleNode, renderSelectedNode(onPropUpdate)],
[
isPatchSelected(currentPatch),
() => renderSelectedPatch(currentPatch, onPatchDescriptionUpdate),
],
[R.T, renderDefault],
])(selection);
return (
<InspectorMessage
text="Open a patch to edit its properties"
/>
<CustomScroll heightRelativeToParent="100%">
{inspectorContent}
</CustomScroll>
);
};

View File

@@ -140,10 +140,16 @@ class Editor extends React.Component {
return (
<HotKeys handlers={this.getHotkeyHandlers()} className="Editor">
<Sidebar>
<FocusTrap onFocus={() => this.props.actions.setFocusedArea(FOCUS_AREAS.PROJECT_BROWSER)}>
<FocusTrap
className="ProjectBrowser-container"
onFocus={() => this.props.actions.setFocusedArea(FOCUS_AREAS.PROJECT_BROWSER)}
>
<ProjectBrowser />
</FocusTrap>
<FocusTrap onFocus={() => this.props.actions.setFocusedArea(FOCUS_AREAS.INSPECTOR)}>
<FocusTrap
className="Inspector-container"
onFocus={() => this.props.actions.setFocusedArea(FOCUS_AREAS.INSPECTOR)}
>
<Inspector
selection={selection}
currentPatch={currentPatch}
@@ -152,7 +158,10 @@ class Editor extends React.Component {
/>
</FocusTrap>
</Sidebar>
<FocusTrap onFocus={() => this.props.actions.setFocusedArea(FOCUS_AREAS.WORKAREA)}>
<FocusTrap
className="Workarea-container"
onFocus={() => this.props.actions.setFocusedArea(FOCUS_AREAS.WORKAREA)}
>
<Workarea>
<Tabs />
{DebugSessionStopButton}

View File

@@ -115,7 +115,10 @@ class Patch extends React.Component {
const { currentMode } = this.state;
return this.props.connectDropTarget(
<div ref={(r) => { this.dropTargetRootRef = r; }}>
<div
className="PatchWrapper-container"
ref={(r) => { this.dropTargetRootRef = r; }}
>
{MODE_HANDLERS[currentMode].render(this.getApi(currentMode))}
</div>
);