+
);
}
@@ -224,39 +207,30 @@ export default class ActionbarImport extends Component {
);
}
- onDrop = (files) => {
+ onFileSelect = (file, content) => {
const { renderValidation } = this.props;
- const file = files[0];
- const reader = new FileReader();
-
- reader.onload = (e) => {
- const content = e.target.result;
-
- if (typeof renderValidation !== 'function') {
- this.props.onConfirm(content);
- return this.onCloseModal();
- }
-
- const validationBody = renderValidation(content);
+ if (typeof renderValidation !== 'function') {
+ this.props.onConfirm(content);
+ return this.onCloseModal();
+ }
- if (validationBody && validationBody.error) {
- return this.setState({
- step: 1,
- error: true,
- errorText: validationBody.error
- });
- }
+ const validationBody = renderValidation(content);
- this.setState({
+ if (validationBody && validationBody.error) {
+ return this.setState({
step: 1,
- validate: true,
- validationBody,
- content
+ error: true,
+ errorText: validationBody.error
});
- };
+ }
- reader.readAsText(file);
+ this.setState({
+ step: 1,
+ validate: true,
+ validationBody,
+ content
+ });
}
onConfirm = () => {
diff --git a/js/src/ui/Form/FileSelect/fileSelect.css b/js/src/ui/Form/FileSelect/fileSelect.css
new file mode 100644
index 00000000000..1ac5981c4de
--- /dev/null
+++ b/js/src/ui/Form/FileSelect/fileSelect.css
@@ -0,0 +1,52 @@
+/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
+/* This file is part of Parity.
+/*
+/* Parity is free software: you can redistribute it and/or modify
+/* it under the terms of the GNU General Public License as published by
+/* the Free Software Foundation, either version 3 of the License, or
+/* (at your option) any later version.
+/*
+/* Parity is distributed in the hope that it will be useful,
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+/* GNU General Public License for more details.
+/*
+/* You should have received a copy of the GNU General Public License
+/* along with Parity. If not, see .
+*/
+
+$backgroundNormal: rgba(0, 0, 0, 0.2);
+$backgroundNormalHover: rgba(0, 0, 0, 0.5);
+$backgroundError: rgba(255, 0, 0, 0.1);
+$backgroundErrorHover: rgba(255, 0, 0, 0.2);
+
+.dropzone {
+ align-items: center;
+ background: $backgroundNormal;
+ border: 2px dashed #666;
+ border-radius: 0.5em;
+ display: flex;
+ justify-content: center;
+ font-size: 1.2em;
+ height: 12em;
+ transition: all 0.5s ease;
+ width: 100%;
+
+ &:hover {
+ background: $backgroundNormalHover;
+ border-radius: 0;
+ cursor: pointer;
+ }
+
+ &.error {
+ background: $backgroundError;
+
+ &:hover {
+ background: $backgroundErrorHover;
+ }
+ }
+
+ .label {
+ color: #aaa;
+ }
+}
diff --git a/js/src/ui/Form/FileSelect/fileSelect.js b/js/src/ui/Form/FileSelect/fileSelect.js
new file mode 100644
index 00000000000..18b2c8d8e58
--- /dev/null
+++ b/js/src/ui/Form/FileSelect/fileSelect.js
@@ -0,0 +1,76 @@
+// Copyright 2015-2017 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+import React, { Component, PropTypes } from 'react';
+import Dropzone from 'react-dropzone';
+import { FormattedMessage } from 'react-intl';
+
+import { nodeOrStringProptype } from '~/util/proptypes';
+
+import styles from './fileSelect.css';
+
+export default class FileSelect extends Component {
+ static propTypes = {
+ className: PropTypes.string,
+ error: nodeOrStringProptype(),
+ label: nodeOrStringProptype(),
+ onSelect: PropTypes.func.isRequired
+ }
+
+ static defaultProps = {
+ label: (
+
+ )
+ }
+
+ render () {
+ const { className, error, label } = this.props;
+
+ return (
+
+
+ { error || label }
+
+
+ );
+ }
+
+ onDrop = (files) => {
+ const { onSelect } = this.props;
+ const reader = new FileReader();
+ const file = files[0];
+
+ reader.onload = (event) => {
+ onSelect(file.name, event.target.result);
+ };
+
+ reader.readAsText(file);
+ }
+}
diff --git a/js/src/ui/Form/FileSelect/fileSelect.spec.js b/js/src/ui/Form/FileSelect/fileSelect.spec.js
new file mode 100644
index 00000000000..f931fc6550f
--- /dev/null
+++ b/js/src/ui/Form/FileSelect/fileSelect.spec.js
@@ -0,0 +1,118 @@
+// Copyright 2015-2017 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+import { shallow } from 'enzyme';
+import React from 'react';
+import sinon from 'sinon';
+
+import FileSelect from './';
+
+const FILE = {
+ content: 'some test content',
+ name: 'someName'
+};
+
+let component;
+let globalFileReader;
+let instance;
+let onSelect;
+let processedFile;
+
+function stubReader () {
+ globalFileReader = global.FileReader;
+
+ global.FileReader = class {
+ readAsText (file) {
+ processedFile = file;
+
+ this.onload({
+ target: {
+ result: file.content
+ }
+ });
+ }
+ };
+}
+
+function restoreReader () {
+ global.FileReader = globalFileReader;
+}
+
+function render (props = {}) {
+ onSelect = sinon.stub();
+ component = shallow(
+
+ );
+ instance = component.instance();
+
+ return component;
+}
+
+describe('ui/Form/FileSelect', () => {
+ beforeEach(() => {
+ stubReader();
+ render();
+ });
+
+ afterEach(() => {
+ restoreReader();
+ });
+
+ it('renders defaults', () => {
+ expect(component).to.be.ok;
+ });
+
+ describe('DropZone', () => {
+ let label;
+ let zone;
+
+ beforeEach(() => {
+ label = component.find('FormattedMessage');
+ zone = component.find('Dropzone');
+ });
+
+ it('renders the label', () => {
+ expect(label.props().id).to.equal('ui.fileSelect.defaultLabel');
+ });
+
+ it('attaches the onDrop event', () => {
+ expect(zone.props().onDrop).to.equal(instance.onDrop);
+ });
+
+ it('does not allow multiples', () => {
+ expect(zone.props().multiple).to.be.false;
+ });
+ });
+
+ describe('event methods', () => {
+ describe('onDrop', () => {
+ beforeEach(() => {
+ instance.onDrop([ FILE ]);
+ });
+
+ it('reads the file as dropped', () => {
+ expect(processedFile).to.deep.equal(FILE);
+ });
+
+ it('calls prop onSelect with file & content', () => {
+ expect(onSelect).to.have.been.calledWith(FILE.name, FILE.content);
+ });
+ });
+ });
+});
diff --git a/js/src/ui/Form/FileSelect/index.js b/js/src/ui/Form/FileSelect/index.js
new file mode 100644
index 00000000000..ff9614ace19
--- /dev/null
+++ b/js/src/ui/Form/FileSelect/index.js
@@ -0,0 +1,17 @@
+// Copyright 2015-2017 Parity Technologies (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+export default from './fileSelect';
diff --git a/js/src/ui/Form/index.js b/js/src/ui/Form/index.js
index 6a003c4727e..bb5516c89a7 100644
--- a/js/src/ui/Form/index.js
+++ b/js/src/ui/Form/index.js
@@ -16,6 +16,7 @@
export AddressSelect from './AddressSelect';
export DappUrlInput from './DappUrlInput';
+export FileSelect from './FileSelect';
export FormWrap from './FormWrap';
export Input from './Input';
export InputAddress from './InputAddress';
diff --git a/js/src/ui/index.js b/js/src/ui/index.js
index 992bb2b05db..ae1ce8451c3 100644
--- a/js/src/ui/index.js
+++ b/js/src/ui/index.js
@@ -30,7 +30,7 @@ export DappCard from './DappCard';
export DappIcon from './DappIcon';
export Errors from './Errors';
export Features, { FEATURES, FeaturesStore } from './Features';
-export Form, { AddressSelect, DappUrlInput, FormWrap, Input, InputAddress, InputAddressSelect, InputChip, InputDate, InputInline, InputTime, Label, RadioButtons, Select, TypedInput } from './Form';
+export Form, { AddressSelect, DappUrlInput, FileSelect, FormWrap, Input, InputAddress, InputAddressSelect, InputChip, InputDate, InputInline, InputTime, Label, RadioButtons, Select, TypedInput } from './Form';
export GasPriceEditor from './GasPriceEditor';
export GasPriceSelector from './GasPriceSelector';
export Icons from './Icons';