From ee8d1e9b824f54a51454eb7148e4467de41e64ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Niechcia=C5=82?= Date: Sat, 18 Jul 2015 12:38:14 +0200 Subject: [PATCH 01/10] extract option component and allow to pass as prop --- src/Option.js | 22 ++++++++++++++++++++++ src/Select.js | 24 +++++++++++++++++------- 2 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 src/Option.js diff --git a/src/Option.js b/src/Option.js new file mode 100644 index 0000000000..7272010e9b --- /dev/null +++ b/src/Option.js @@ -0,0 +1,22 @@ +var React = require('react'); + +var Option = React.createClass({ + render: function() { + var renderedLabel = this.props.renderFunc(this.props.object); + var obj = this.props.object; + + return this.props.object.disabled ? ( +
{renderedLabel}
+ ) : ( +
+ { obj.create ? this.props.addLabelText.replace('{label}', obj.label) : renderedLabel } +
+ ); + } +}); + +module.exports = Option; diff --git a/src/Select.js b/src/Select.js index 927268b34f..f047cad6f0 100644 --- a/src/Select.js +++ b/src/Select.js @@ -6,6 +6,7 @@ var React = require('react'); var Input = require('react-input-autosize'); var classes = require('classnames'); var Value = require('./Value'); +var Option = require('./Option'); var requestId = 0; @@ -44,7 +45,8 @@ var Select = React.createClass({ searchable: React.PropTypes.bool, // whether to enable searching feature or not searchPromptText: React.PropTypes.string, // label to prompt for search input value: React.PropTypes.any, // initial field value - valueRenderer: React.PropTypes.func // valueRenderer: function(option) {} + valueRenderer: React.PropTypes.func, // valueRenderer: function(option) {} + optionComponent: React.PropTypes.func // optionComponent to render }, getDefaultProps: function() { @@ -72,7 +74,8 @@ var Select = React.createClass({ placeholder: 'Select...', searchable: true, searchPromptText: 'Type to search', - value: undefined + value: undefined, + optionComponent: Option }; }, @@ -685,11 +688,18 @@ var Select = React.createClass({ var mouseDown = this.selectValue.bind(this, op); var renderedLabel = renderLabel(op); - return op.disabled ? ( -
{renderedLabel}
- ) : ( -
{ op.create ? this.props.addLabelText.replace('{label}', op.label) : renderedLabel}
- ); + var optionResult = React.createElement(this.props.optionComponent, { + key: 'option-' + op.value, + className: optionClass, + renderFunc: renderLabel, + mouseEnter: mouseEnter, + mouseDown: mouseDown, + click: mouseDown, + addLabelText: this.props.addLabelText, + object: op + }); + + return optionResult; }, this); return ops.length ? ops : ( From fa35c42d0d096888a8931a96ea518bb1d79f625c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Niechcia=C5=82?= Date: Sat, 18 Jul 2015 12:38:42 +0200 Subject: [PATCH 02/10] allow to use passed in props value component or default --- src/Select.js | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/Select.js b/src/Select.js index f047cad6f0..32a6ebc691 100644 --- a/src/Select.js +++ b/src/Select.js @@ -46,7 +46,8 @@ var Select = React.createClass({ searchPromptText: React.PropTypes.string, // label to prompt for search input value: React.PropTypes.any, // initial field value valueRenderer: React.PropTypes.func, // valueRenderer: function(option) {} - optionComponent: React.PropTypes.func // optionComponent to render + optionComponent: React.PropTypes.func, // optionComponent to render + valueComponent: React.PropTypes.func }, getDefaultProps: function() { @@ -75,7 +76,8 @@ var Select = React.createClass({ searchable: true, searchPromptText: 'Type to search', value: undefined, - optionComponent: Option + optionComponent: Option, + valueComponent: Value }; }, @@ -730,14 +732,20 @@ var Select = React.createClass({ if (this.props.multi) { this.state.values.forEach(function(val) { - value.push(); + var onOptionLabelClick = this.handleOptionLabelClick.bind(this, val); + var onRemove = this.removeValue.bind(this, val); + + var valueComponent = React.createElement(this.props.valueComponent, { + key: val.value, + option: val, + renderer: this.props.valueRenderer, + optionLabelClick: !!this.props.onOptionLabelClick, + onOptionLabelClick: onOptionLabelClick, + onRemove: onRemove, + disabled: this.props.disabled + }); + + value.push(valueComponent); }, this); } From b7e751aca7d6b7109d2b3d05484d852a2d15c417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Niechcia=C5=82?= Date: Tue, 21 Jul 2015 21:18:53 +0200 Subject: [PATCH 03/10] add SingleValue component to handle single selection mode --- src/Select.js | 17 ++++++++++++----- src/SingleValue.js | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 src/SingleValue.js diff --git a/src/Select.js b/src/Select.js index 32a6ebc691..adbc127f72 100644 --- a/src/Select.js +++ b/src/Select.js @@ -6,6 +6,7 @@ var React = require('react'); var Input = require('react-input-autosize'); var classes = require('classnames'); var Value = require('./Value'); +var SingleValue = require('./SingleValue'); var Option = require('./Option'); var requestId = 0; @@ -47,7 +48,8 @@ var Select = React.createClass({ value: React.PropTypes.any, // initial field value valueRenderer: React.PropTypes.func, // valueRenderer: function(option) {} optionComponent: React.PropTypes.func, // optionComponent to render - valueComponent: React.PropTypes.func + valueComponent: React.PropTypes.func, // value component to render in multiple mode + singleValueComponent: React.PropTypes.func // single value component when multiple is set to false }, getDefaultProps: function() { @@ -77,7 +79,8 @@ var Select = React.createClass({ searchPromptText: 'Type to search', value: undefined, optionComponent: Option, - valueComponent: Value + valueComponent: Value, + singleValueComponent: SingleValue }; }, @@ -751,16 +754,20 @@ var Select = React.createClass({ if(!this.state.inputValue && (!this.props.multi || !value.length)) { if(this.props.valueRenderer && !!this.state.values.length) { - var val = this.state.values[0] || null; value.push(); } else { - value.push(
{this.state.placeholder}
); + var val = this.state.values[0] || null; + var singleValueComponent = React.createElement(this.props.singleValueComponent, { + key: "placeholder", + value: val, + placeholder: this.state.placeholder + }); + value.push(singleValueComponent); } - } var loading = this.state.isLoading ?