Skip to content

Commit 9925c6c

Browse files
author
theporchrat
committed
1.4.0
1 parent 0a18968 commit 9925c6c

15 files changed

+433
-224
lines changed

browser/react-widgets.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/docs.js

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/calendar/calendar.js

Lines changed: 48 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,35 @@ var React = require('react')
77
, Century = require('./century')
88
, cx = require('../util/cx')
99
, setter = require('../util/stateSetter')
10+
, controlledInput = require('../util/controlledInput')
1011
, SlideTransition = require('../common/slide-transition')
1112
, dates = require('../util/dates')
1213
, mergeIntoProps = require('../util/transferProps').mergeIntoProps
14+
, constants = require('../util/constants')
1315
, _ = require('lodash');
1416

15-
var RIGHT = 'right'
16-
, LEFT = 'left'
17-
, UP = 'up'
18-
, DOWN = 'down'
17+
var dir = constants.directions;
1918

20-
, MULTIPLIER = {
21-
'year': 1,
22-
'decade': 10,
23-
'century': 100
24-
},
25-
VIEW = {
26-
'month': Month,
27-
'year': Year,
28-
'decade': Decade,
29-
'century': Century,
30-
}
31-
NEXT_VIEW = {
32-
'month': 'year',
33-
'year': 'decade',
34-
'decade': 'century'
35-
}
36-
VIEW_UNIT = {
37-
'month': 'day',
38-
'year': 'month',
39-
'decade': 'year',
40-
'century': 'decade',
41-
};
19+
var views = constants.calendarViews
20+
, VIEW_OPTIONS = _.values(views)
21+
, ALT_VIEW = _.invert(constants.calendarViewHierarchy)
22+
, NEXT_VIEW = constants.calendarViewHierarchy
23+
, VIEW_UNIT = constants.calendarViewUnits
24+
, VIEW = _.object([
25+
[views.MONTH, Month],
26+
[views.YEAR, Year],
27+
[views.DECADE, Decade],
28+
[views.CENTURY, Century]
29+
]);
4230

43-
var VIEW_OPTIONS = ['month', 'year', 'decade', 'century'];
31+
var MULTIPLIER = _.object([
32+
[views.YEAR, 1],
33+
[views.DECADE, 10],
34+
[views.CENTURY, 100]
35+
]);
4436

