mirror of
https://github.com/xodio/xod.git
synced 2026-03-23 17:16:53 +01:00
Merge pull request #833 from xodio/tweak-819-scroll-inspector
Make Inspector scrollable
This commit is contained in:
13
packages/xod-client/src/core/styles/components/App.scss
Normal file
13
packages/xod-client/src/core/styles/components/App.scss
Normal 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;
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
bottom: 0;
|
||||
height: 200px;
|
||||
height: 196px;
|
||||
width: 100%;
|
||||
|
||||
color: $sidebar-color-text;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.Editor {
|
||||
flex-grow: 1;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 5%;
|
||||
z-index: 10;
|
||||
|
||||
width: 400px;
|
||||
margin: 0 0 0 -200px;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user