@instructure/ui-select 10.16.1 → 10.16.3

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.
@@ -22,7 +22,8 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- import { ComponentElement, Children, Component, memo } from 'react'
25
+
26
+ import { ComponentElement, Children, Component, memo, ReactNode } from 'react'
26
27
 
27
28
  import * as utils from '@instructure/ui-utils'
28
29
  import { testable } from '@instructure/ui-testable'
@@ -186,6 +187,10 @@ class Select extends Component<SelectProps> {
186
187
  this._input && this._input.focus()
187
188
  }
188
189
 
190
+ blur() {
191
+ this._input && this._input.blur()
192
+ }
193
+
189
194
  get childrenArray() {
190
195
  return Children.toArray(this.props.children) as SelectChildren
191
196
  }
@@ -735,7 +740,17 @@ class Select extends Component<SelectProps> {
735
740
  shouldNotWrap,
736
741
  display: isInline ? 'inline-block' : 'block',
737
742
  renderBeforeInput: this.handleRenderBeforeInput(),
738
- renderAfterInput: this.handleRenderAfterInput(),
743
+ // On iOS VoiceOver, if there is a custom element instead of the changing up and down arrow button
744
+ // the listbox closes on a swipe, so a DOM change is enforced by the key change
745
+ // that seems to inform VoiceOver to behave the correct way
746
+ renderAfterInput:
747
+ utils.isAndroidOrIOS() && renderAfterInput !== undefined ? (
748
+ <span key={this.props.isShowingOptions ? 'open' : 'closed'}>
749
+ {this.handleRenderAfterInput() as ReactNode}
750
+ </span>
751
+ ) : (
752
+ this.handleRenderAfterInput()
753
+ ),
739
754
 
740
755
  // If `inputValue` is provided, we need to pass a default onChange handler,
741
756
  // because TextInput `value` is a controlled prop,
@@ -798,7 +813,16 @@ class Select extends Component<SelectProps> {
798
813
  <Popover
799
814
  constrain={constrain}
800
815
  placement={placement}
801
- mountNode={mountNode}
816
+ // On iOS VoiceOver, the Popover is mounted right after the input
817
+ // in order to be able to navigate through the list items with a swipe.
818
+ // The swipe would result in closing the listbox if mounted elsewhere.
819
+ mountNode={
820
+ mountNode !== undefined
821
+ ? mountNode
822
+ : utils.isAndroidOrIOS()
823
+ ? this.ref
824
+ : undefined
825
+ }
802
826
  positionTarget={this._inputContainer}
803
827
  isShowingContent={isShowingOptions}
804
828
  shouldReturnFocus={false}