45-
module.exports = React.createClass({
37+
38+
var Calendar = React.createClass({
4639

4740
displayName: 'Calendar',
4841

@@ -86,19 +79,17 @@ module.exports = React.createClass({
8679
getInitialState: function(){
8780
return {
8881
selectedIndex: 0,
89-
open: false,
9082
view: this.props.initialView || 'month',
91-
92-
//determines the position of views
9383
currentDate: this.inRangeValue(new Date(this.props.value))
9484
}
9585
},
9686

9787
getDefaultProps: function(){
9888
return {
89+
open: false,
9990
value: new Date,
100-
min: new Date(1900,0, 1),
101-
max: new Date(2099,11, 31),
91+
min: new Date(1900,0, 1),
92+
max: new Date(2099,11, 31),
10293

10394
initialView: 'month',
10495
finalView: 'century',
@@ -134,7 +125,6 @@ module.exports = React.createClass({
134125
, key = this.state.view + '_' + dates[this.state.view](date)
135126
, id = this._id('_view');
136127

137-
//console.log(key)
138128
return mergeIntoProps(_.omit(this.props, 'value', 'min', 'max'),
139129
React.DOM.div({className: cx({
140130
'rw-calendar': true,
@@ -148,11 +138,11 @@ module.exports = React.createClass({
148138
labelId: labelId,
149139
messages: this.props.messages,
150140
upDisabled: disabled || this.state.view === this.props.finalView,
151-
prevDisabled: disabled || !dates.inRange(this.nextDate(LEFT), this.props.min, this.props.max),
152-
nextDisabled: disabled || !dates.inRange(this.nextDate(RIGHT), this.props.min, this.props.max),
153-
onViewChange: this._maybeHandle(_.partial(this.navigate, UP, null)),
154-
onMoveLeft: this._maybeHandle(_.partial(this.navigate, LEFT, null)),
155-
onMoveRight: this._maybeHandle(_.partial(this.navigate, RIGHT, null))}),
141+
prevDisabled: disabled || !dates.inRange(this.nextDate(dir.LEFT), this.props.min, this.props.max),
142+
nextDisabled: disabled || !dates.inRange(this.nextDate(dir.RIGHT), this.props.min, this.props.max),
143+
onViewChange: this._maybeHandle(_.partial(this.navigate, dir.UP, null)),
144+
onMoveLeft: this._maybeHandle(_.partial(this.navigate, dir.LEFT, null)),
145+
onMoveRight: this._maybeHandle(_.partial(this.navigate, dir.RIGHT, null))}),
156146

157147
SlideTransition({
158148
ref: "animation",
@@ -168,8 +158,8 @@ module.exports = React.createClass({
168158
onChange: this._maybeHandle(this.change),
169159
onKeyDown: this._maybeHandle(this._keyDown),
170160
onFocus: this._maybeHandle(_.partial(this._focus, true), true),
171-
onMoveLeft: this._maybeHandle(_.partial(this.navigate, LEFT)),
172-
onMoveRight: this._maybeHandle(_.partial(this.navigate, RIGHT)),
161+
onMoveLeft: this._maybeHandle(_.partial(this.navigate, dir.LEFT)),
162+
onMoveRight: this._maybeHandle(_.partial(this.navigate, dir.RIGHT)),
173163
disabled: this.props.disabled,
174164
readOnly: this.props.readOnly,
175165
min: this.props.min,
@@ -184,21 +174,20 @@ module.exports = React.createClass({
184174
},
185175

186176
navigate: function(direction, date){
187-
var alts = _.invert(NEXT_VIEW)
188-
, view = this.state.view
189-
, slideDir = (direction === LEFT || direction === UP)
177+
var view = this.state.view
178+
, slideDir = (direction === dir.LEFT || direction === dir.UP)
190179
? 'right'
191180
: 'left';
192181

193182
if ( !date )
194-
date = _.contains([ LEFT, RIGHT ], direction)
183+
date = _.contains([ dir.LEFT, dir.RIGHT ], direction)
195184
? this.nextDate(direction)
196185
: this.state.currentDate
197186

198-
if (direction === DOWN )
199-
view = alts[view] || view
187+
if (direction === dir.DOWN )
188+
view = ALT_VIEW[view] || view
200189

201-
if (direction === UP )
190+
if (direction === dir.UP )
202191
view = NEXT_VIEW[view] || view
203192

204193
if ( this.isValidView(view) && dates.inRange(date, this.props.min, this.props.max, view)) {
@@ -221,15 +210,15 @@ module.exports = React.createClass({
221210

222211
change: function(date){
223212
if ( this.props.onChange && this.state.view === this.props.initialView)
224-
return this.props.onChange(date)
213+
return this.notify('onChange', date)
225214

226-
this.navigate(DOWN, date)
215+
this.navigate(dir.DOWN, date)
227216
},
228217

229218
nextDate: function(direction){
230-
var method = direction === LEFT ? 'subtract' : 'add'
219+
var method = direction === dir.LEFT ? 'subtract' : 'add'
231220
, view = this.state.view
232-
, unit = view === 'month' ? view : 'year'
221+
, unit = view === views.MONTH ? view : views.YEAR
233222
, multi = MULTIPLIER[view] || 1;
234223

235224
return dates[method](this.state.currentDate, 1 * multi, unit)
@@ -242,19 +231,19 @@ module.exports = React.createClass({
242231
if ( ctrl ) {
243232
if ( key === 'ArrowDown' ) {
244233
e.preventDefault()
245-
this.navigate(DOWN)
234+
this.navigate(dir.DOWN)
246235
}
247236
if ( key === 'ArrowUp' ) {
248237
e.preventDefault()
249-
this.navigate(UP)
238+
this.navigate(dir.UP)
250239
}
251240
if ( key === 'ArrowLeft' ) {
252241
e.preventDefault()
253-
this.navigate(LEFT)
242+
this.navigate(dir.LEFT)
254243
}
255244
if ( key === 'ArrowRight' ) {
256245
e.preventDefault()
257-
this.navigate(RIGHT)
246+
this.navigate(dir.RIGHT)
258247
}
259248
} else {
260249
this.refs.currentView._keyDown
@@ -299,3 +288,6 @@ module.exports = React.createClass({
299288
return current >= bottom && current <= top
300289
}
301290
});
291+
292+
module.exports = controlledInput.createControlledClass(
293+
'Calendar', Calendar, { value: 'onChange' });

lib/common/slide-transition.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ var SlideChildGroup = React.createClass({displayName: 'SlideChildGroup',
2424
width = direction === 'left' ? width : -width
2525

2626
this.ORGINAL_POSITION = node.style.position;
27-
27+
2828
$.css(node, { position: 'absolute', left: width + 'px' , top: 0 })
2929

3030
$.animate(node, { left: 0 }, self.props.duration, function(){
31+
3132
$.css(node, {
3233
position: self.ORGINAL_POSITION,
3334
overflow: 'hidden'

lib/dropdowns/combobox.js

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var React = require('react')
44
, _ = require('lodash')
55
, caretPos = require('../util/caret')
66
, filter = require('../util/filter')
7+
, controlledInput = require('../util/controlledInput')
78
, mergeIntoProps = require('../util/transferProps').mergeIntoProps
89
, directions = require('../util/constants').directions
910
, Input = require('./combo-input')
@@ -13,8 +14,12 @@ var React = require('react')
1314

1415
var btn = require('../common/btn')
1516
, propTypes = {
17+
//-- controlled props -----------
1618
value: React.PropTypes.any,
1719
onChange: React.PropTypes.func,
20+
open: React.PropTypes.bool,
21+
onToggle: React.PropTypes.func,
22+
//------------------------------------
1823

1924
itemComponent: React.PropTypes.func,
2025

@@ -45,7 +50,7 @@ var btn = require('../common/btn')
4550
})
4651
};
4752

48-
module.exports = React.createClass({
53+
var ComboBox = React.createClass({
4954

5055
displayName: 'ComboBox',
5156

@@ -62,11 +67,8 @@ module.exports = React.createClass({
6267
propTypes: propTypes,
6368

6469
getInitialState: function(){
65-
var items = this.process(
66-
this.props.data
67-
, this.props.value)
68-
, idx = this._dataIndexOf(items, this.props.value);
69-
70+
var items = this.process(this.props.data, this.props.value)
71+
, idx = this._dataIndexOf(items, this.props.value);
7072

7173
return {
7274
selectedIndex: idx,
@@ -79,6 +81,8 @@ module.exports = React.createClass({
7981
getDefaultProps: function(){
8082
return {
8183
data: [],
84+
value: '',
85+
open: false,
8286
suggest: false,
8387
filter: false,
8488
delay: 500,
@@ -143,7 +147,7 @@ module.exports = React.createClass({
143147
'rw-combobox': true,
144148
'rw-widget': true,
145149
'rw-state-focus': this.state.focused,
146-
'rw-open': this.state.open,
150+
'rw-open': this.props.open,
147151
'rw-state-disabled': this.props.disabled,
148152
'rw-state-readonly': this.props.readOnly,
149153
'rw-rtl': this.isRtl()
@@ -165,8 +169,8 @@ module.exports = React.createClass({
165169
'aria-owns': listID,
166170
'aria-busy': !!this.props.busy,
167171
'aria-autocomplete': completeType,
168-
'aria-activedescendent': this.state.open ? optID : undefined,
169-
'aria-expanded': this.state.open,
172+
'aria-activedescendent': this.props.open ? optID : undefined,
173+
'aria-expanded': this.props.open,
170174
'aria-haspopup': true,
171175
placeholder: this.props.placeholder,
172176
disabled: this.props.disabled,
@@ -176,12 +180,12 @@ module.exports = React.createClass({
176180
onChange: this._inputTyping,
177181
onKeyDown: this._inputKeyDown}),
178182

179-
Popup({open: this.state.open, onRequestClose: this.close, duration: this.props.duration},
183+
Popup({open: this.props.open, onRequestClose: this.close, duration: this.props.duration},
180184
React.DOM.div(null,
181185
List({ref: "list",
182186
id: listID,
183187
optID: optID,
184-
'aria-hidden': !this.state.open,
188+
'aria-hidden': !this.props.open,
185189
'aria-live': completeType && 'polite',
186190
style: { maxHeight: 200, height: 'auto'},
187191
data: items,
@@ -266,7 +270,7 @@ module.exports = React.createClass({
266270
, character = String.fromCharCode(e.keyCode)
267271
, selectedIdx = this.state.selectedIndex
268272
, focusedIdx = this.state.focusedIndex
269-
, isOpen = this.state.open
273+
, isOpen = this.props.open
270274
, noselection = selectedIdx == null || selectedIdx === -1;
271275

272276
if ( key === 'End' )
@@ -310,28 +314,24 @@ module.exports = React.createClass({
310314
},
311315

312316
change: function(data, typing){
313-
var change = this.props.onChange
314-
315317
this._typedChange = !!typing
316-
317-
if ( change ) change(data)
318+
this.notify('onChange', data)
318319
},
319320

320321
open: function(){
321-
322-
if ( !this.state.open )
323-
this.setState({ open: true })
322+
if ( !this.props.open )
323+
this.notify('onToggle', true)
324324
},
325325

326326
close: function(){
327-
if ( this.state.open )
328-
this.setState({ open: false })
327+
if ( this.props.open )
328+
this.notify('onToggle', true)
329329
},
330330

331331
toggle: function(e){
332332
this._focus(true)
333333

334-
this.state.open
334+
this.props.open
335335
? this.close()
336336
: this.open()
337337
},
@@ -367,6 +367,13 @@ module.exports = React.createClass({
367367
}
368368
})
369369

370+
371+
module.exports = controlledInput.createControlledClass(
372+
'ComboBox', ComboBox
373+
, { open: 'onToggle', value: 'onChange' });
374+
375+
376+
370377
function shallowEqual(objA, objB) {
371378
var key;
372379

0 commit comments

Comments
 (0)