rsuite 4.9.1 → 4.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +46 -14
  2. package/dist/rsuite.js +1565 -296
  3. package/dist/rsuite.min.js +2 -2
  4. package/dist/rsuite.min.js.map +1 -1
  5. package/dist/styles/rsuite-dark-rtl.css +2 -1
  6. package/dist/styles/rsuite-dark-rtl.min.css +1 -1
  7. package/dist/styles/rsuite-dark-rtl.min.css.map +1 -1
  8. package/dist/styles/rsuite-dark.css +2 -1
  9. package/dist/styles/rsuite-dark.min.css +1 -1
  10. package/dist/styles/rsuite-dark.min.css.map +1 -1
  11. package/dist/styles/rsuite-default-rtl.css +2 -1
  12. package/dist/styles/rsuite-default-rtl.min.css +1 -1
  13. package/dist/styles/rsuite-default-rtl.min.css.map +1 -1
  14. package/dist/styles/rsuite-default.css +2 -1
  15. package/dist/styles/rsuite-default.min.css +1 -1
  16. package/dist/styles/rsuite-default.min.css.map +1 -1
  17. package/es/InputPicker/InputPicker.js +1 -13
  18. package/es/MultiCascader/DropdownMenu.js +1 -1
  19. package/es/MultiCascader/MultiCascader.d.ts +8 -0
  20. package/es/MultiCascader/MultiCascader.js +6 -3
  21. package/es/Nav/Nav.js +5 -4
  22. package/es/Table/styles/common.less +2 -1
  23. package/es/Uploader/Uploader.js +2 -0
  24. package/lib/InputPicker/InputPicker.js +1 -13
  25. package/lib/MultiCascader/DropdownMenu.js +1 -1
  26. package/lib/MultiCascader/MultiCascader.d.ts +8 -0
  27. package/lib/MultiCascader/MultiCascader.js +6 -3
  28. package/lib/Nav/Nav.js +4 -3
  29. package/lib/Table/styles/common.less +2 -1
  30. package/lib/Uploader/Uploader.js +2 -0
  31. package/package.json +2 -2
  32. package/src/InputPicker/InputPicker.tsx +1 -8
  33. package/src/MultiCascader/DropdownMenu.tsx +1 -1
  34. package/src/MultiCascader/MultiCascader.d.ts +8 -0
  35. package/src/MultiCascader/MultiCascader.tsx +4 -2
  36. package/src/MultiCascader/test/DropdownMenuSpec.js +17 -0
  37. package/src/MultiCascader/test/MultiCascaderSpec.js +14 -1
  38. package/src/Nav/Nav.tsx +10 -4
  39. package/src/Nav/test/NavSpec.js +35 -0
  40. package/src/Table/styles/common.less +2 -1
  41. package/src/Uploader/Uploader.tsx +1 -0
  42. package/src/Whisper/test/WhisperSpec.js +15 -4
@@ -403,18 +403,6 @@ function (_React$Component) {
403
403
  (_this$triggerRef$curr5 = _this.triggerRef.current) === null || _this$triggerRef$curr5 === void 0 ? void 0 : _this$triggerRef$curr5.show();
404
404
  };
405
405
 
406
- _this.handleInputBlur = function () {
407
- if (!_this.props.multi) {
408
- var _this$triggerRef$curr6;
409
-
410
- _this.setState({
411
- open: false
412
- });
413
-
414
- (_this$triggerRef$curr6 = _this.triggerRef.current) === null || _this$triggerRef$curr6 === void 0 ? void 0 : _this$triggerRef$curr6.hide();
415
- }
416
- };
417
-
418
406
  _this.removeLastItem = function (event) {
419
407
  var tagName = _get(event, 'target.tagName');
420
408
 
@@ -796,7 +784,7 @@ function (_React$Component) {
796
784
  tabIndex: tabIndex,
797
785
  onChange: this.handleSearch,
798
786
  value: this.state.open ? this.state.searchKeyword : '',
799
- onBlur: createChainedFunction(this.handleInputBlur, onBlur),
787
+ onBlur: onBlur,
800
788
  onFocus: createChainedFunction(this.handleInputFocus, onFocus)
801
789
  }));
802
790
  };
