mirror of
https://github.com/strapi/strapi.git
synced 2025-11-02 02:44:55 +00:00
add drop dynamic
This commit is contained in:
parent
167f892519
commit
055ff7a244
@ -13,6 +13,8 @@
|
||||
|
||||
"app.components.InputFile.newFile": "ADD NEW FILE",
|
||||
"app.components.InputFileDetails.details": "Details",
|
||||
"app.components.ImgPreview.hint": "Drag & drop your file into this area or {browse} for a file to upload",
|
||||
"app.components.ImgPreview.hint.browse": "browse",
|
||||
|
||||
"app.components.InstallPluginPage.helmet": "Install plugins",
|
||||
"app.components.InstallPluginPage.title": "Install new plugins",
|
||||
|
||||
@ -11,6 +11,9 @@
|
||||
"app.components.HomePage.button": "Créez votre premier type de contenu",
|
||||
"app.components.HomePage.feedback": "N'hésitez pas à utiliser un des channels ci-dessous pour poser vos questions ou nous donner vos retours.",
|
||||
|
||||
"app.components.ImgPreview.hint": "Drag & drop dans cette zone ou {browse} un fichier à télécharger",
|
||||
"app.components.ImgPreview.hint.browse": "recherchez",
|
||||
|
||||
"app.components.InputFile.newFile": "AJOUTER UN NOUVEAU FICHIER",
|
||||
"app.components.InputFileDetails.details": "Détails",
|
||||
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="105px" height="84px" viewBox="0 0 105 84" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 46.1 (44463) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Icon</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<rect id="path-1" x="0" y="1.35416667" width="77.3333333" height="62.2916667" rx="4"></rect>
|
||||
<rect id="path-2" x="0" y="1.35416667" width="77.3333333" height="62.2916667" rx="4"></rect>
|
||||
</defs>
|
||||
<g id="Pages" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.049999997">
|
||||
<g id="Users-&-Groups---Edit-view" transform="translate(-420.000000, -918.000000)">
|
||||
<g id="Content" transform="translate(269.000000, 157.000000)">
|
||||
<g id="Main-data">
|
||||
<g id="File-#1" transform="translate(23.000000, 695.000000)">
|
||||
<g id="Empty" transform="translate(-8.000000, 21.000000)">
|
||||
<g id="Icon" transform="translate(135.000000, 44.000000)">
|
||||
<g id="picture-o" transform="translate(46.000000, 40.500000) rotate(-12.000000) translate(-46.000000, -40.500000) translate(6.000000, 8.000000)">
|
||||
<g id="Rectangle-4">
|
||||
<use fill="#FAFAFB" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
<rect stroke="#979797" stroke-width="1" x="0.5" y="1.85416667" width="76.3333333" height="61.2916667" rx="4"></rect>
|
||||
</g>
|
||||
<path d="M69.3333333,35.2083333 L69.3333333,54.1666667 L10.6666667,54.1666667 L10.6666667,46.0416667 L24,32.5 L30.6666667,39.2708333 L52,17.6041667 L69.3333333,35.2083333 Z M73.3333333,5.41666667 L6.66666667,5.41666667 C6.30555556,5.41666667 5.99305556,5.55067274 5.72916667,5.8186849 C5.46527778,6.08669705 5.33333333,6.40407986 5.33333333,6.77083333 L5.33333333,58.2291667 C5.33333333,58.5959201 5.46527778,58.913303 5.72916667,59.1813151 C5.99305556,59.4493273 6.30555556,59.5833333 6.66666667,59.5833333 L73.3333333,59.5833333 C73.6944444,59.5833333 74.0069444,59.4493273 74.2708333,59.1813151 C74.5347222,58.913303 74.6666667,58.5959201 74.6666667,58.2291667 L74.6666667,6.77083333 C74.6666667,6.40407986 74.5347222,6.08669705 74.2708333,5.8186849 C74.0069444,5.55067274 73.6944444,5.41666667 73.3333333,5.41666667 Z M80,6.77083333 L80,58.2291667 C80,60.0911458 79.3472222,61.6851128 78.0416667,63.0110677 C76.7361111,64.3370226 75.1666667,65 73.3333333,65 L6.66666667,65 C4.83333333,65 3.26388889,64.3370226 1.95833333,63.0110677 C0.652777778,61.6851128 0,60.0911458 0,58.2291667 L0,6.77083333 C0,4.90885417 0.652777778,3.31488715 1.95833333,1.98893229 C3.26388889,0.662977431 4.83333333,0 6.66666667,0 L73.3333333,0 C75.1666667,0 76.7361111,0.662977431 78.0416667,1.98893229 C79.3472222,3.31488715 80,4.90885417 80,6.77083333 Z" id="Shape" fill="#333740" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
<g id="picture-o" transform="translate(60.000000, 44.500000) rotate(15.000000) translate(-60.000000, -44.500000) translate(20.000000, 12.000000)">
|
||||
<g id="Rectangle-4">
|
||||
<use fill="#FAFAFB" fill-rule="evenodd" xlink:href="#path-2"></use>
|
||||
<rect stroke="#979797" stroke-width="1" x="0.5" y="1.85416667" width="76.3333333" height="61.2916667" rx="4"></rect>
|
||||
</g>
|
||||
<path d="M26.6666667,18.9583333 C26.6666667,21.2152778 25.8888889,23.1336806 24.3333333,24.7135417 C22.7777778,26.2934028 20.8888889,27.0833333 18.6666667,27.0833333 C16.4444444,27.0833333 14.5555556,26.2934028 13,24.7135417 C11.4444444,23.1336806 10.6666667,21.2152778 10.6666667,18.9583333 C10.6666667,16.7013889 11.4444444,14.7829861 13,13.203125 C14.5555556,11.6232639 16.4444444,10.8333333 18.6666667,10.8333333 C20.8888889,10.8333333 22.7777778,11.6232639 24.3333333,13.203125 C25.8888889,14.7829861 26.6666667,16.7013889 26.6666667,18.9583333 Z M69.3333333,35.2083333 L69.3333333,54.1666667 L10.6666667,54.1666667 L10.6666667,46.0416667 L24,32.5 L30.6666667,39.2708333 L52,17.6041667 L69.3333333,35.2083333 Z M73.3333333,5.41666667 L6.66666667,5.41666667 C6.30555556,5.41666667 5.99305556,5.55067274 5.72916667,5.8186849 C5.46527778,6.08669705 5.33333333,6.40407986 5.33333333,6.77083333 L5.33333333,58.2291667 C5.33333333,58.5959201 5.46527778,58.913303 5.72916667,59.1813151 C5.99305556,59.4493273 6.30555556,59.5833333 6.66666667,59.5833333 L73.3333333,59.5833333 C73.6944444,59.5833333 74.0069444,59.4493273 74.2708333,59.1813151 C74.5347222,58.913303 74.6666667,58.5959201 74.6666667,58.2291667 L74.6666667,6.77083333 C74.6666667,6.40407986 74.5347222,6.08669705 74.2708333,5.8186849 C74.0069444,5.55067274 73.6944444,5.41666667 73.3333333,5.41666667 Z M80,6.77083333 L80,58.2291667 C80,60.0911458 79.3472222,61.6851128 78.0416667,63.0110677 C76.7361111,64.3370226 75.1666667,65 73.3333333,65 L6.66666667,65 C4.83333333,65 3.26388889,64.3370226 1.95833333,63.0110677 C0.652777778,61.6851128 0,60.0911458 0,58.2291667 L0,6.77083333 C0,4.90885417 0.652777778,3.31488715 1.95833333,1.98893229 C3.26388889,0.662977431 4.83333333,0 6.66666667,0 L73.3333333,0 C75.1666667,0 76.7361111,0.662977431 78.0416667,1.98893229 C79.3472222,3.31488715 80,4.90885417 80,6.77083333 Z" id="Shape" fill="#333740" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
@ -7,13 +7,21 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { cloneDeep, get, isEmpty, isObject, size } from 'lodash';
|
||||
import cn from 'classnames';
|
||||
|
||||
import BkgImg from 'assets/icons/icon_upload.svg';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class ImgPreview extends React.Component {
|
||||
state = { imgURL: '', position: 0, isImg: false };
|
||||
state = {
|
||||
imgURL: '',
|
||||
isDraging: false,
|
||||
isImg: false,
|
||||
position: 0,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
// We don't need the generateImgURL function here since the compo will
|
||||
@ -83,6 +91,23 @@ class ImgPreview extends React.Component {
|
||||
this.updateFilePosition(nextPosition);
|
||||
}
|
||||
|
||||
handleDragEnter = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.setState({ isDraging: true });
|
||||
}
|
||||
|
||||
handleDragLeave = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.setState({ isDraging: false });
|
||||
}
|
||||
|
||||
handleDrop = (e) => {
|
||||
this.setState({ isDraging: false });
|
||||
this.props.onDrop(e);
|
||||
}
|
||||
|
||||
isPictureType = (fileName) => /\.(jpe?g|png|gif)$/i.test(fileName);
|
||||
|
||||
removeFile = (e) => {
|
||||
@ -133,6 +158,41 @@ class ImgPreview extends React.Component {
|
||||
/>
|
||||
)
|
||||
|
||||
renderContent = () => {
|
||||
const fileType = this.getFileType(this.state.imgURL);
|
||||
|
||||
if (this.state.isImg) {
|
||||
return (
|
||||
<img src={this.state.imgURL} />
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className={styles.fileIcon}>
|
||||
<i className={`fa fa-file-${fileType}-o`} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
renderHint = () => {
|
||||
if (isEmpty(this.state.imgURL) || this.state.isDraging) {
|
||||
return (
|
||||
<div>
|
||||
<p className={cn(this.state.isDraging && styles.hintDropping)}>
|
||||
<FormattedMessage
|
||||
id="app.components.ImgPreview.hint"
|
||||
values={{
|
||||
browse: <FormattedMessage id="app.components.ImgPreview.hint.browse">{(message) => <u>{message}</u>}</FormattedMessage>
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
renderIconRemove = () => (
|
||||
<div className={styles.iconContainer} onClick={this.removeFile}>
|
||||
<i className="fa fa-times" />
|
||||
@ -146,13 +206,28 @@ class ImgPreview extends React.Component {
|
||||
|
||||
render() {
|
||||
const { files, multiple } = this.props;
|
||||
const fileType = this.getFileType(this.state.imgURL);
|
||||
const { imgURL } = this.state;
|
||||
const containerStyle = isEmpty(imgURL) ? { backgroundImage: `url(${BkgImg})` } : {};
|
||||
|
||||
return (
|
||||
<div className={styles.imgPreviewContainer}>
|
||||
<div
|
||||
className={styles.imgPreviewContainer}
|
||||
onDragOver={(e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation();
|
||||
|
||||
if (!this.state.isDraging) {
|
||||
this.setState({ isDraging: true });
|
||||
}
|
||||
}}
|
||||
onDragEnter={this.handleDragEnter}
|
||||
onDragLeave={this.handleDragLeave}
|
||||
onDrop={this.handleDrop}
|
||||
style={containerStyle}
|
||||
>
|
||||
{ this.renderHint() }
|
||||
{ !isEmpty(files) && this.renderIconRemove() }
|
||||
{ !this.state.isImg && <div style={{fontSize: '30px'}}><i className={`fa fa-file-${fileType}-o`} /></div>}
|
||||
{ !isEmpty(this.state.imgURL) && this.state.isImg && <img src={this.state.imgURL} /> }
|
||||
{ !isEmpty(imgURL) && this.renderContent() }
|
||||
{ multiple && size(files) > 1 && this.renderArrow('right') }
|
||||
{ multiple && size(files) > 1 && this.renderArrow('left') }
|
||||
</div>
|
||||
@ -166,6 +241,7 @@ ImgPreview.defaultProps = {
|
||||
multiple: false,
|
||||
name: '',
|
||||
onChange: () => {},
|
||||
onDrop: () => {},
|
||||
updateFilePosition: () => {},
|
||||
};
|
||||
|
||||
@ -175,6 +251,7 @@ ImgPreview.propTypes = {
|
||||
multiple: PropTypes.bool,
|
||||
name: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
onDrop: PropTypes.func,
|
||||
updateFilePosition: PropTypes.func,
|
||||
};
|
||||
|
||||
|
||||
@ -6,7 +6,8 @@
|
||||
}
|
||||
|
||||
.imgPreviewContainer {
|
||||
display: table-cell;
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
height: 144px;
|
||||
width: 358px;
|
||||
position: relative;
|
||||
@ -15,12 +16,23 @@
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
background-color: #F3F4F4;
|
||||
|
||||
background-position: center;
|
||||
white-space: nowrap;
|
||||
> img {
|
||||
max-width: 358px;
|
||||
max-height: 144px;
|
||||
}
|
||||
> p, span {
|
||||
display: block;
|
||||
padding: 12px 40px 0 40px;
|
||||
line-height: 18px;
|
||||
color: #333740;
|
||||
font-size: 13px;
|
||||
white-space: pre-line;
|
||||
> u {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.iconContainer {
|
||||
@ -71,3 +83,33 @@
|
||||
font-weight: 800;
|
||||
}
|
||||
}
|
||||
|
||||
.hintDropping {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 37px;
|
||||
z-index: 9999;
|
||||
padding: 12px 40px 0 40px;
|
||||
line-height: 18px;
|
||||
color: #fff !important;
|
||||
font-size: 13px;
|
||||
white-space: pre-line;
|
||||
> span {
|
||||
display: block;
|
||||
padding: 12px 40px 0 40px;
|
||||
color: #fff;
|
||||
> u {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.fileIcon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
justify-content: space-around;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
@ -17,8 +17,11 @@ import InputFileDetails from 'components/InputFileDetails';
|
||||
import styles from './styles.scss';
|
||||
|
||||
class InputFile extends React.Component {
|
||||
// NOTE: use isDropping to change the background color of the ImgPreview
|
||||
state = { isUploading: false, isDropping: false, position: 0, isOpen: false };
|
||||
state = {
|
||||
isOpen: false,
|
||||
isUploading: false,
|
||||
position: 0,
|
||||
};
|
||||
|
||||
addFilesToProps = (files) => {
|
||||
const value = Object.keys(files).reduce((acc, current) => {
|
||||
@ -39,17 +42,7 @@ class InputFile extends React.Component {
|
||||
|
||||
handleChange = ({ target }) => this.addFilesToProps(target.files);
|
||||
|
||||
handleDragEnter = () => {
|
||||
this.setState({ isDropping: true });
|
||||
}
|
||||
|
||||
handleDragLeave = () => {
|
||||
this.setState({ isDropping: false });
|
||||
}
|
||||
|
||||
handleDragOver = (e) => e.preventDefault();
|
||||
|
||||
handleDrop = (e) => {
|
||||
onDrop = (e) => {
|
||||
e.preventDefault();
|
||||
this.addFilesToProps(e.dataTransfer.files);
|
||||
}
|
||||
@ -66,34 +59,31 @@ class InputFile extends React.Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<label
|
||||
onDragEnter={this.handleDragEnter}
|
||||
onDragLeave={this.handleDragLeave}
|
||||
onDragOver={this.handleDragOver}
|
||||
onDrop={this.handleDrop}
|
||||
>
|
||||
<ImgPreview
|
||||
files={value}
|
||||
isUploading={this.state.isUploading}
|
||||
multiple={multiple}
|
||||
name={name}
|
||||
onChange={onChange}
|
||||
updateFilePosition={this.updateFilePosition}
|
||||
/>
|
||||
<ImgPreview
|
||||
files={value}
|
||||
isUploading={this.state.isUploading}
|
||||
multiple={multiple}
|
||||
name={name}
|
||||
onChange={onChange}
|
||||
onDrop={this.onDrop}
|
||||
updateFilePosition={this.updateFilePosition}
|
||||
/>
|
||||
<label>
|
||||
<input
|
||||
className={styles.inputFile}
|
||||
multiple={multiple}
|
||||
name={name}
|
||||
onChange={this.handleChange}
|
||||
type="file"
|
||||
/>
|
||||
/>
|
||||
|
||||
<div className={styles.buttonContainer}>
|
||||
<i className="fa fa-plus" />
|
||||
<FormattedMessage id="app.components.InputFile.newFile" />
|
||||
</div>
|
||||
</label>
|
||||
<InputFileDetails
|
||||
isOpen={!this.state.isOpen}
|
||||
isOpen={this.state.isOpen}
|
||||
number={value.length}
|
||||
onClick={() => { this.setState({ isOpen: !this.state.isOpen }) }}
|
||||
position={this.state.position}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
width: 100%;
|
||||
width: 358px;
|
||||
height: 34px;
|
||||
text-align: center;
|
||||
background-color: #FAFAFB;
|
||||
|
||||
@ -33,7 +33,7 @@ export class HomePage extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.homePage} style={{ paddingTop: '100px', marginLeft: '100px'}}>
|
||||
<div className={styles.homePage} style={{ paddingTop: '98px', marginLeft: '100px'}}>
|
||||
<form>
|
||||
<InputFile
|
||||
name="test"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user