Skip to content

Commit

Permalink
[form-builder] Show paste enable on uploadplaceholder (#583)
Browse files Browse the repository at this point in the history
* [form-builder] Show paste enable on uploadplaceholder

* [form-builder] Remove debug

* [form-builder] Focus-state on uploadarea on imageInput

* [form-builder] Pass onFocus/onBlur to image/file fields
  • Loading branch information
Kristoffer J. Sivertsen authored and bjoerge committed Feb 16, 2018
1 parent c5bfebf commit 9ebff06
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 34 deletions.
27 changes: 22 additions & 5 deletions packages/@sanity/form-builder/src/inputs/File/FileInput.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable complexity */
import type {Node} from 'react'
// @flow
import React from 'react'
Expand Down Expand Up @@ -192,6 +193,7 @@ export default class FileInput extends React.PureComponent<Props, State> {
})))
}


handleStartAdvancedEdit = () => {
this.setState({isAdvancedEditOpen: true})
}
Expand All @@ -215,8 +217,22 @@ export default class FileInput extends React.PureComponent<Props, State> {
return fields.map(field => this.renderField(field))
}

handleFocus = event => {
this.setState({
hasFocus: true
})
this.props.onFocus(event)
}

handleBlur = event => {
this.setState({
hasFocus: false
})
this.props.onBlur(event)
}

