Skip to content

Commit

Permalink
components: add FilePicker component
Browse files Browse the repository at this point in the history
Opens a native browser file picker dialog when the user clicks
the contents of the component. Usage looks something like:

     <FilePicker multiple accept="image/*" onPick={ console.log.bind(console) } >
       <a href="#">Select a few images!</a>
     </FilePicker>

Will be used for Reader's OPML "Import" button, but
is generic enough to turn into a reusable component.
  • Loading branch information
TooTallNate committed Mar 11, 2016
1 parent c3bbea5 commit bb644d0
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 0 deletions.
28 changes: 28 additions & 0 deletions client/components/file-picker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FilePicker
==========

This component opens a native file picker when its children are clicked on.
It is a very thin wrapper around
[`component/file-picker`](https://github.com/component/file-picker)

#### How to use:

```js
var FilePicker = require( 'components/file-picker' );

render: function() {
return (
<FilePicker multiple accept="image/*" onPick={ console.log.bind(console) } >
<a href="#">Select a few images!</a>
</FilePicker>
);
}
```

#### Props

* `multiple`: (bool) Allow selecting multiple files (Defaults to `false`).
* `directory`: (bool) Allow selecting of a directory (Defaults to `false`).
* `accept`: (string) Content type MIME to accept. Wildcards (`*`) are supported.
* `onPick`: (func) Function to call when the user has selected one or more files.

75 changes: 75 additions & 0 deletions client/components/file-picker/docs/example.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* External dependencies
*/
import React from 'react';

/**
* Internal dependencies
*/
import Card from 'components/card';
import Button from 'components/button';
import FilePicker from 'components/file-picker';

export default class FilePickers extends React.Component {
constructor( props ) {
super( props );
this.onSingle = this.onSingle.bind( this );
this.onMulti = this.onMulti.bind( this );
}

onSingle( files ) {
alert( 'Selected file: ' + JSON.stringify( files[0].name ) );
}

onMulti( files ) {
alert( 'Selected files:\n' + [].slice.call( files ).map( ( file ) => {
return ' ' + JSON.stringify( file.name );
} ).join( '\n' ) );
}

render() {
return (
<div className="design-assets__group">
<h2>
<a href="/devdocs/design/file-pickers">File Picker</a>
</h2>
{ this.renderPickers() }
</div>
);
}

renderPickers() {
return (
<Card>

<h4>Select a single file:</h4>
<FilePicker onPick={ this.onSingle } >
<Button>Single Item</Button>
</FilePicker>

<h4>Select a multiple files:</h4>
<FilePicker multiple onPick={ this.onMulti } >
<Button>Multiple Items</Button>
</FilePicker>

<h4>Select a directory:</h4>
<FilePicker directory onPick={ this.onMulti } >
<Button>Directory</Button>
</FilePicker>

<h4>Select a image file:</h4>
<FilePicker accept="image/*" onPick={ this.onSingle } >
<Button>JPEG / PNG / GIF</Button>
</FilePicker>

<h4>Any internal content works:</h4>
<FilePicker onPick={ this.onSingle } >
<a href="#">Select File…</a>
</FilePicker>

</Card>
);
}
}

FilePickers.displayName = 'FilePickers';
44 changes: 44 additions & 0 deletions client/components/file-picker/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/** @ssr-ready **/

/**
* External dependencies
*/
import React from 'react';
import assign from 'lodash/assign';
import noop from 'lodash/noop';
import pick from 'component-file-picker';

export default class FilePicker extends React.Component {
constructor( props ) {
super( props );
this.showPicker = this.showPicker.bind( this );
}

showPicker() {
pick( assign( {}, this.props ), this.props.onPick );
}

render() {
return (
<span className="file-picker" onClick={ this.showPicker } >
{ this.props.children }
</span>
);
}
}

FilePicker.displayName = 'FilePicker';

FilePicker.propTypes = {
multiple: React.PropTypes.bool,
directory: React.PropTypes.bool,
accept: React.PropTypes.string,
onPick: React.PropTypes.func
};

FilePicker.defaultProps = {
multiple: false,
directory: false,
accept: null,
onPick: noop
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"commander": "2.3.0",
"component-classes": "1.2.1",
"component-closest": "0.1.4",
"component-file-picker": "0.2.1",
"component-tip": "2.5.0",
"component-uid": "0.0.2",
"cookie": "0.1.2",
Expand Down

0 comments on commit bb644d0

Please sign in to comment.