UNPKG

2.93 kBJavaScriptView Raw
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { CustomInput } from 'reactstrap';
4
5const htmlValidationAttrs = ['min', 'max', 'required'];
6
7let id = 0;
8class FilePicker extends Component {
9 constructor(props) {
10 super(props);
11
12 this.state = {};
13 }
14
15 id = `filePicker-${(id += 1)}`;
16
17 onChange = event => {
18 const { files } = event.target;
19 const { onChange } = this.props;
20 this.value = [];
21 for (let i = 0; i < files.length; i++) {
22 this.value[i] = files[i];
23 }
24 this.setState({ value: this.value });
25 this.validate();
26 if (onChange) onChange(event);
27 };
28
29 reset = () => {
30 this.value = null;
31 this.setState({ value: null });
32 };
33
34 componentDidMount() {
35 if (this.context.FormCtrl && this.props.name) {
36 this.updateValidations();
37 }
38 }
39
40 updateValidations(props = this.props) {
41 this.validations = { ...props.validate };
42
43 Object.keys(props)
44 .filter(val => htmlValidationAttrs.indexOf(val) > -1)
45 .forEach(attr => {
46 if (props[attr]) {
47 this.validations[attr] = this.validations[attr] || {
48 value: props[attr],
49 };
50 } else {
51 delete this.validations[attr];
52 }
53 });
54
55 this.context.FormCtrl.register(this);
56 this.validate();
57 }
58
59 validate() {
60 if (this.context.FormCtrl && this.props.name) {
61 this.context.FormCtrl.validate(this.props.name);
62 }
63 }
64
65 componentWillUnmount() {
66 if (this.context.FormCtrl && this.props.name)
67 this.context.FormCtrl.unregister(this);
68 }
69
70 getValue() {
71 if (!this.value) return '';
72 return this.props.multiple ? this.value || [] : this.value[0];
73 }
74
75 render() {
76 const {
77 tag: Tag,
78 maxSize,
79 allowedFileTypes,
80 children,
81 ...props
82 } = this.props;
83 const file = this.state.value && this.getValue();
84 props.id = props.id || props.name || this.id;
85 return children &&
86 props.name &&
87 file &&
88 (!this.props.multiple || file.length > 0) ? (
89 children({ file, clear: this.reset, reset: this.reset })
90 ) : (
91 <Tag
92 value=""
93 type="file"
94 accept={
95 Array.isArray(allowedFileTypes) && allowedFileTypes.length > 0
96 ? allowedFileTypes.join(',')
97 : undefined
98 }
99 size={maxSize ? maxSize.toString() : undefined}
100 {...props}
101 onChange={this.onChange}
102 />
103 );
104 }
105}
106
107FilePicker.propTypes = {
108 tag: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
109 onChange: PropTypes.func,
110 multiple: PropTypes.bool,
111 children: PropTypes.func,
112 name: PropTypes.string,
113 allowedFileTypes: PropTypes.arrayOf(PropTypes.string),
114 maxSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
115};
116
117FilePicker.defaultProps = {
118 tag: CustomInput,
119};
120
121FilePicker.contextTypes = {
122 FormCtrl: PropTypes.object,
123};
124
125export default FilePicker;