@@ -146,7 +146,7 @@ function (_React$Component) {
146
146
  className: classes,
147
147
  componentClass: "li",
148
148
  indeterminate: cascade && !active && this.utils.isSomeChildChecked(node, value),
149
- onSelectItem: this.handleSelect.bind(this, layer, node),
149
+ onSelectItem: this.handleSelect.bind(this, layer),
150
150
  onCheck: onCheck,
151
151
  checkable: !uncheckable
152
152
  }, renderMenuItem ? renderMenuItem(label, node) : label, children ? React.createElement("span", {
@@ -41,6 +41,14 @@ export interface MultiCascaderProps<ValueType = any> extends FormControlPickerPr
41
41
  event: React.SyntheticEvent<HTMLElement>
42
42
  ) => void;
43
43
 
44
+ /** Called after the checkbox state changes */
45
+ onCheck?: (
46
+ value: ValueType,
47
+ item: any,
48
+ checked: boolean,
49
+ event: React.SyntheticEvent<HTMLElement>
50
+ ) => void;
51
+
44
52
  /** Called when clean */
45
53
  onClean?: (event: React.SyntheticEvent<HTMLElement>) => void;
46
54
 
@@ -37,9 +37,10 @@ function (_React$Component) {
37
37
  _this.handleCheck = function (item, event, checked) {
38
38
  var _this$props = _this.props,
39
39
  valueKey = _this$props.valueKey,
40
- onChange = _this$props.onChange,
41
40
  cascade = _this$props.cascade,
42
- uncheckableItemValues = _this$props.uncheckableItemValues;
41
+ uncheckableItemValues = _this$props.uncheckableItemValues,
42
+ onChange = _this$props.onChange,
43
+ onCheck = _this$props.onCheck;
43
44
  var itemValue = item[valueKey];
44
45
  var value = [];
45
46
 
@@ -64,6 +65,7 @@ function (_React$Component) {
64
65
  }
65
66
 
66
67
  onChange === null || onChange === void 0 ? void 0 : onChange(value, event);
68
+ onCheck === null || onCheck === void 0 ? void 0 : onCheck(value, item, checked, event);
67
69
  };
68
70
 
69
71
  _this.handleChangeForSearchItem = function (value, checked, event) {
@@ -543,7 +545,8 @@ MultiCascader.propTypes = _extends({}, listPickerPropTypes, {
543
545
  renderMenuItem: PropTypes.func,
544
546
  renderMenu: PropTypes.func,
545
547
  onSearch: PropTypes.func,
546
- onSelect: PropTypes.func
548
+ onSelect: PropTypes.func,
549
+ onCheck: PropTypes.func
547
550
  });
548
551
  MultiCascader.defaultProps = _extends({}, listPickerDefaultProps, {
549
552
  searchable: true,
package/es/Nav/Nav.js CHANGED
@@ -7,7 +7,7 @@ import classNames from 'classnames';
7
7
  import { setStatic } from 'recompose';
8
8
  import shallowEqual from '../utils/shallowEqual';
9
9
  import NavItem from './NavItem';
10
- import { prefix, getUnhandledProps, defaultProps, ReactChildren } from '../utils';
10
+ import { prefix, getUnhandledProps, defaultProps, ReactChildren, createChainedFunction } from '../utils';
11
11
  import { getClassNamePrefix } from '../utils/prefix';
12
12
  import { NavbarContext } from '../Navbar/Navbar';
13
13
  import { SidenavContext } from '../Sidenav/Sidenav';
@@ -54,20 +54,21 @@ function (_React$Component) {
54
54
  var _item$props = item.props,
55
55
  eventKey = _item$props.eventKey,
56
56
  active = _item$props.active,
57
- rest = _objectWithoutPropertiesLoose(_item$props, ["eventKey", "active"]);
57
+ onSelectItem = _item$props.onSelect,
58
+ rest = _objectWithoutPropertiesLoose(_item$props, ["eventKey", "active", "onSelect"]);
58
59
 
59
60
  var displayName = item === null || item === void 0 ? void 0 : (_item$type = item.type) === null || _item$type === void 0 ? void 0 : _item$type.displayName;
60
61
  var hasTooltip = sidenav && !expanded;
61
62
 
62
63
  if (~(displayName === null || displayName === void 0 ? void 0 : displayName.indexOf('(NavItem)'))) {
63
64
  return _extends({}, rest, {
64
- onSelect: onSelect,
65
+ onSelect: createChainedFunction(onSelect, onSelectItem),
65
66
  hasTooltip: hasTooltip,
66
67
  active: typeof activeKey === 'undefined' ? active : shallowEqual(activeKey, eventKey)
67
68
  });
68
69
  } else if (~(displayName === null || displayName === void 0 ? void 0 : displayName.indexOf('(Dropdown)'))) {
69
70
  return _extends({}, rest, {
70
- onSelect: onSelect,
71
+ onSelect: createChainedFunction(onSelect, onSelectItem),
71
72
  activeKey: activeKey,
72
73
  showHeader: hasTooltip,
73
74
  componentClass: 'li'
@@ -166,11 +166,12 @@
166
166
  border-style: solid;
167
167
  border-width: 0;
168
168
  border-color: @table-border-color;
169
- display: block;
170
169
  overflow: hidden;
171
170
  position: absolute;
172
171
  white-space: normal;
173
172
  background: @table-body-background;
173
+ display: table;
174
+ table-layout: fixed;
174
175
 
175
176
  &.first {
176
177
  border-left-width: 0;
@@ -48,6 +48,8 @@ function (_React$Component) {
48
48
 
49
49
  (_this$props$onRemove = (_this$props = _this.props).onRemove) === null || _this$props$onRemove === void 0 ? void 0 : _this$props$onRemove.call(_this$props, file);
50
50
  (_this$props$onChange = (_this$props2 = _this.props).onChange) === null || _this$props$onChange === void 0 ? void 0 : _this$props$onChange.call(_this$props2, nextFileList);
51
+
52
+ _this.cleanInputValue();
51
53
  };
52
54
 
53
55
  _this.handleUploadTriggerChange = function (event) {
@@ -436,18 +436,6 @@ function (_React$Component) {
436
436
  (_this$triggerRef$curr5 = _this.triggerRef.current) === null || _this$triggerRef$curr5 === void 0 ? void 0 : _this$triggerRef$curr5.show();
437
437
  };
438
438
 
439
- _this.handleInputBlur = function () {
440
- if (!_this.props.multi) {
441
- var _this$triggerRef$curr6;
442
-
443
- _this.setState({
444
- open: false
445
- });
446
-
447
- (_this$triggerRef$curr6 = _this.triggerRef.current) === null || _this$triggerRef$curr6 === void 0 ? void 0 : _this$triggerRef$curr6.hide();
448
- }
449
- };
450
-
451
439
  _this.removeLastItem = function (event) {
452
440
  var tagName = (0, _get2.default)(event, 'target.tagName');
453
441
 
@@ -827,7 +815,7 @@ function (_React$Component) {
827
815
  tabIndex: tabIndex,
828
816
  onChange: this.handleSearch,
829
817
  value: this.state.open ? this.state.searchKeyword : '',
830
- onBlur: (0, _utils.createChainedFunction)(this.handleInputBlur, onBlur),
818
+ onBlur: onBlur,
831
819
  onFocus: (0, _utils.createChainedFunction)(this.handleInputFocus, onFocus)
832
820
  }));
833
821
  };
@@ -168,7 +168,7 @@ function (_React$Component) {
168
168
  className: classes,
169
169
  componentClass: "li",
170
170
  indeterminate: cascade && !active && this.utils.isSomeChildChecked(node, value),
171
- onSelectItem: this.handleSelect.bind(this, layer, node),
171
+ onSelectItem: this.handleSelect.bind(this, layer),
172
172
  onCheck: onCheck,
173
173
  checkable: !uncheckable
174
174
  }, renderMenuItem ? renderMenuItem(label, node) : label, children ? React.createElement("span", {
@@ -41,6 +41,14 @@ export interface MultiCascaderProps<ValueType = any> extends FormControlPickerPr
41
41
  event: React.SyntheticEvent<HTMLElement>
42
42
  ) => void;
43
43
 
44
+ /** Called after the checkbox state changes */
45
+ onCheck?: (
46
+ value: ValueType,
47
+ item: any,
48
+ checked: boolean,
49
+ event: React.SyntheticEvent<HTMLElement>
50
+ ) => void;
51
+
44
52
  /** Called when clean */
45
53
  onClean?: (event: React.SyntheticEvent<HTMLElement>) => void;
46
54
 
@@ -66,9 +66,10 @@ function (_React$Component) {
66
66
  _this.handleCheck = function (item, event, checked) {
67
67
  var _this$props = _this.props,
68
68
  valueKey = _this$props.valueKey,
69
- onChange = _this$props.onChange,
70
69
  cascade = _this$props.cascade,
71
- uncheckableItemValues = _this$props.uncheckableItemValues;
70
+ uncheckableItemValues = _this$props.uncheckableItemValues,
71
+ onChange = _this$props.onChange,
72
+ onCheck = _this$props.onCheck;
72
73
  var itemValue = item[valueKey];
73
74
  var value = [];
74
75
 
@@ -93,6 +94,7 @@ function (_React$Component) {
93
94
  }
94
95
 
95
96
  onChange === null || onChange === void 0 ? void 0 : onChange(value, event);
97
+ onCheck === null || onCheck === void 0 ? void 0 : onCheck(value, item, checked, event);
96
98
  };
97
99
 
98
100
  _this.handleChangeForSearchItem = function (value, checked, event) {
@@ -569,7 +571,8 @@ MultiCascader.propTypes = (0, _extends3.default)({}, _propTypes2.listPickerPropT
569
571
  renderMenuItem: _propTypes.default.func,
570
572
  renderMenu: _propTypes.default.func,
571
573
  onSearch: _propTypes.default.func,
572
- onSelect: _propTypes.default.func
574
+ onSelect: _propTypes.default.func,
575
+ onCheck: _propTypes.default.func
573
576
  });
574
577
  MultiCascader.defaultProps = (0, _extends3.default)({}, _propTypes2.listPickerDefaultProps, {
575
578
  searchable: true,
package/lib/Nav/Nav.js CHANGED
@@ -76,19 +76,20 @@ function (_React$Component) {
76
76
  var _item$props = item.props,
77
77
  eventKey = _item$props.eventKey,
78
78
  active = _item$props.active,
79
- rest = (0, _objectWithoutPropertiesLoose2.default)(_item$props, ["eventKey", "active"]);
79
+ onSelectItem = _item$props.onSelect,
80
+ rest = (0, _objectWithoutPropertiesLoose2.default)(_item$props, ["eventKey", "active", "onSelect"]);
80
81
  var displayName = item === null || item === void 0 ? void 0 : (_item$type = item.type) === null || _item$type === void 0 ? void 0 : _item$type.displayName;
81
82
  var hasTooltip = sidenav && !expanded;
82
83
 
83
84
  if (~(displayName === null || displayName === void 0 ? void 0 : displayName.indexOf('(NavItem)'))) {
84
85
  return (0, _extends2.default)({}, rest, {
85
- onSelect: onSelect,
86
+ onSelect: (0, _utils.createChainedFunction)(onSelect, onSelectItem),
86
87
  hasTooltip: hasTooltip,
87
88
  active: typeof activeKey === 'undefined' ? active : (0, _shallowEqual.default)(activeKey, eventKey)
88
89
  });
89
90
  } else if (~(displayName === null || displayName === void 0 ? void 0 : displayName.indexOf('(Dropdown)'))) {
90
91
  return (0, _extends2.default)({}, rest, {
91
- onSelect: onSelect,
92
+ onSelect: (0, _utils.createChainedFunction)(onSelect, onSelectItem),
92
93
  activeKey: activeKey,
93
94
  showHeader: hasTooltip,
94
95
  componentClass: 'li'
@@ -166,11 +166,12 @@
166
166
  border-style: solid;
167
167
  border-width: 0;
168
168
  border-color: @table-border-color;
169
- display: block;
170
169
  overflow: hidden;
171
170
  position: absolute;
172
171
  white-space: normal;
173
172
  background: @table-body-background;
173
+ display: table;
174
+ table-layout: fixed;
174
175
 
175
176
  &.first {
176
177
  border-left-width: 0;
@@ -70,6 +70,8 @@ function (_React$Component) {
70
70
 
71
71
  (_this$props$onRemove = (_this$props = _this.props).onRemove) === null || _this$props$onRemove === void 0 ? void 0 : _this$props$onRemove.call(_this$props, file);
72
72
  (_this$props$onChange = (_this$props2 = _this.props).onChange) === null || _this$props$onChange === void 0 ? void 0 : _this$props$onChange.call(_this$props2, nextFileList);
73
+
74
+ _this.cleanInputValue();
73
75
  };
74
76
 
75
77
  _this.handleUploadTriggerChange = function (event) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rsuite",
3
- "version": "4.9.1",
3
+ "version": "4.10.0",
4
4
  "description": "A suite of react components",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -63,7 +63,7 @@
63
63
  "react-lifecycles-compat": "^3.0.4",
64
64
  "react-virtualized": "^9.21.0",
65
65
  "recompose": "^0.30.0",
66
- "rsuite-table": "^3.14.3",
66
+ "rsuite-table": "^3.14.6",
67
67
  "schema-typed": "^1.5.1"
68
68
  },
69
69
  "peerDependencies": {
@@ -502,13 +502,6 @@ class InputPicker extends React.Component<InputPickerProps, InputPickerState> {
502
502
  this.triggerRef.current?.show();
503
503
  };
504
504
 
505
- handleInputBlur = () => {
506
- if (!this.props.multi) {
507
- this.setState({ open: false });
508
- this.triggerRef.current?.hide();
509
- }
510
- };
511
-
512
505
  removeLastItem = (event: React.KeyboardEvent<HTMLInputElement>) => {
513
506
  const tagName = _.get(event, 'target.tagName');
514
507
  if (tagName !== 'INPUT') {
@@ -686,7 +679,7 @@ class InputPicker extends React.Component<InputPickerProps, InputPickerState> {
686
679
  tabIndex={tabIndex}
687
680
  onChange={this.handleSearch}
688
681
  value={this.state.open ? this.state.searchKeyword : ''}
689
- onBlur={createChainedFunction(this.handleInputBlur, onBlur)}
682
+ onBlur={onBlur}
690
683
  onFocus={createChainedFunction(this.handleInputFocus, onFocus)}
691
684
  />
692
685
  );
@@ -166,7 +166,7 @@ class DropdownMenu extends React.Component<DropdownMenuProps> {
166
166
  className={classes}
167
167
  componentClass="li"
168
168
  indeterminate={cascade && !active && this.utils.isSomeChildChecked(node, value)}
169
- onSelectItem={this.handleSelect.bind(this, layer, node)}
169
+ onSelectItem={this.handleSelect.bind(this, layer)}
170
170
  onCheck={onCheck}
171
171
  checkable={!uncheckable}
172
172
  >
@@ -41,6 +41,14 @@ export interface MultiCascaderProps<ValueType = any> extends FormControlPickerPr
41
41
  event: React.SyntheticEvent<HTMLElement>
42
42
  ) => void;
43
43
 
44
+ /** Called after the checkbox state changes */
45
+ onCheck?: (
46
+ value: ValueType,
47
+ item: any,
48
+ checked: boolean,
49
+ event: React.SyntheticEvent<HTMLElement>
50
+ ) => void;
51
+
44
52
  /** Called when clean */
45
53
  onClean?: (event: React.SyntheticEvent<HTMLElement>) => void;
46
54
 
@@ -57,7 +57,8 @@ class MultiCascader extends React.Component<MultiCascaderProps, MultiCascaderSta
57
57
  renderMenuItem: PropTypes.func,
58
58
  renderMenu: PropTypes.func,
59
59
  onSearch: PropTypes.func,
60
- onSelect: PropTypes.func
60
+ onSelect: PropTypes.func,
61
+ onCheck: PropTypes.func
61
62
  };
62
63
 
63
64
  static defaultProps = {
@@ -187,7 +188,7 @@ class MultiCascader extends React.Component<MultiCascaderProps, MultiCascaderSta
187
188
  }
188
189
 
189
190
  handleCheck = (item: any, event: React.SyntheticEvent<any>, checked: boolean) => {
190
- const { valueKey, onChange, cascade, uncheckableItemValues } = this.props;
191
+ const { valueKey, cascade, uncheckableItemValues, onChange, onCheck } = this.props;
191
192
  const itemValue = item[valueKey];
192
193
  let value = [];
193
194
 
@@ -208,6 +209,7 @@ class MultiCascader extends React.Component<MultiCascaderProps, MultiCascaderSta
208
209
  }
209
210
 
210
211
  onChange?.(value, event);
212
+ onCheck?.(value, item, checked, event);
211
213
  };
212
214
 
213
215
  handleChangeForSearchItem = (value: any, checked: boolean, event: React.SyntheticEvent<any>) => {
@@ -112,6 +112,23 @@ describe('MultiCascader - DropdownMenu', () => {
112
112
  }, 1);
113
113
  });
114
114
 
115
+ it('Should call onSelect callback with 4 params', done => {
116
+ const doneOp = (node, activePaths, createConcat, event) => {
117
+ if (
118
+ typeof node === 'object' &&
119
+ Array.isArray(activePaths) &&
120
+ typeof createConcat === 'function' &&
121
+ event.target
122
+ ) {
123
+ done();
124
+ }
125
+ };
126
+
127
+ const instance = getInstance(<Dropdown defaultOpen data={items} onSelect={doneOp} />);
128
+ const menuContainer = getDOMNode(instance.menuContainerRef.current);
129
+ ReactTestUtils.Simulate.click(menuContainer.querySelectorAll('.rs-checkbox')[1]);
130
+ });
131
+
115
132
  it('Should not call onSelect callback on disabled item', () => {
116
133
  const onSelectSpy = sinon.spy();
117
134
  const instance = getInstance(
@@ -7,7 +7,6 @@ import Button from '../../Button';
7
7
 
8
8
  const namespace = `${globalKey}-picker`;
9
9
  const toggleClassName = `.${namespace}-toggle-placeholder`;
10
- const activeClassName = '.rs-dropdown-menu-item-active';
11
10
 
12
11
  const items = [
13
12
  {
@@ -209,6 +208,20 @@ describe('MultiCascader', () => {
209
208
  ReactTestUtils.Simulate.click(menu.querySelector('.rs-checkbox'));
210
209
  });
211
210
 
211
+ it('Should call onCheck callback ', done => {
212
+ let checkbox = null;
213
+ const doneOp = (value, item, checked, event) => {
214
+ if (value[0] === 'abc' && item.value === 'abc' && checked && event.target === checkbox) {
215
+ done();
216
+ }
217
+ };
218
+
219
+ const instance = getInstance(<Dropdown data={items} defaultOpen onCheck={doneOp} />);
220
+ const menu = findDOMNode(instance.menuContainerRef.current);
221
+ checkbox = menu.querySelector('.rs-checkbox-wrapper');
222
+ ReactTestUtils.Simulate.click(checkbox);
223
+ });
224
+
212
225
  it('Should call onChange callback ', done => {
213
226
  const doneOp = value => {
214
227
  if (value[0] === 'abc') {
package/src/Nav/Nav.tsx CHANGED
@@ -5,7 +5,13 @@ import { setStatic } from 'recompose';
5
5
  import shallowEqual from '../utils/shallowEqual';
6
6
 
7
7
  import NavItem from './NavItem';
8
- import { prefix, getUnhandledProps, defaultProps, ReactChildren } from '../utils';
8
+ import {
9
+ prefix,
10
+ getUnhandledProps,
11
+ defaultProps,
12
+ ReactChildren,
13
+ createChainedFunction
14
+ } from '../utils';
9
15
  import { getClassNamePrefix } from '../utils/prefix';
10
16
  import { NavbarContext } from '../Navbar/Navbar';
11
17
  import { SidenavContext } from '../Sidenav/Sidenav';
@@ -56,21 +62,21 @@ class Nav extends React.Component<NavProps> {
56
62
  const hasWaterline = appearance !== 'default';
57
63
 
58
64
  const items = ReactChildren.mapCloneElement(children, item => {
59
- const { eventKey, active, ...rest } = item.props;
65
+ const { eventKey, active, onSelect: onSelectItem, ...rest } = item.props;
60
66
  const displayName = item?.type?.displayName;
61
67
  const hasTooltip = sidenav && !expanded;
62
68
 
63
69
  if (~displayName?.indexOf('(NavItem)')) {
64
70
  return {
65
71
  ...rest,
66
- onSelect,
72
+ onSelect: createChainedFunction(onSelect, onSelectItem),
67
73
  hasTooltip,
68
74
  active: typeof activeKey === 'undefined' ? active : shallowEqual(activeKey, eventKey)
69
75
  };
70
76
  } else if (~displayName?.indexOf('(Dropdown)')) {
71
77
  return {
72
78
  ...rest,
73
- onSelect,
79
+ onSelect: createChainedFunction(onSelect, onSelectItem),
74
80
  activeKey,
75
81
  showHeader: hasTooltip,
76
82
  componentClass: 'li'
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import ReactTestUtils from 'react-dom/test-utils';
2
3
  import { innerText, getDOMNode } from '@test/testUtils';
3
4
 
4
5
  import Nav from '../Nav';
@@ -68,4 +69,38 @@ describe('Nav', () => {
68
69
  const instance = getDOMNode(<Nav classPrefix="custom-prefix" />);
69
70
  assert.ok(instance.className.match(/\bcustom-prefix\b/));
70
71
  });
72
+
73
+ it('Should call onSelect callback', done => {
74
+ const doneOp = eventKey => {
75
+ if (eventKey === 2) {
76
+ done();
77
+ }
78
+ };
79
+ const instance = getDOMNode(
80
+ <Nav onSelect={doneOp}>
81
+ <Nav.Item eventKey={1}>1</Nav.Item>
82
+ <Nav.Item eventKey={2}>2</Nav.Item>
83
+ </Nav>
84
+ );
85
+
86
+ ReactTestUtils.Simulate.click(instance.querySelectorAll('.rs-nav-item a')[1]);
87
+ });
88
+
89
+ it('Should call onSelect callback on Nav.Item', done => {
90
+ const doneOp = eventKey => {
91
+ if (eventKey === 2) {
92
+ done();
93
+ }
94
+ };
95
+ const instance = getDOMNode(
96
+ <Nav>
97
+ <Nav.Item eventKey={1}>1</Nav.Item>
98
+ <Nav.Item eventKey={2} onSelect={doneOp}>
99
+ 2
100
+ </Nav.Item>
101
+ </Nav>
102
+ );
103
+
104
+ ReactTestUtils.Simulate.click(instance.querySelectorAll('.rs-nav-item a')[1]);
105
+ });
71
106
  });
@@ -166,11 +166,12 @@
166
166
  border-style: solid;
167
167
  border-width: 0;
168
168
  border-color: @table-border-color;
169
- display: block;
170
169
  overflow: hidden;
171
170
  position: absolute;
172
171
  white-space: normal;
173
172
  background: @table-body-background;
173
+ display: table;
174
+ table-layout: fixed;
174
175
 
175
176
  &.first {
176
177
  border-left-width: 0;
@@ -132,6 +132,7 @@ class Uploader extends React.Component<UploaderProps, UploaderState> {
132
132
 
133
133
  this.props.onRemove?.(file);
134
134
  this.props.onChange?.(nextFileList);
135
+ this.cleanInputValue();
135
136
  };
136
137
 
137
138
  handleUploadTriggerChange = (event: React.ChangeEvent<HTMLInputElement>) => {
@@ -172,12 +172,14 @@ describe('Whisper', () => {
172
172
  const doneOp = () => {
173
173
  done();
174
174
  };
175
- const triggerRef = React.createRef();
176
175
  const btnRef = React.createRef();
176
+ const closeBtnRef = React.createRef();
177
177
  const Overlay = React.forwardRef(({ style, onClose, ...rest }, ref) => {
178
178
  return (
179
179
  <div {...rest} style={style} ref={ref}>
180
- <button onClick={onClose}>close</button>
180
+ <button ref={closeBtnRef} onClick={onClose}>
181
+ close
182
+ </button>
181
183
  </div>
182
184
  );
183
185
  });
@@ -186,7 +188,16 @@ describe('Whisper', () => {
186
188
 
187
189
  ReactTestUtils.act(() => {
188
190
  ReactDOM.render(
189
- <Whisper ref={triggerRef} onExited={doneOp} trigger="click" speaker={<Tooltip />}>
191
+ <Whisper
192
+ onExited={doneOp}
193
+ trigger="click"
194
+ speaker={(props, ref) => {
195
+ const { className, left, top, onClose } = props;
196
+ return (
197
+ <Overlay style={{ left, top }} onClose={onClose} className={className} ref={ref} />
198
+ );
199
+ }}
200
+ >
190
201
  <button ref={btnRef}>button</button>
191
202
  </Whisper>,
192
203
  createTestContainer()
@@ -197,7 +208,7 @@ describe('Whisper', () => {
197
208
  });
198
209
 
199
210
  ReactTestUtils.act(() => {
200
- ReactTestUtils.Simulate.click(triggerRef.current.getOverlayTarget());
211
+ ReactTestUtils.Simulate.click(closeBtnRef.current);
201
212
  });
202
213
  });
203
214
  });