baseui 10.11.0 → 10.12.1

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.
@@ -10,7 +10,7 @@ import * as React from 'react';
10
10
  import { KIND, SIZE, SHAPE } from './constants.js';
11
11
  import type { OverrideT } from '../helpers/overrides.js';
12
12
 
13
- export type ReactRefT<T> = {| current: null | T |};
13
+ export type ReactRefT<T> = { current: null | T } | {| current: null | T |};
14
14
 
15
15
  export type OverridesT = {
16
16
  Root?: OverrideT,
@@ -11,7 +11,7 @@ import { STYLE_TYPE } from './constants.js';
11
11
 
12
12
  export type LabelPlacementT = 'top' | 'right' | 'bottom' | 'left';
13
13
  export type StyleTypeT = $Keys<typeof STYLE_TYPE>;
14
- export type ReactRefT<T> = {| current: null | T |};
14
+ export type ReactRefT<T> = { current: null | T } | {| current: null | T |};
15
15
 
16
16
  export type OverridesT = {
17
17
  Checkmark?: OverrideT,
@@ -11,7 +11,7 @@ import * as React from 'react';
11
11
  import type { OverrideT } from '../helpers/overrides.js';
12
12
  import { SIZE } from '../input/index.js';
13
13
 
14
- export type ReactRefT<T> = {| current: null | T |};
14
+ export type ReactRefT<T> = { current: null | T } | {| current: null | T |};
15
15
 
16
16
  export type PropsT<OptionT = mixed> = {|
17
17
  // Controls if the input value will be updated while keyboard navigating. Defaults to true.
package/es/radio/radio.js CHANGED
@@ -61,7 +61,7 @@ class Radio extends React.Component {
61
61
  }
62
62
 
63
63
  componentDidMount() {
64
- if (this.props.autoFocus && this.props.inputRef.current) {
64
+ if (this.props.autoFocus && this.props.inputRef?.current) {
65
65
  this.props.inputRef.current.focus();
66
66
  }
67
67
 
@@ -437,12 +437,8 @@ class Select extends React.Component {
437
437
  _defineProperty(this, "handleInputRef", input => {
438
438
  this.input = input;
439
439
 
440
- if (this.props.controlRef) {
441
- if (typeof this.props.controlRef === 'function') {
442
- this.props.controlRef(input);
443
- } else {
444
- this.props.controlRef.current = input;
445
- }
440
+ if (this.props.controlRef && typeof this.props.controlRef === 'function') {
441
+ this.props.controlRef(input);
446
442
  }
447
443
  });
448
444
 
@@ -561,13 +557,19 @@ class Select extends React.Component {
561
557
  }
562
558
 
563
559
  this.isItMounted = true;
560
+ const {
561
+ controlRef
562
+ } = this.props;
564
563
 
565
- if (this.props.methodsRef) {
566
- const {
567
- methodsRef
568
- } = this.props;
569
- methodsRef.current = {
570
- setDropdownOpen: this.handleDropdownOpen.bind(this)
564
+ if (controlRef && typeof controlRef !== 'function') {
565
+ controlRef.current = {
566
+ setDropdownOpen: this.handleDropdownOpen.bind(this),
567
+ setInputValue: this.handleSetInputValue.bind(this),
568
+ setInputFocus: this.handleSetInputFocus.bind(this),
569
+ setInputBlur: this.handleSetInputBlur.bind(this),
570
+ // `focus` & `blur` below are for backwards compatibility and may be removed. Use setInputFocus and setInputBlur instead.
571
+ focus: this.handleSetInputFocus.bind(this),
572
+ blur: this.handleSetInputBlur.bind(this)
571
573
  };
572
574
  }
573
575
  }
@@ -608,6 +610,20 @@ class Select extends React.Component {
608
610
  this.setState({
609
611
  isOpen: nextOpenState
610
612
  });
613
+ }
614
+
615
+ handleSetInputValue(newInputValue) {
616
+ this.setState({
617
+ inputValue: newInputValue
618
+ });
619
+ }
620
+
621
+ handleSetInputFocus() {
622
+ this.input.focus();
623
+ }
624
+
625
+ handleSetInputBlur() {
626
+ this.input.blur();
611
627
  } // Handle touch outside on mobile to dismiss menu, ensures that the
612
628
  // touch target is not within the anchor DOM node.
613
629
 
@@ -117,7 +117,9 @@ var Radio = /*#__PURE__*/function (_React$Component) {
117
117
  _createClass(Radio, [{
118
118
  key: "componentDidMount",
119
119
  value: function componentDidMount() {
120
- if (this.props.autoFocus && this.props.inputRef.current) {
120
+ var _this$props$inputRef;
121
+
122
+ if (this.props.autoFocus && (_this$props$inputRef = this.props.inputRef) !== null && _this$props$inputRef !== void 0 && _this$props$inputRef.current) {
121
123
  this.props.inputRef.current.focus();
122
124
  }
123
125
 
@@ -512,12 +512,8 @@ var Select = /*#__PURE__*/function (_React$Component) {
512
512
  _defineProperty(_assertThisInitialized(_this), "handleInputRef", function (input) {
513
513
  _this.input = input;
514
514
 
515
- if (_this.props.controlRef) {
516
- if (typeof _this.props.controlRef === 'function') {
517
- _this.props.controlRef(input);
518
- } else {
519
- _this.props.controlRef.current = input;
520
- }
515
+ if (_this.props.controlRef && typeof _this.props.controlRef === 'function') {
516
+ _this.props.controlRef(input);
521
517
  }
522
518
  });
523
519
 
@@ -656,11 +652,17 @@ var Select = /*#__PURE__*/function (_React$Component) {
656
652
  }
657
653
 
658
654
  this.isItMounted = true;
659
-
660
- if (this.props.methodsRef) {
661
- var methodsRef = this.props.methodsRef;
662
- methodsRef.current = {
663
- setDropdownOpen: this.handleDropdownOpen.bind(this)
655
+ var controlRef = this.props.controlRef;
656
+
657
+ if (controlRef && typeof controlRef !== 'function') {
658
+ controlRef.current = {
659
+ setDropdownOpen: this.handleDropdownOpen.bind(this),
660
+ setInputValue: this.handleSetInputValue.bind(this),
661
+ setInputFocus: this.handleSetInputFocus.bind(this),
662
+ setInputBlur: this.handleSetInputBlur.bind(this),
663
+ // `focus` & `blur` below are for backwards compatibility and may be removed. Use setInputFocus and setInputBlur instead.
664
+ focus: this.handleSetInputFocus.bind(this),
665
+ blur: this.handleSetInputBlur.bind(this)
664
666
  };
665
667
  }
666
668
  }
@@ -705,6 +707,23 @@ var Select = /*#__PURE__*/function (_React$Component) {
705
707
  this.setState({
706
708
  isOpen: nextOpenState
707
709
  });
710
+ }
711
+ }, {
712
+ key: "handleSetInputValue",
713
+ value: function handleSetInputValue(newInputValue) {
714
+ this.setState({
715
+ inputValue: newInputValue
716
+ });
717
+ }
718
+ }, {
719
+ key: "handleSetInputFocus",
720
+ value: function handleSetInputFocus() {
721
+ this.input.focus();
722
+ }
723
+ }, {
724
+ key: "handleSetInputBlur",
725
+ value: function handleSetInputBlur() {
726
+ this.input.blur();
708
727
  } // Handle touch outside on mobile to dismiss menu, ensures that the
709
728
  // touch target is not within the anchor DOM node.
710
729
 
@@ -27,7 +27,10 @@ import { isFocusVisible, forkFocus, forkBlur } from '../utils/focusVisible.js';
27
27
 
28
28
  const NullComponent = () => null;
29
29
 
30
- class BaseInput<T: EventTarget> extends React.Component<BaseInputPropsT<T>, InternalStateT> {
30
+ class BaseInput<T: HTMLInputElement | HTMLTextAreaElement> extends React.Component<
31
+ BaseInputPropsT<T>,
32
+ InternalStateT
33
+ > {
31
34
  static defaultProps = {
32
35
  'aria-activedescendant': null,
33
36
  'aria-autocomplete': null,
@@ -63,8 +66,7 @@ class BaseInput<T: EventTarget> extends React.Component<BaseInputPropsT<T>, Inte
63
66
  type: 'text',
64
67
  };
65
68
 
66
- // flowlint-next-line unclear-type:off
67
- inputRef = this.props.inputRef || React.createRef<any>();
69
+ inputRef = this.props.inputRef || React.createRef<T>();
68
70
 
69
71
  state = {
70
72
  isFocused: this.props.autoFocus || false,
@@ -13,7 +13,7 @@ import Input from './input.js';
13
13
  import { Input as StyledInput } from './styled-components.js';
14
14
  import type { MaskedInputPropsT } from './types.js';
15
15
 
16
- const MaskOverride = React.forwardRef<MaskedInputPropsT, HTMLElement>(
16
+ const MaskOverride = React.forwardRef<MaskedInputPropsT, HTMLInputElement>(
17
17
  (
18
18
  {
19
19
  // do nothing with these - we just don't want to pass it to the InputMask, as
@@ -12,7 +12,7 @@ import { STATE_CHANGE_TYPE, ADJOINED, SIZE, ENHANCER_POSITION } from './constant
12
12
  export type AdjoinedT = $Keys<typeof ADJOINED>;
13
13
  export type SizeT = $Keys<typeof SIZE>;
14
14
  export type StateTypeT = $Keys<typeof STATE_CHANGE_TYPE>;
15
- export type ReactRefT<T> = {| current: null | T |};
15
+ export type ReactRefT<T> = {| current: null | T |} | { current: null | T };
16
16
 
17
17
  export type InternalStateT = {
18
18
  /** Renders UI in 'focus' state */
@@ -108,7 +108,7 @@ export type BaseInputPropsT<T> = {|
108
108
  /** A hint as to the type of data that might be entered by the user while editing the element or its contents. */
109
109
  inputMode?: string,
110
110
  /** A ref to access an input element. */
111
- inputRef?: ReactRefT<HTMLElement>,
111
+ inputRef?: ReactRefT<T>,
112
112
  name: string,
113
113
  onBlur: (e: SyntheticFocusEvent<T>) => mixed,
114
114
  onChange?: (e: SyntheticInputEvent<T>) => mixed,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baseui",
3
- "version": "10.11.0",
3
+ "version": "10.12.1",
4
4
  "description": "A React Component library implementing the Base design language",
5
5
  "keywords": [
6
6
  "react",
@@ -81,13 +81,13 @@
81
81
  "@commitlint/config-conventional": "^8.0.0",
82
82
  "@date-io/luxon": "^2.7.0",
83
83
  "@date-io/moment": "^2.7.0",
84
- "@ladle/react": "^0.8.2",
84
+ "@ladle/react": "^0.10.2",
85
85
  "@mdx-js/tag": "^0.20.0",
86
86
  "@octokit/rest": "^16.33.1",
87
87
  "@svgr/cli": "^4.3.2",
88
- "@testing-library/jest-dom": "^5.11.5",
89
- "@testing-library/react": "^11.1.0",
90
- "@testing-library/user-event": "^12.1.10",
88
+ "@testing-library/jest-dom": "^5.16.3",
89
+ "@testing-library/react": "^12.1.4",
90
+ "@testing-library/user-event": "^13.5.0",
91
91
  "@types/babel__code-frame": "^7.0.1",
92
92
  "@types/babel__core": "^7.1.3",
93
93
  "@types/babel__generator": "^7.0.2",
@@ -168,10 +168,10 @@
168
168
  "puppeteer": "^9.1.1",
169
169
  "query-string": "^6.14.0",
170
170
  "raw-loader": "^3.1.0",
171
- "react": "^16.9.0",
171
+ "react": "^17.0.2",
172
172
  "react-codesandboxer": "^3.1.5",
173
173
  "react-compare-image": "^2.0.3",
174
- "react-dom": "^16.9.0",
174
+ "react-dom": "^17.0.2",
175
175
  "react-hook-form": "^7.9.0",
176
176
  "react-icons": "^3.8.0",
177
177
  "react-map-gl": "^5.3.19",
@@ -220,8 +220,8 @@
220
220
  "resize-observer-polyfill": "^1.5.1"
221
221
  },
222
222
  "peerDependencies": {
223
- "react": ">= 16.8.0 < 18",
224
- "react-dom": ">= 16.8.0 < 18",
223
+ "react": ">= 16.8.0 < 19",
224
+ "react-dom": ">= 16.8.0 < 19",
225
225
  "styletron-react": ">=5.2.2 < 7"
226
226
  },
227
227
  "resolutions": {
@@ -10,7 +10,7 @@ import { STATE_CHANGE_TYPE, SIZE, COUNTRIES } from './constants.js';
10
10
  import type { OverrideT } from '../helpers/overrides.js';
11
11
  import type { OnChangeParamsT } from '../select/types.js';
12
12
 
13
- export type ReactRefT<T> = { current: null | T };
13
+ export type ReactRefT<T> = { current: null | T } | {| current: null | T |};
14
14
  export type SizeT = $Keys<typeof SIZE>;
15
15
  export type CountryIsoT = $Keys<typeof COUNTRIES>;
16
16
  export type CountriesT = $ReadOnly<CountryT>;
@@ -16,7 +16,7 @@ export type { PopperDataObjectT, PopperOffsetT, PopperOptionsT } from '../layer/
16
16
  export type PopoverPlacementT = TetherPlacementT;
17
17
  export type TriggerTypeT = $Keys<typeof TRIGGER_TYPE>;
18
18
  export type AccessibilityTypeT = $Keys<typeof ACCESSIBILITY_TYPE>;
19
- export type ReactRefT<T> = {| current: null | T |};
19
+ export type ReactRefT<T> = { current: null | T } | {| current: null | T |};
20
20
 
21
21
  export type StateT = {
22
22
  isOpen: boolean,
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import {StyletronComponent} from 'styletron-react';
3
- import {Override} from '../overrides';
2
+ import { StyletronComponent } from 'styletron-react';
3
+ import { Override } from '../overrides';
4
4
 
5
5
  export interface SIZE {
6
6
  small: 'small';
@@ -27,7 +27,7 @@ export interface ProgressBarProps {
27
27
  steps?: number;
28
28
  successValue?: number;
29
29
  minValue?: number;
30
- mxaValue?: number;
30
+ maxValue?: number;
31
31
  value?: number;
32
32
  }
33
33
  export class ProgressBar extends React.Component<ProgressBarProps> {}
package/radio/radio.js CHANGED
@@ -124,7 +124,9 @@ var Radio = /*#__PURE__*/function (_React$Component) {
124
124
  _createClass(Radio, [{
125
125
  key: "componentDidMount",
126
126
  value: function componentDidMount() {
127
- if (this.props.autoFocus && this.props.inputRef.current) {
127
+ var _this$props$inputRef;
128
+
129
+ if (this.props.autoFocus && (_this$props$inputRef = this.props.inputRef) !== null && _this$props$inputRef !== void 0 && _this$props$inputRef.current) {
128
130
  this.props.inputRef.current.focus();
129
131
  }
130
132
 
@@ -56,7 +56,7 @@ class Radio extends React.Component<RadioPropsT, RadioStateT> {
56
56
  };
57
57
 
58
58
  componentDidMount() {
59
- if (this.props.autoFocus && this.props.inputRef.current) {
59
+ if (this.props.autoFocus && this.props.inputRef?.current) {
60
60
  this.props.inputRef.current.focus();
61
61
  }
62
62
  if (__DEV__ && this.props.isError) {
@@ -13,7 +13,7 @@ import { ALIGN } from './constants.js';
13
13
 
14
14
  export type LabelPlacementT = 'top' | 'right' | 'bottom' | 'left';
15
15
  export type AlignT = $Keys<typeof ALIGN>;
16
- export type ReactRefT<T> = {| current: null | T |};
16
+ export type ReactRefT<T> = { current: null | T } | {| current: null | T |};
17
17
 
18
18
  export type RadioOverridesT = {
19
19
  RadioMarkInner?: OverrideT,
@@ -114,7 +114,7 @@ export type RadioPropsT = {
114
114
  /** Disable the checkbox from being changed. */
115
115
  disabled?: boolean,
116
116
  /** Used to get a ref to the input element. Useful for programmatically focusing the input */
117
- inputRef: ReactRefT<HTMLInputElement>,
117
+ inputRef?: ReactRefT<HTMLInputElement>,
118
118
  /** Renders checkbox in errored state. */
119
119
  error?: boolean,
120
120
  /** You should use the error prop instead. */
package/select/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import * as React from 'react';
2
- import {StyletronComponent} from 'styletron-react';
3
- import {SIZE} from '../input';
4
- import {OnItemSelect} from '../menu';
5
- import {Override} from '../overrides';
6
- import {Locale} from '../locale';
2
+ import { StyletronComponent } from 'styletron-react';
3
+ import { SIZE } from '../input';
4
+ import { OnItemSelect } from '../menu';
5
+ import { Override } from '../overrides';
6
+ import { Locale } from '../locale';
7
7
 
8
- export {SIZE} from '../input';
8
+ export { SIZE } from '../input';
9
9
 
10
10
  export interface TYPE {
11
11
  select: 'select';
@@ -27,7 +27,7 @@ export interface Option {
27
27
  [others: string]: any;
28
28
  }
29
29
  export type Value = ReadonlyArray<Option>;
30
- export type OptgroupsT = {__ungrouped: Value; [key: string]: Value};
30
+ export type OptgroupsT = { __ungrouped: Value; [key: string]: Value };
31
31
  export type OptionsT = Value | OptgroupsT;
32
32
 
33
33
  export type ChangeAction = () => any;
@@ -44,9 +44,16 @@ export type filterOptions = (
44
44
  matchProp?: 'any' | 'label' | 'value';
45
45
  trimFilter?: boolean;
46
46
  valueKey?: string;
47
- },
47
+ }
48
48
  ) => Value;
49
49
 
50
+ export interface ImperativeMethods {
51
+ setInputFocus: () => void;
52
+ setInputBlur: () => void;
53
+ setDropdownOpen: (d: boolean) => void;
54
+ setInputValue: (s: string) => void;
55
+ }
56
+
50
57
  export interface SelectOverrides {
51
58
  Root?: Override<any>;
52
59
  ControlContainer?: Override<any>;
@@ -91,7 +98,7 @@ export interface SelectProps {
91
98
  options: Value,
92
99
  filterValue: string,
93
100
  excludeOptions?: Value,
94
- newProps?: {valueKey: string; labelKey: string},
101
+ newProps?: { valueKey: string; labelKey: string }
95
102
  ) => Value;
96
103
  filterOutSelected?: boolean;
97
104
  getOptionLabel?: (args: {
@@ -102,9 +109,9 @@ export interface SelectProps {
102
109
  $isHighlighted?: boolean;
103
110
  };
104
111
  }) => React.ReactNode;
105
- getValueLabel?: (args: {option: Option}) => React.ReactNode;
112
+ getValueLabel?: (args: { option: Option }) => React.ReactNode;
106
113
  id?: string;
107
- controlRef?: React.Ref<HTMLInputElement | HTMLDivElement>;
114
+ controlRef?: React.Ref<ImperativeMethods>;
108
115
  isLoading?: boolean;
109
116
  labelKey?: string;
110
117
  startOpen?: boolean;
@@ -164,22 +171,18 @@ export class Select extends React.Component<SelectProps, SelectState> {
164
171
  $disabled: boolean;
165
172
  $isHighlighted: boolean;
166
173
  };
167
- },
174
+ }
168
175
  ): React.ReactNode;
169
- getValueLabel({option}: {option: Option}): React.ReactNode;
176
+ getValueLabel({ option }: { option: Option }): React.ReactNode;
170
177
  getValueArray(value: Value): Option[];
171
178
  setValue(value: Value, option: Option, type: ChangeAction): void;
172
- selectValue({item}: {item: Option}): void;
179
+ selectValue({ item }: { item: Option }): void;
173
180
  addValue(item: Option): void;
174
181
  popValue(): void;
175
182
  removeValue(item: Option): void;
176
183
  clearValue(event: KeyboardEvent | MouseEvent | TouchEvent): void;
177
184
  renderLoading(): React.ReactNode;
178
- renderValue(
179
- valueArray: Value,
180
- isOpen: boolean,
181
- locale: Locale,
182
- ): React.ReactNode;
185
+ renderValue(valueArray: Value, isOpen: boolean, locale: Locale): React.ReactNode;
183
186
  renderInput(): React.ReactNode;
184
187
  renderClear(): React.ReactNode;
185
188
  renderArrow(): React.ReactNode;
@@ -219,10 +222,7 @@ export interface AutosizeInputProps {
219
222
  export interface AutosizeInputState {
220
223
  inputWidth: number;
221
224
  }
222
- export class AutosizeInput extends React.Component<
223
- AutosizeInputProps,
224
- AutosizeInputState
225
- > {
225
+ export class AutosizeInput extends React.Component<AutosizeInputProps, AutosizeInputState> {
226
226
  sizerRef(el?: HTMLElement): void;
227
227
  updateInputWidth(): void;
228
228
  }
@@ -276,18 +276,14 @@ export class SelectDropdown extends React.Component<DropdownProps> {
276
276
  $type: TYPE[keyof TYPE];
277
277
  $width: number;
278
278
  };
279
- getItemLabel(option: {[key: string]: any}): React.ReactNode;
279
+ getItemLabel(option: { [key: string]: any }): React.ReactNode;
280
280
  onMouseDown(e: Event): void;
281
281
  }
282
282
 
283
283
  export interface State {
284
284
  value: Value;
285
285
  }
286
- export type StateReducer = (
287
- stateType: string,
288
- nextState: State,
289
- currentState: State,
290
- ) => State;
286
+ export type StateReducer = (stateType: string, nextState: State, currentState: State) => State;
291
287
  export interface OnChangeParams {
292
288
  value: Value;
293
289
  option?: Option;
@@ -306,10 +302,7 @@ export interface StatefulContainerProps {
306
302
  stateReducer?: StateReducer;
307
303
  onChange?: (params: OnChangeParams) => any;
308
304
  }
309
- export class StatefulSelectContainer extends React.Component<
310
- StatefulContainerProps,
311
- State
312
- > {
305
+ export class StatefulSelectContainer extends React.Component<StatefulContainerProps, State> {
313
306
  onChange(params: OnChangeParams): void;
314
307
  internalSetState(params: OnChangeParams): void;
315
308
  }
@@ -532,12 +532,8 @@ var Select = /*#__PURE__*/function (_React$Component) {
532
532
  _defineProperty(_assertThisInitialized(_this), "handleInputRef", function (input) {
533
533
  _this.input = input;
534
534
 
535
- if (_this.props.controlRef) {
536
- if (typeof _this.props.controlRef === 'function') {
537
- _this.props.controlRef(input);
538
- } else {
539
- _this.props.controlRef.current = input;
540
- }
535
+ if (_this.props.controlRef && typeof _this.props.controlRef === 'function') {
536
+ _this.props.controlRef(input);
541
537
  }
542
538
  });
543
539
 
@@ -676,11 +672,17 @@ var Select = /*#__PURE__*/function (_React$Component) {
676
672
  }
677
673
 
678
674
  this.isItMounted = true;
679
-
680
- if (this.props.methodsRef) {
681
- var methodsRef = this.props.methodsRef;
682
- methodsRef.current = {
683
- setDropdownOpen: this.handleDropdownOpen.bind(this)
675
+ var controlRef = this.props.controlRef;
676
+
677
+ if (controlRef && typeof controlRef !== 'function') {
678
+ controlRef.current = {
679
+ setDropdownOpen: this.handleDropdownOpen.bind(this),
680
+ setInputValue: this.handleSetInputValue.bind(this),
681
+ setInputFocus: this.handleSetInputFocus.bind(this),
682
+ setInputBlur: this.handleSetInputBlur.bind(this),
683
+ // `focus` & `blur` below are for backwards compatibility and may be removed. Use setInputFocus and setInputBlur instead.
684
+ focus: this.handleSetInputFocus.bind(this),
685
+ blur: this.handleSetInputBlur.bind(this)
684
686
  };
685
687
  }
686
688
  }
@@ -725,6 +727,23 @@ var Select = /*#__PURE__*/function (_React$Component) {
725
727
  this.setState({
726
728
  isOpen: nextOpenState
727
729
  });
730
+ }
731
+ }, {
732
+ key: "handleSetInputValue",
733
+ value: function handleSetInputValue(newInputValue) {
734
+ this.setState({
735
+ inputValue: newInputValue
736
+ });
737
+ }
738
+ }, {
739
+ key: "handleSetInputFocus",
740
+ value: function handleSetInputFocus() {
741
+ this.input.focus();
742
+ }
743
+ }, {
744
+ key: "handleSetInputBlur",
745
+ value: function handleSetInputBlur() {
746
+ this.input.blur();
728
747
  } // Handle touch outside on mobile to dismiss menu, ensures that the
729
748
  // touch target is not within the anchor DOM node.
730
749
 
@@ -118,11 +118,16 @@ class Select extends React.Component<PropsT, SelectStateT> {
118
118
  }
119
119
  this.isItMounted = true;
120
120
 
121
- if (this.props.methodsRef) {
122
- const { methodsRef } = this.props;
123
-
124
- methodsRef.current = {
121
+ const { controlRef } = this.props;
122
+ if (controlRef && typeof controlRef !== 'function') {
123
+ controlRef.current = {
125
124
  setDropdownOpen: this.handleDropdownOpen.bind(this),
125
+ setInputValue: this.handleSetInputValue.bind(this),
126
+ setInputFocus: this.handleSetInputFocus.bind(this),
127
+ setInputBlur: this.handleSetInputBlur.bind(this),
128
+ // `focus` & `blur` below are for backwards compatibility and may be removed. Use setInputFocus and setInputBlur instead.
129
+ focus: this.handleSetInputFocus.bind(this),
130
+ blur: this.handleSetInputBlur.bind(this),
126
131
  };
127
132
  }
128
133
  }
@@ -164,6 +169,20 @@ class Select extends React.Component<PropsT, SelectStateT> {
164
169
  });
165
170
  }
166
171
 
172
+ handleSetInputValue(newInputValue: string) {
173
+ this.setState({
174
+ inputValue: newInputValue,
175
+ });
176
+ }
177
+
178
+ handleSetInputFocus() {
179
+ this.input.focus();
180
+ }
181
+
182
+ handleSetInputBlur() {
183
+ this.input.blur();
184
+ }
185
+
167
186
  // Handle touch outside on mobile to dismiss menu, ensures that the
168
187
  // touch target is not within the anchor DOM node.
169
188
  handleTouchOutside = (event: TouchEvent) => {
@@ -479,15 +498,13 @@ class Select extends React.Component<PropsT, SelectStateT> {
479
498
  }
480
499
  };
481
500
 
501
+ // This method is to preserve backwards compatibility for users using controlRef to directly
502
+ // access the input element. This capability is not documented, and may be removed in the future.
482
503
  //flowlint-next-line unclear-type:off
483
504
  handleInputRef = (input: React.ElementRef<any>) => {
484
505
  this.input = input;
485
- if (this.props.controlRef) {
486
- if (typeof this.props.controlRef === 'function') {
487
- this.props.controlRef(input);
488
- } else {
489
- this.props.controlRef.current = input;
490
- }
506
+ if (this.props.controlRef && typeof this.props.controlRef === 'function') {
507
+ this.props.controlRef(input);
491
508
  }
492
509
  };
493
510
 
@@ -15,7 +15,7 @@ import type { OnItemSelectFnT } from '../menu/types.js';
15
15
  export type ChangeActionT = $Keys<typeof STATE_CHANGE_TYPE>;
16
16
  export type SizeT = $Keys<typeof SIZE>;
17
17
  export type TypeT = $Keys<typeof TYPE>;
18
- export type ReactRefT<T> = {| current: null | T |};
18
+ export type ReactRefT<T> = { current: null | T } | {| current: null | T |};
19
19
 
20
20
  export type OptionT = $ReadOnly<{
21
21
  id?: string | number,
@@ -73,11 +73,17 @@ export type OverridesDropdownT = {
73
73
  StatefulMenu?: OverrideT,
74
74
  };
75
75
 
76
- type ImperativeFnsT = {|
76
+ type ImperativeMethodsT = {|
77
77
  setDropdownOpen: (boolean) => mixed,
78
+ setInputValue: (string) => void,
79
+ setInputFocus: () => void,
80
+ setInputBlur: () => void,
81
+ // these below are for backwards compatibility and may be removed. Don't use them.
82
+ focus: () => void,
83
+ blur: () => void,
78
84
  |};
79
- export type MethodsRefT = {
80
- current: ImperativeFnsT | null,
85
+ export type ControlRefT = {
86
+ current: ImperativeMethodsT | null,
81
87
  };
82
88
 
83
89
  export type PropsT = {
@@ -132,8 +138,8 @@ export type PropsT = {
132
138
  id?: string,
133
139
  /** Defines if the comparison for a new creatable value should be case-insensitive. */
134
140
  ignoreCase?: boolean,
135
- /** A ref to access the input element powering the select if it's a search select, or the container div if it isn't. */
136
- controlRef?: ReactRefT<HTMLElement>,
141
+ /** An imperative handle exposing internal methods. */
142
+ controlRef?: ControlRefT,
137
143
  /** Defines if the select is in a loading (async) state. */
138
144
  isLoading: boolean,
139
145
  /** Defines an option key for a default label value. */
@@ -142,8 +148,6 @@ export type PropsT = {
142
148
  maxDropdownHeight: string,
143
149
  /** Defines if multiple options can be selected. */
144
150
  multi: boolean,
145
- /** Handle for accessing internal methods. */
146
- methodsRef?: MethodsRefT,
147
151
  /** Message to be displayed if no options is found for a search query. */
148
152
  noResultsMsg?: React.Node,
149
153
  onBlur: (e: Event) => mixed,
@@ -8,7 +8,7 @@ LICENSE file in the root directory of this source tree.
8
8
  import * as React from 'react';
9
9
  import type { OverrideT } from '../helpers/overrides.js';
10
10
 
11
- export type ReactRefT<T> = {| current: null | T |};
11
+ export type ReactRefT<T> = { current: null | T } | {| current: null | T |};
12
12
 
13
13
  export type TreeLabelOverridesT = {
14
14
  TreeItemContent?: OverrideT,