renderField(field: FieldT) {
const {value, level, onBlur, focusPath, onFocus} = this.props
const {value, level, onFocus, onBlur, focusPath} = this.props
const fieldValue = value && value[field.name]

return (
Expand Down Expand Up @@ -256,9 +272,9 @@ export default class FileInput extends React.PureComponent<Props, State> {
}

render() {
const {type, value, level, onFocus, materialize} = this.props
const {type, value, level, materialize} = this.props

const {isAdvancedEditOpen, uploadError} = this.state
const {isAdvancedEditOpen, uploadError, hasFocus} = this.state

const [highlightedFields, otherFields] = partition(
type.fields.filter(field => !HIDDEN_FIELDS.includes(field.name)),
Expand All @@ -272,7 +288,8 @@ export default class FileInput extends React.PureComponent<Props, State> {
legend={type.title}
description={type.description}
level={level}
onFocus={onFocus}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
onUpload={this.handleUpload}
getUploadOptions={this.getUploadOptions}
ref={this.setFocusArea}
Expand All @@ -297,7 +314,7 @@ export default class FileInput extends React.PureComponent<Props, State> {
<WithMaterializedReference reference={value.asset} materialize={materialize}>
{this.renderMaterializedAsset}
</WithMaterializedReference>
) : <UploadPlaceholder />}
) : <UploadPlaceholder hasFocus={hasFocus} />}
</div>
{highlightedFields.length > 0 && (
<div className={styles.fieldsWrapper}>
Expand Down
32 changes: 25 additions & 7 deletions packages/@sanity/form-builder/src/inputs/Image/ImageInput.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable complexity */
import type {Node} from 'react'
// @flow
import React from 'react'
Expand Down Expand Up @@ -52,7 +53,8 @@ type Props = {
type State = {
isAdvancedEditOpen: boolean,
isUploading: boolean,
isSelectAssetOpen: boolean
isSelectAssetOpen: boolean,
hasFocus: boolean
}

const HIDDEN_FIELDS = ['asset', 'hotspot', 'crop']
Expand All @@ -63,7 +65,8 @@ export default class ImageInput extends React.PureComponent<Props, State> {
isUploading: false,
uploadError: null,
isAdvancedEditOpen: false,
isSelectAssetOpen: false
isSelectAssetOpen: false,
hasFocus: false
}

handleRemoveButtonClick = (event: SyntheticEvent<*>) => {
Expand Down Expand Up @@ -257,7 +260,7 @@ export default class ImageInput extends React.PureComponent<Props, State> {
}

renderField(field: FieldT) {
const {value, level, onBlur, focusPath, onFocus} = this.props
const {value, level, focusPath, onFocus, onBlur} = this.props
const fieldValue = value && value[field.name]

return (
Expand Down Expand Up @@ -285,6 +288,20 @@ export default class ImageInput extends React.PureComponent<Props, State> {
}
}

handleFocus = event => {
this.setState({
hasFocus: true
})
this.props.onFocus(event)
}

handleBlur = event => {
this.props.onBlur(event)
this.setState({
hasFocus: false
})
}

setFocusArea = (el: ?FocusArea) => {
this._focusArea = el
}
Expand All @@ -301,9 +318,9 @@ export default class ImageInput extends React.PureComponent<Props, State> {
}

render() {
const {type, value, level, onFocus, materialize} = this.props
const {type, value, level, materialize} = this.props

const {isAdvancedEditOpen, isSelectAssetOpen, uploadError} = this.state
const {isAdvancedEditOpen, isSelectAssetOpen, uploadError, hasFocus} = this.state

const [highlightedFields, otherFields] = partition(
type.fields.filter(field => !HIDDEN_FIELDS.includes(field.name)),
Expand All @@ -319,7 +336,8 @@ export default class ImageInput extends React.PureComponent<Props, State> {
legend={type.title}
description={type.description}
level={level}
onFocus={onFocus}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
className={styles.root}
onUpload={this.handleUpload}
getUploadOptions={this.getUploadOptions}
Expand All @@ -345,7 +363,7 @@ export default class ImageInput extends React.PureComponent<Props, State> {
<WithMaterializedReference reference={value.asset} materialize={materialize}>
{this.renderMaterializedAsset}
</WithMaterializedReference>
) : <UploadPlaceholder />}
) : <UploadPlaceholder hasFocus={hasFocus} />}
</div>
{highlightedFields.length > 0 && (
<div className={styles.fieldsWrapper}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,79 @@
// eslint-disable max-len
// @flow
import React from 'react'
import PropTypes from 'prop-types'
import styles from './styles/UploadPlaceholder.css'
import PasteIcon from 'part:@sanity/base/paste-icon'
import UploadIcon from 'part:@sanity/base/upload-icon'

export default function UploadPlaceholder() {
return (
<div className={styles.root}>
<div className={styles.inner}>
<div className={styles.iconContainer}>
<PasteIcon />
</div>
<div>
<p className={styles.strong}>
<span>Paste file</span>
</p>
<p className={styles.light}>
<span>…or drop it here</span>
</p>
export default class UploadPlaceholder extends React.PureComponent {
static propTypes = {
hasFocus: PropTypes.bool
}
render() {
const {hasFocus} = this.props
return (
<div className={hasFocus ? styles.hasFocus : styles.noFocus}>
<div className={styles.inner}>
<div className={styles.dropFile}>
<div className={styles.iconContainer}>
<UploadIcon />
</div>
<p className={styles.strong}>
<span>Drop file</span>
</p>
</div>
<div className={styles.pasteFile}>
<div className={styles.iconContainer}>
<svg
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 30 37"
shapeRendering="geometricPrecision"
>
<path
className={styles.eyeRight}
fill="none"
stroke="currentColor"
height="1em"
width="1em"
d="M4.75,0.75C4.75,0.75,2.95914,0.75,0.75,0.75C-1.45914,0.75,-3.25,0.75,-3.25,0.75C-3.25,0.75,-1.45914,0.75,0.75,0.75C2.95914,0.75,4.75,0.75,4.75,0.75Z"
transform="translate(19.75,16.75)"
/>
<path
className={styles.eyeLeft}
fill="none"
stroke="currentColor"
d="M4.75,0.75C4.75,0.75,2.95914,0.75,0.75,0.75C-1.45914,0.75,-3.25,0.75,-3.25,0.75C-3.25,0.75,-1.45914,0.75,0.75,0.75C2.95914,0.75,4.75,0.75,4.75,0.75Z"
transform="translate(8.75,16.75)"
/>
<path
id="Shape"
d="M26.6,33.4L26.6,6.6L23.4,6.6L23.4,11.6L6.6,11.6L6.6,6.6L3.4,6.6L3.4,33.4L26.6,33.4ZM15,3.4C14.1,3.4,13.4,4.1,13.4,5C13.4,5.9,14.1,6.6,15,6.6C15.9,6.6,16.6,5.9,16.6,5C16.6,4.1,15.9,3.4,15,3.4L15,3.4ZM26.6,3.4C28.4,3.4,30,4.8,30,6.6L30,33.4C30,35.2,28.4,36.6,26.6,36.6L3.4,36.6C1.6,36.6,0,35.2,0,33.4L0,6.6C0,4.8,1.6,3.4,3.4,3.4L10.3,3.4C11,1.4,12.8,0,15,0C17.2,0,19,1.4,19.7,3.4L26.6,3.4L26.6,3.4Z"
fillRule="nonzero"
fill="currentColor"
stroke="none"
strokeWidth="1"
/>
<path
className={styles.smile}
d="M0,0C0,0,4.5,0,10,0C15.5,0,19,0,19,0"
stroke="currentColor"
fill="none"
strokeLinecap="square"
transform="translate(5.5,26.5)"
/>
</svg>
</div>
<div>
<p className={styles.strong}>
<span>Paste file</span>
</p>
</div>
</div>
</div>
</div>
</div>
)
)
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,63 @@
@import 'part:@sanity/base/theme/variables-style';

@keyframes eye-right_d {
0% {
d: path('M4.75,0.75C4.75,0.75,2.95914,0.75,0.75,0.75C-1.45914,0.75,-3.25,0.75,-3.25,0.75C-3.25,0.75,-1.45914,0.75,0.75,0.75C2.95914,0.75,4.75,0.75,4.75,0.75Z'); } 100% { d: path('M4.75,0.75C4.75,2.95914,2.95914,4.75,0.75,4.75C-1.45914,4.75,-3.25,2.95914,-3.25,0.75C-3.25,-1.45914,-1.45914,-3.25,0.75,-3.25C2.95914,-3.25,4.75,-1.45914,4.75,0.75Z');
}
}

@keyframes eye-left_d {
0% {
d: path('M4.75,0.75C4.75,0.75,2.95914,0.75,0.75,0.75C-1.45914,0.75,-3.25,0.75,-3.25,0.75C-3.25,0.75,-1.45914,0.75,0.75,0.75C2.95914,0.75,4.75,0.75,4.75,0.75Z'); } 100% { d: path('M4.75,0.75C4.75,2.95914,2.95914,4.75,0.75,4.75C-1.45914,4.75,-3.25,2.95914,-3.25,0.75C-3.25,-1.45914,-1.45914,-3.25,0.75,-3.25C2.95914,-3.25,4.75,-1.45914,4.75,0.75Z');
}
}

@keyframes smile_d {
0% {
d: path('M0,0C0,0,4.5,0,10,0C15.5,0,19,0,19,0');
}

100% {
d: path('M0,0C0,0,4,5,9.5,5C15,5,19,0,19,0');
}
}

.root {
display: flex;
align-items: center;
justify-content: center;
justify-content: space-between;
text-align: center;
height: 100%;
}

.inner {
display: flex;
flex-wrap: wrap;
align-content: space-between;
}

.hasFocus {
composes: root;

@nest & .eyeRight {
animation: eye-right_d 0.3s linear both;
}

@nest & .eyeLeft {
animation: eye-left_d 0.3s linear both;
}

@nest & .smile {
animation: smile_d 0.3s linear both;
}
}

.noFocus {
composes: root;
}

.iconContainer {
font-size: 2rem;
font-size: 3rem;
}

.strong {
Expand All @@ -19,8 +67,16 @@
padding: 0;
}

.light {
opacity: 0.7;
margin: 0;
padding: 0;
.dropFile,
.pasteFile {
padding: 1rem;
}

.pasteFile {
opacity: 0.2;
transition: opacity linear 0.2s;

@nest .hasFocus & {
opacity: 1;
}
}

0 comments on commit 9ebff06

Please sign in to comment.