@instructure/ui-simple-select 10.19.2-snapshot-9 → 10.19.2-snapshot-10

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.
package/CHANGELOG.md CHANGED
@@ -3,12 +3,13 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
- ## [10.19.2-snapshot-9](https://github.com/instructure/instructure-ui/compare/v10.19.1...v10.19.2-snapshot-9) (2025-06-13)
6
+ ## [10.19.2-snapshot-10](https://github.com/instructure/instructure-ui/compare/v10.19.1...v10.19.2-snapshot-10) (2025-06-13)
7
7
 
8
8
 
9
9
  ### Bug Fixes
10
10
 
11
11
  * **many:** update dependencies, browsersdb and moment timezone database ([3813636](https://github.com/instructure/instructure-ui/commit/3813636458c901ad4bc74a4d5ae015cb55defcb2))
12
+ * **ui-time-select,ui-simple-select,ui-select:** add missing keyboard interactions and fix duplicate SR announcements ([0f7ffa5](https://github.com/instructure/instructure-ui/commit/0f7ffa5b263b0b287ca1c2387e0b902189706cb2))
12
13
 
13
14
 
14
15
 
@@ -88,6 +88,20 @@ let SimpleSelect = (_dec = withDeterministicId(), _dec2 = testable(), _dec(_clas
88
88
  if (typeof this.props.onShowOptions === 'function') {
89
89
  this.props.onShowOptions(event);
90
90
  }
91
+ if (event.type.startsWith('key')) {
92
+ const keyboardEvent = event;
93
+ const children = Children.toArray(this.props.children);
94
+ if (!this.state.inputValue && children.length > 0) {
95
+ const position = keyboardEvent.key === 'ArrowDown' ? 'first' : keyboardEvent.key === 'ArrowUp' ? 'last' : void 0;
96
+ if (position) {
97
+ var _this$getOptionByPosi;
98
+ const optionId = (_this$getOptionByPosi = this.getOptionByPosition(position)) === null || _this$getOptionByPosi === void 0 ? void 0 : _this$getOptionByPosi.props.id;
99
+ optionId && this.setState({
100
+ highlightedOptionId: optionId
101
+ });
102
+ }
103
+ }
104
+ }
91
105
  };
92
106
  this.handleHideOptions = event => {
93
107
  this.setState(state => {
@@ -102,16 +116,13 @@ let SimpleSelect = (_dec = withDeterministicId(), _dec2 = testable(), _dec(_clas
102
116
  this.props.onHideOptions(event);
103
117
  }
104
118
  };
105
- this.handleHighlightOption = (event, {
119
+ this.handleHighlightOption = (_event, {
106
120
  id
107
121
  }) => {
108
122
  if (id === this._emptyOptionId) return;
109
- const option = this.getOption('id', id);
110
- const label = option === null || option === void 0 ? void 0 : option.props.children;
111
- const inputValue = event.type === 'keydown' ? label : this.state.inputValue;
112
123
  this.setState({
113
124
  highlightedOptionId: id,
114
- inputValue
125
+ inputValue: this.state.inputValue
115
126
  });
116
127
  };
117
128
  this.handleSelectOption = (event, {
@@ -255,6 +266,29 @@ let SimpleSelect = (_dec = withDeterministicId(), _dec2 = testable(), _dec(_clas
255
266
  }
256
267
  return match;
257
268
  }
269
+ getOptionByPosition(position) {
270
+ const children = Children.toArray(this.props.children);
271
+
272
+ // Determine where to start looking based on position
273
+ const index = position === 'first' ? 0 : children.length - 1;
274
+
275
+ // Check if child is an option or group
276
+ const child = children[index];
277
+ if (!child) return void 0;
278
+
279
+ // If it's a regular option, return it
280
+ if (matchComponentTypes(child, [Option])) {
281
+ return child;
282
+ }
283
+
284
+ // If it's a group, get its options
285
+ if (matchComponentTypes(child, [Group])) {
286
+ const groupOptions = Children.toArray(child.props.children);
287
+ const groupIndex = position === 'first' ? 0 : groupOptions.length - 1;
288
+ return groupOptions[groupIndex];
289
+ }
290
+ return void 0;
291
+ }
258
292
  renderChildren() {
259
293
  let children = Children.toArray(this.props.children);
260
294
  children = Children.map(children, child => {
@@ -99,6 +99,20 @@ let SimpleSelect = exports.SimpleSelect = (_dec = (0, _withDeterministicId.withD
99
99
  if (typeof this.props.onShowOptions === 'function') {
100
100
  this.props.onShowOptions(event);
101
101
  }
102
+ if (event.type.startsWith('key')) {
103
+ const keyboardEvent = event;
104
+ const children = _react.Children.toArray(this.props.children);
105
+ if (!this.state.inputValue && children.length > 0) {
106
+ const position = keyboardEvent.key === 'ArrowDown' ? 'first' : keyboardEvent.key === 'ArrowUp' ? 'last' : void 0;
107
+ if (position) {
108
+ var _this$getOptionByPosi;
109
+ const optionId = (_this$getOptionByPosi = this.getOptionByPosition(position)) === null || _this$getOptionByPosi === void 0 ? void 0 : _this$getOptionByPosi.props.id;
110
+ optionId && this.setState({
111
+ highlightedOptionId: optionId
112
+ });
113
+ }
114
+ }
115
+ }
102
116
  };
103
117
  this.handleHideOptions = event => {
104
118
  this.setState(state => {
@@ -113,16 +127,13 @@ let SimpleSelect = exports.SimpleSelect = (_dec = (0, _withDeterministicId.withD
113
127
  this.props.onHideOptions(event);
114
128
  }
115
129
  };
116
- this.handleHighlightOption = (event, {
130
+ this.handleHighlightOption = (_event, {
117
131
  id
118
132
  }) => {
119
133
  if (id === this._emptyOptionId) return;
120
- const option = this.getOption('id', id);
121
- const label = option === null || option === void 0 ? void 0 : option.props.children;
122
- const inputValue = event.type === 'keydown' ? label : this.state.inputValue;
123
134
  this.setState({
124
135
  highlightedOptionId: id,
125
- inputValue
136
+ inputValue: this.state.inputValue
126
137
  });
127
138
  };
128
139
  this.handleSelectOption = (event, {
@@ -266,6 +277,29 @@ let SimpleSelect = exports.SimpleSelect = (_dec = (0, _withDeterministicId.withD
266
277
  }
267
278
  return match;
268
279
  }
280
+ getOptionByPosition(position) {
281
+ const children = _react.Children.toArray(this.props.children);
282
+
283
+ // Determine where to start looking based on position
284
+ const index = position === 'first' ? 0 : children.length - 1;
285
+
286
+ // Check if child is an option or group
287
+ const child = children[index];
288
+ if (!child) return void 0;
289
+
290
+ // If it's a regular option, return it
291
+ if ((0, _matchComponentTypes.matchComponentTypes)(child, [_Option.Option])) {
292
+ return child;
293
+ }
294
+
295
+ // If it's a group, get its options
296
+ if ((0, _matchComponentTypes.matchComponentTypes)(child, [_Group.Group])) {
297
+ const groupOptions = _react.Children.toArray(child.props.children);
298
+ const groupIndex = position === 'first' ? 0 : groupOptions.length - 1;
299
+ return groupOptions[groupIndex];
300
+ }
301
+ return void 0;
302
+ }
269
303
  renderChildren() {
270
304
  let children = _react.Children.toArray(this.props.children);
271
305
  children = _react.Children.map(children, child => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-simple-select",
3
- "version": "10.19.2-snapshot-9",
3
+ "version": "10.19.2-snapshot-10",
4
4
  "description": "A component for standard select element behavior.",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "module": "./es/index.js",
@@ -24,23 +24,23 @@
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
26
  "@babel/runtime": "^7.27.6",
27
- "@instructure/console": "10.19.2-snapshot-9",
28
- "@instructure/shared-types": "10.19.2-snapshot-9",
29
- "@instructure/ui-form-field": "10.19.2-snapshot-9",
30
- "@instructure/ui-position": "10.19.2-snapshot-9",
31
- "@instructure/ui-prop-types": "10.19.2-snapshot-9",
32
- "@instructure/ui-react-utils": "10.19.2-snapshot-9",
33
- "@instructure/ui-select": "10.19.2-snapshot-9",
34
- "@instructure/ui-testable": "10.19.2-snapshot-9",
27
+ "@instructure/console": "10.19.2-snapshot-10",
28
+ "@instructure/shared-types": "10.19.2-snapshot-10",
29
+ "@instructure/ui-form-field": "10.19.2-snapshot-10",
30
+ "@instructure/ui-position": "10.19.2-snapshot-10",
31
+ "@instructure/ui-prop-types": "10.19.2-snapshot-10",
32
+ "@instructure/ui-react-utils": "10.19.2-snapshot-10",
33
+ "@instructure/ui-select": "10.19.2-snapshot-10",
34
+ "@instructure/ui-testable": "10.19.2-snapshot-10",
35
35
  "prop-types": "^15.8.1"
36
36
  },
37
37
  "devDependencies": {
38
- "@instructure/ui-axe-check": "10.19.2-snapshot-9",
39
- "@instructure/ui-babel-preset": "10.19.2-snapshot-9",
40
- "@instructure/ui-color-utils": "10.19.2-snapshot-9",
41
- "@instructure/ui-icons": "10.19.2-snapshot-9",
42
- "@instructure/ui-test-utils": "10.19.2-snapshot-9",
43
- "@instructure/ui-utils": "10.19.2-snapshot-9",
38
+ "@instructure/ui-axe-check": "10.19.2-snapshot-10",
39
+ "@instructure/ui-babel-preset": "10.19.2-snapshot-10",
40
+ "@instructure/ui-color-utils": "10.19.2-snapshot-10",
41
+ "@instructure/ui-icons": "10.19.2-snapshot-10",
42
+ "@instructure/ui-test-utils": "10.19.2-snapshot-10",
43
+ "@instructure/ui-utils": "10.19.2-snapshot-10",
44
44
  "@testing-library/jest-dom": "^6.6.3",
45
45
  "@testing-library/react": "^16.0.1",
46
46
  "@testing-library/user-event": "^14.6.1",
@@ -248,6 +248,31 @@ class SimpleSelect extends Component<SimpleSelectProps, SimpleSelectState> {
248
248
  return match
249
249
  }
250
250
 
251
+ getOptionByPosition(position: 'first' | 'last'): OptionChild | undefined {
252
+ const children = Children.toArray(this.props.children)
253
+
254
+ // Determine where to start looking based on position
255
+ const index = position === 'first' ? 0 : children.length - 1
256
+
257
+ // Check if child is an option or group
258
+ const child = children[index]
259
+ if (!child) return undefined
260
+
261
+ // If it's a regular option, return it
262
+ if (matchComponentTypes<OptionChild>(child, [Option])) {
263
+ return child
264
+ }
265
+
266
+ // If it's a group, get its options
267
+ if (matchComponentTypes<GroupChild>(child, [Group])) {
268
+ const groupOptions = Children.toArray(child.props.children)
269
+ const groupIndex = position === 'first' ? 0 : groupOptions.length - 1
270
+ return groupOptions[groupIndex] as OptionChild
271
+ }
272
+
273
+ return undefined
274
+ }
275
+
251
276
  handleRef = (node: Select) => {
252
277
  this.ref = node
253
278
  }
@@ -264,6 +289,30 @@ class SimpleSelect extends Component<SimpleSelectProps, SimpleSelectState> {
264
289
  if (typeof this.props.onShowOptions === 'function') {
265
290
  this.props.onShowOptions(event)
266
291
  }
292
+
293
+ if (event.type.startsWith('key')) {
294
+ const keyboardEvent = event as React.KeyboardEvent
295
+ const children = Children.toArray(this.props.children) as (
296
+ | OptionChild
297
+ | GroupChild
298
+ )[]
299
+
300
+ if (!this.state.inputValue && children.length > 0) {
301
+ const position =
302
+ keyboardEvent.key === 'ArrowDown'
303
+ ? 'first'
304
+ : keyboardEvent.key === 'ArrowUp'
305
+ ? 'last'
306
+ : undefined
307
+ if (position) {
308
+ const optionId = this.getOptionByPosition(position)?.props.id
309
+ optionId &&
310
+ this.setState({
311
+ highlightedOptionId: optionId
312
+ })
313
+ }
314
+ }
315
+ }
267
316
  }
268
317
 
269
318
  handleHideOptions: SelectProps['onRequestHideOptions'] = (event) => {
@@ -281,18 +330,14 @@ class SimpleSelect extends Component<SimpleSelectProps, SimpleSelectState> {
281
330
  }
282
331
 
283
332
  handleHighlightOption: SelectProps['onRequestHighlightOption'] = (
284
- event,
333
+ _event,
285
334
  { id }
286
335
  ) => {
287
336
  if (id === this._emptyOptionId) return
288
337
 
289
- const option = this.getOption('id', id)
290
- const label = option?.props.children
291
- const inputValue = event.type === 'keydown' ? label : this.state.inputValue
292
-
293
338
  this.setState({
294
339
  highlightedOptionId: id,
295
- inputValue
340
+ inputValue: this.state.inputValue
296
341
  })
297
342
  }
298
343