Merge pull request #284 from netlify/entry-editor-ui
improve entry editor UI
This commit is contained in:
commit
f23229bcb6
@ -1,3 +1,5 @@
|
|||||||
|
@import "../UI/theme";
|
||||||
|
|
||||||
.control {
|
.control {
|
||||||
color: #7c8382;
|
color: #7c8382;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -9,12 +11,13 @@
|
|||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 12px 0 10px 0;
|
padding: 12px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: none;
|
border: none;
|
||||||
|
border-radius: var(--borderRadius);
|
||||||
outline: 0;
|
outline: 0;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
background: 0 0;
|
background-color: var(--controlBGColor);
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
color: #7c8382;
|
color: #7c8382;
|
||||||
}
|
}
|
||||||
@ -22,8 +25,8 @@
|
|||||||
|
|
||||||
.label {
|
.label {
|
||||||
display: block;
|
display: block;
|
||||||
color: #AAB0AF;
|
color: var(--controlLabelColor);
|
||||||
font-size: 12px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.labelWithError {
|
.labelWithError {
|
||||||
@ -37,31 +40,3 @@
|
|||||||
color: #FF706F;
|
color: #FF706F;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.widget {
|
|
||||||
border-bottom: 1px solid #e8eae8;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 42px;
|
|
||||||
bottom: -7px;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
background-color: #f2f5f4;
|
|
||||||
-webkit-transform: rotate(45deg);
|
|
||||||
transform: rotate(45deg);
|
|
||||||
z-index: 1;
|
|
||||||
border-right: 1px solid #e8eae8;
|
|
||||||
border-bottom: 1px solid #e8eae8;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child:after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
border-right: 1px solid var(--defaultColorLight);
|
border-right: 1px solid var(--defaultColorLight);
|
||||||
|
background-color: color(#f2f5f4 lightness(90%));
|
||||||
}
|
}
|
||||||
|
|
||||||
.previewPane {
|
.previewPane {
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
--textFieldBorderColor: #e7e7e7;
|
--textFieldBorderColor: #e7e7e7;
|
||||||
--highlightFGColor: #fff;
|
--highlightFGColor: #fff;
|
||||||
--highlightBGColor: #3ab7a5;
|
--highlightBGColor: #3ab7a5;
|
||||||
|
--controlLabelColor: #272e30;
|
||||||
|
--controlBGColor: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.base {
|
.base {
|
||||||
|
@ -1,55 +1,66 @@
|
|||||||
|
@import "../UI/theme";
|
||||||
|
|
||||||
:global(.list-item-dragging) {
|
:global(.list-item-dragging) {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addButton {
|
.addButton {
|
||||||
display: block;
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin: 20px 0;
|
margin-top: 20px;
|
||||||
border: none;
|
padding: 8px;
|
||||||
background: transparent;
|
border: 0;
|
||||||
&::before {
|
border-radius: var(--borderRadius);
|
||||||
content: "+";
|
background-color: var(--controlBGColor);
|
||||||
display: inline-block;
|
}
|
||||||
margin-right: 5px;
|
|
||||||
width: 15px;
|
.addButtonIcon {
|
||||||
height: 15px;
|
font-size: 18px;
|
||||||
border: 1px solid #444;
|
}
|
||||||
border-radius: 100%;
|
|
||||||
background: transparent;
|
.addButtonText {
|
||||||
line-height: 13px;
|
margin-left: 4px;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.removeButton {
|
.removeButton {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px;
|
top: 2px;
|
||||||
right: 5px;
|
right: 2px;
|
||||||
display: inline-block;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: none;
|
display: flex;
|
||||||
background: transparent;
|
align-items: center;
|
||||||
width: 15px;
|
padding: 0 0 2px 2px;
|
||||||
height: 15px;
|
border: 0;
|
||||||
border: 1px solid #444;
|
background: none;
|
||||||
border-radius: 100%;
|
z-index: 1;
|
||||||
line-height: 13px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggleButton {
|
.toggleButton {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px;
|
top: 0;
|
||||||
left: 5px;
|
left: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 28px;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--borderRadius) 0 0 var(--borderRadius);
|
||||||
|
background: rgba(0,0,0,0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 20px;
|
padding-left: 24px;
|
||||||
cursor: move;
|
cursor: move;
|
||||||
}
|
}
|
||||||
|
|
||||||
.objectLabel {
|
.objectLabel {
|
||||||
border: 1px solid #e8eae8;
|
border: 2px solid rgba(0,0,0,0.1);
|
||||||
|
border-top-width: 28px;
|
||||||
|
border-radius: var(--borderRadius);
|
||||||
|
border-top-left-radius: 0;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
display: none;
|
display: none;
|
||||||
@ -57,6 +68,8 @@
|
|||||||
|
|
||||||
.objectControl {
|
.objectControl {
|
||||||
display: block;
|
display: block;
|
||||||
|
border-top: 28px solid rgba(0,0,0,0.1);
|
||||||
|
border-top-left-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.expanded {
|
.expanded {
|
||||||
@ -70,3 +83,11 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dragIcon {
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { List, Map, fromJS } from 'immutable';
|
import { List, Map, fromJS } from 'immutable';
|
||||||
import { sortable } from 'react-sortable';
|
import { sortable } from 'react-sortable';
|
||||||
|
import FontIcon from 'react-toolbox/lib/font_icon';
|
||||||
import ObjectControl from './ObjectControl';
|
import ObjectControl from './ObjectControl';
|
||||||
import styles from './ListControl.css';
|
import styles from './ListControl.css';
|
||||||
|
|
||||||
@ -143,21 +144,23 @@ export default class ListControl extends Component {
|
|||||||
outline="list"
|
outline="list"
|
||||||
>
|
>
|
||||||
<div className={classNames.join(' ')}>
|
<div className={classNames.join(' ')}>
|
||||||
<div className={styles.objectLabel}>{this.objectLabel(item)}</div>
|
|
||||||
<div className={styles.objectControl}>
|
|
||||||
<ObjectControl
|
|
||||||
value={item}
|
|
||||||
field={field}
|
|
||||||
onChange={this.handleChangeFor(index)}
|
|
||||||
getAsset={getAsset}
|
|
||||||
onAddAsset={onAddAsset}
|
|
||||||
onRemoveAsset={onRemoveAsset}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<button className={styles.toggleButton} onClick={this.handleToggle(index)}>
|
<button className={styles.toggleButton} onClick={this.handleToggle(index)}>
|
||||||
{collapsed ? '+' : '-'}
|
<FontIcon value={collapsed ? 'expand_more' : 'expand_less'} />
|
||||||
</button>
|
</button>
|
||||||
<button className={styles.removeButton} onClick={this.handleRemove(index)}>x</button>
|
<FontIcon value="drag_handle" className={styles.dragIcon} />
|
||||||
|
<button className={styles.removeButton} onClick={this.handleRemove(index)}>
|
||||||
|
<FontIcon value="close" />
|
||||||
|
</button>
|
||||||
|
<div className={styles.objectLabel}>{this.objectLabel(item)}</div>
|
||||||
|
<ObjectControl
|
||||||
|
value={item}
|
||||||
|
field={field}
|
||||||
|
className={styles.objectControl}
|
||||||
|
onChange={this.handleChangeFor(index)}
|
||||||
|
getAsset={getAsset}
|
||||||
|
onAddAsset={onAddAsset}
|
||||||
|
onRemoveAsset={onRemoveAsset}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</SortableListItem>);
|
</SortableListItem>);
|
||||||
}
|
}
|
||||||
@ -166,7 +169,10 @@ export default class ListControl extends Component {
|
|||||||
const { value, forID } = this.props;
|
const { value, forID } = this.props;
|
||||||
return (<div id={forID}>
|
return (<div id={forID}>
|
||||||
{value && value.map((item, index) => this.renderItem(item, index))}
|
{value && value.map((item, index) => this.renderItem(item, index))}
|
||||||
<div><button className={styles.addButton} onClick={this.handleAdd}>new</button></div>
|
<button className={styles.addButton} onClick={this.handleAdd}>
|
||||||
|
<FontIcon value="add" className={styles.addButtonIcon} />
|
||||||
|
<span className={styles.addButtonText}>new</span>
|
||||||
|
</button>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@import "../../../UI/theme";
|
||||||
|
|
||||||
.editor {
|
.editor {
|
||||||
position: relative;
|
position: relative;
|
||||||
& h1, & h2, & h3 {
|
& h1, & h2, & h3 {
|
||||||
@ -57,6 +59,9 @@
|
|||||||
:global {
|
:global {
|
||||||
& .ProseMirror {
|
& .ProseMirror {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
background-color: var(--controlBGColor);
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: var(--borderRadius);
|
||||||
}
|
}
|
||||||
|
|
||||||
& .ProseMirror-content {
|
& .ProseMirror-content {
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
@import "../UI/theme";
|
||||||
|
|
||||||
.root {
|
.root {
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 1px solid #e8eae8;
|
border: 2px solid rgba(0,0,0,0.1);
|
||||||
|
border-radius: var(--borderRadius);
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
padding: 20px;
|
padding: 0 20px 12px;
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,12 @@ export default class ObjectControl extends Component {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
onAddAsset: PropTypes.func.isRequired,
|
onAddAsset: PropTypes.func.isRequired,
|
||||||
|
onRemoveAsset: PropTypes.func.isRequired,
|
||||||
getAsset: PropTypes.func.isRequired,
|
getAsset: PropTypes.func.isRequired,
|
||||||
value: PropTypes.node,
|
value: PropTypes.node,
|
||||||
field: PropTypes.object,
|
field: PropTypes.object,
|
||||||
forID: PropTypes.string.isRequired,
|
forID: PropTypes.string.isRequired,
|
||||||
|
className: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
controlFor(field) {
|
controlFor(field) {
|
||||||
@ -21,9 +23,10 @@ export default class ObjectControl extends Component {
|
|||||||
|
|
||||||
return (<div className={controlStyles.widget} key={field.get('name')}>
|
return (<div className={controlStyles.widget} key={field.get('name')}>
|
||||||
<div className={controlStyles.control} key={field.get('name')}>
|
<div className={controlStyles.control} key={field.get('name')}>
|
||||||
<label className={controlStyles.label}>{field.get('label')}</label>
|
<label className={controlStyles.label} htmlFor={field.get('name')}>{field.get('label')}</label>
|
||||||
{
|
{
|
||||||
React.createElement(widget.control, {
|
React.createElement(widget.control, {
|
||||||
|
id: field.get('name'),
|
||||||
field,
|
field,
|
||||||
value: fieldValue,
|
value: fieldValue,
|
||||||
onChange: (val, metadata) => {
|
onChange: (val, metadata) => {
|
||||||
@ -42,10 +45,11 @@ export default class ObjectControl extends Component {
|
|||||||
const { field, forID } = this.props;
|
const { field, forID } = this.props;
|
||||||
const multiFields = field.get('fields');
|
const multiFields = field.get('fields');
|
||||||
const singleField = field.get('field');
|
const singleField = field.get('field');
|
||||||
|
const className = this.props.className || '';
|
||||||
|
|
||||||
if (multiFields) {
|
if (multiFields) {
|
||||||
return (<div id={forID} className={styles.root}>
|
return (<div id={forID} className={`${ className } ${ styles.root }`}>
|
||||||
{multiFields.map(field => this.controlFor(field))}
|
{multiFields.map(f => this.controlFor(f))}
|
||||||
</div>);
|
</div>);
|
||||||
} else if (singleField) {
|
} else if (singleField) {
|
||||||
return this.controlFor(singleField);
|
return this.controlFor(singleField);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user