@instructure/ui-time-select 8.37.1-snapshot-13 → 8.38.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.
@@ -67,15 +67,31 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
67
67
  };
68
68
  this.handleBlur = event => {
69
69
  var _this$props$onBlur, _this$props;
70
- this.setState({
71
- highlightedOptionId: void 0
72
- });
73
70
  (_this$props$onBlur = (_this$props = this.props).onBlur) === null || _this$props$onBlur === void 0 ? void 0 : _this$props$onBlur.call(_this$props, event);
74
71
  };
75
72
  this.handleInputChange = event => {
76
73
  var _this$props$onInputCh, _this$props3;
77
74
  const value = event.target.value;
78
75
  const newOptions = this.filterOptions(value);
76
+ if ((newOptions === null || newOptions === void 0 ? void 0 : newOptions.length) == 1) {
77
+ // if there is only 1 option, it will be automatically selected except
78
+ // if in controlled mode (it would commit this change)
79
+ if (!this.isControlled) {
80
+ this.setState({
81
+ selectedOptionId: newOptions[0].id
82
+ });
83
+ }
84
+ this.setState({
85
+ fireChangeOnBlur: newOptions[0]
86
+ });
87
+ } else {
88
+ this.setState({
89
+ // needs not to lose selectedOptionId in controlled mode otherwise it'd
90
+ // revert to the default or '' instead of the set value
91
+ selectedOptionId: this.isControlled ? this.state.selectedOptionId : void 0,
92
+ fireChangeOnBlur: void 0
93
+ });
94
+ }
79
95
  this.setState({
80
96
  inputValue: value,
81
97
  filteredOptions: newOptions,
@@ -89,112 +105,111 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
89
105
  const inputAsDate = this.parseInputText(value);
90
106
  (_this$props$onInputCh = (_this$props3 = this.props).onInputChange) === null || _this$props$onInputCh === void 0 ? void 0 : _this$props$onInputCh.call(_this$props3, event, value, inputAsDate.isValid() ? inputAsDate.toISOString() : void 0);
91
107
  };
108
+ this.onKeyDown = event => {
109
+ var _this$props$onKeyDown, _this$props4;
110
+ const input = this.parseInputText(this.state.inputValue);
111
+ if (event.key === 'Enter' && this.props.allowNonStepInput && input.isValid()) {
112
+ this.setState(() => ({
113
+ isShowingOptions: false,
114
+ highlightedOptionId: void 0
115
+ }));
116
+ // others are set in handleBlurOrEsc
117
+ }
118
+
119
+ (_this$props$onKeyDown = (_this$props4 = this.props).onKeyDown) === null || _this$props$onKeyDown === void 0 ? void 0 : _this$props$onKeyDown.call(_this$props4, event);
120
+ };
92
121
  this.handleShowOptions = event => {
93
- var _this$props$onShowOpt2, _this$props4;
122
+ var _this$props$onShowOpt2, _this$props5;
94
123
  this.setState({
95
124
  isShowingOptions: true,
96
125
  highlightedOptionId: this.state.selectedOptionId
97
126
  });
98
- (_this$props$onShowOpt2 = (_this$props4 = this.props).onShowOptions) === null || _this$props$onShowOpt2 === void 0 ? void 0 : _this$props$onShowOpt2.call(_this$props4, event);
127
+ (_this$props$onShowOpt2 = (_this$props5 = this.props).onShowOptions) === null || _this$props$onShowOpt2 === void 0 ? void 0 : _this$props$onShowOpt2.call(_this$props5, event);
99
128
  };
100
- this.handleHideOptions = event => {
101
- var _this$props$onHideOpt, _this$props5;
102
- const input = this.parseInputText(this.state.inputValue);
129
+ this.handleBlurOrEsc = event => {
130
+ var _this$props$onHideOpt, _this$props7;
131
+ const _this$state = this.state,
132
+ selectedOptionId = _this$state.selectedOptionId,
133
+ inputValue = _this$state.inputValue;
103
134
  let defaultValue = '';
104
135
  if (this.props.defaultValue) {
105
136
  const date = _DateTime.DateTime.parse(this.props.defaultValue, this.locale(), this.timezone());
106
137
  defaultValue = this.props.format ? date.format(this.props.format) : date.toISOString();
107
138
  }
108
- if (!this.props.allowNonStepInput || this.props.allowNonStepInput && input.isValid() && input.minute() % this.props.step === 0) {
109
- const selectedOptionId = this.state.selectedOptionId;
110
- const option = this.getOption('id', selectedOptionId);
111
- this.setState(() => ({
112
- isShowingOptions: false,
113
- highlightedOptionId: void 0,
114
- inputValue: selectedOptionId ? option.label : defaultValue,
115
- filteredOptions: this.filterOptions(''),
116
- ...this.matchValue()
117
- }));
118
- } else {
139
+ const selectedOption = this.getOption('id', selectedOptionId);
140
+ let newInputValue = defaultValue;
141
+ if (selectedOption) {
142
+ // If there is a selected option use its value in the input field.
143
+ newInputValue = selectedOption.label;
144
+ }
145
+ // if input was completely cleared, ensure it stays clear
146
+ // e.g. defaultValue defined, but no selection yet made
147
+ else if (inputValue === '') {
148
+ newInputValue = '';
149
+ }
150
+ this.setState(() => ({
151
+ isShowingOptions: false,
152
+ highlightedOptionId: void 0,
153
+ inputValue: newInputValue,
154
+ filteredOptions: this.filterOptions('')
155
+ }));
156
+ if (this.state.fireChangeOnBlur && event.key !== 'Escape') {
157
+ var _this$props$onChange, _this$props6;
119
158
  this.setState(() => ({
120
- isShowingOptions: false,
121
- highlightedOptionId: void 0,
122
- inputValue: this.state.lastValidInput || defaultValue || '',
123
- filteredOptions: this.filterOptions('')
159
+ fireChangeOnBlur: void 0
124
160
  }));
161
+ (_this$props$onChange = (_this$props6 = this.props).onChange) === null || _this$props$onChange === void 0 ? void 0 : _this$props$onChange.call(_this$props6, event, {
162
+ value: this.state.fireChangeOnBlur.value.toISOString(),
163
+ inputText: this.state.fireChangeOnBlur.label
164
+ });
125
165
  }
126
- (_this$props$onHideOpt = (_this$props5 = this.props).onHideOptions) === null || _this$props$onHideOpt === void 0 ? void 0 : _this$props$onHideOpt.call(_this$props5, event);
127
- };
128
- this.handleHighlightOption = (event, _ref) => {
129
- let id = _ref.id;
130
- if (id === this._emptyOptionId) return;
131
- const type = event.type;
132
- const option = this.getOption('id', id).label;
133
- this.setState(state => ({
134
- highlightedOptionId: id,
135
- inputValue: type === 'keydown' ? option : state.inputValue
136
- }));
166
+ // TODO only fire this if handleSelectOption was not called before.
167
+ (_this$props$onHideOpt = (_this$props7 = this.props).onHideOptions) === null || _this$props$onHideOpt === void 0 ? void 0 : _this$props$onHideOpt.call(_this$props7, event);
137
168
  };
138
- this.handleSelectOption = (event, _ref2) => {
139
- var _this$props$onHideOpt2, _this$props7;
140
- let id = _ref2.id;
141
- if (id === this._emptyOptionId) {
169
+ this.handleSelectOption = (event, data) => {
170
+ var _this$props$onHideOpt2, _this$props9;
171
+ if (data.id === this._emptyOptionId) {
142
172
  this.setState({
143
173
  isShowingOptions: false
144
174
  });
145
175
  return;
146
176
  }
147
- const option = this.getOption('id', id);
177
+ const selectedOption = this.getOption('id', data.id);
148
178
  let newInputValue;
179
+ const currentSelectedOptionId = this.state.selectedOptionId;
149
180
  if (this.isControlled) {
181
+ // in controlled mode we leave to the user to set the value of the
182
+ // component e.g. in the onChange event handler.
183
+ // This is accomplished by not setting a selectedOptionId
150
184
  const prev = this.getOption('id', this.state.selectedOptionId);
151
185
  newInputValue = prev ? prev.label : '';
152
186
  this.setState({
153
- isShowingOptions: false,
154
- inputValue: newInputValue,
155
- filteredOptions: this.filterOptions('')
187
+ isShowingOptions: false
156
188
  });
157
189
  } else {
158
- newInputValue = option.label;
190
+ newInputValue = selectedOption.label;
159
191
  this.setState({
160
192
  isShowingOptions: false,
161
- selectedOptionId: id,
162
- inputValue: newInputValue,
163
- filteredOptions: this.filterOptions('')
164
- });
165
- }
166
- if (id !== this.state.selectedOptionId) {
167
- var _this$props$onChange, _this$props6;
168
- this.setState({
169
- lastValidInput: newInputValue
170
- });
171
- (_this$props$onChange = (_this$props6 = this.props).onChange) === null || _this$props$onChange === void 0 ? void 0 : _this$props$onChange.call(_this$props6, event, {
172
- value: option.value,
173
- inputText: newInputValue
193
+ selectedOptionId: data.id,
194
+ inputValue: newInputValue
174
195
  });
175
196
  }
176
- (_this$props$onHideOpt2 = (_this$props7 = this.props).onHideOptions) === null || _this$props$onHideOpt2 === void 0 ? void 0 : _this$props$onHideOpt2.call(_this$props7, event);
177
- };
178
- this.onKeyDown = event => {
179
- var _this$props$onKeyDown, _this$props9;
180
- const input = this.parseInputText(this.state.inputValue);
181
- // validate input and if OK close dropdown
182
- if (event.key === 'Enter' && this.props.allowNonStepInput && input.isValid() && input.minute() % this.props.step !== 0 && this.state.lastValidInput != this.state.inputValue) {
197
+ if (data.id !== currentSelectedOptionId) {
183
198
  var _this$props$onChange2, _this$props8;
184
- this.setState(() => ({
185
- isShowingOptions: false,
186
- highlightedOptionId: void 0,
187
- filteredOptions: this.filterOptions(''),
188
- lastValidInput: this.state.inputValue
189
- }));
190
199
  (_this$props$onChange2 = (_this$props8 = this.props).onChange) === null || _this$props$onChange2 === void 0 ? void 0 : _this$props$onChange2.call(_this$props8, event, {
191
- value: input.toISOString(),
192
- inputText: this.state.inputValue
200
+ value: selectedOption.value.toISOString(),
201
+ inputText: newInputValue
193
202
  });
194
- // others are set in OnHideOptions
195
203
  }
196
-
197
- (_this$props$onKeyDown = (_this$props9 = this.props).onKeyDown) === null || _this$props$onKeyDown === void 0 ? void 0 : _this$props$onKeyDown.call(_this$props9, event);
204
+ (_this$props$onHideOpt2 = (_this$props9 = this.props).onHideOptions) === null || _this$props$onHideOpt2 === void 0 ? void 0 : _this$props$onHideOpt2.call(_this$props9, event);
205
+ };
206
+ this.handleHighlightOption = (event, data) => {
207
+ if (data.id === this._emptyOptionId) return;
208
+ const option = this.getOption('id', data.id).label;
209
+ this.setState(state => ({
210
+ highlightedOptionId: data.id,
211
+ inputValue: event.type === 'keydown' ? option : state.inputValue
212
+ }));
198
213
  };
199
214
  this.parseInputText = inputValue => {
200
215
  const input = _DateTime.DateTime.parse(inputValue, this.locale(), this.timezone(), [this.props.format], true);
@@ -249,22 +264,29 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
249
264
  return _DateTime.DateTime.browserTimeZone();
250
265
  }
251
266
  componentDidUpdate(prevProps) {
252
- if (this.props.step !== prevProps.step || this.props.format !== prevProps.format || this.props.locale !== prevProps.locale || this.props.timezone !== prevProps.timezone) {
267
+ if (this.props.step !== prevProps.step || this.props.format !== prevProps.format || this.props.locale !== prevProps.locale || this.props.timezone !== prevProps.timezone || this.props.allowNonStepInput !== prevProps.allowNonStepInput) {
253
268
  // options change, reset everything
254
269
  // when controlled, selection will be preserved
255
270
  // when uncontrolled, selection will be lost
256
271
  this.setState(this.getInitialState());
257
272
  }
258
273
  if (this.props.value !== prevProps.value) {
259
- const normalizedValue = this.normalizeISOTime(this.props.value);
274
+ let newValue;
275
+ if (this.props.value) {
276
+ newValue = _DateTime.DateTime.parse(this.props.value, this.locale(), this.timezone());
277
+ }
260
278
  // value changed
261
279
  const initState = this.getInitialState();
262
280
  this.setState(initState);
263
281
  // options need to be passed because state is not set immediately
264
- let option = this.getOption('value', normalizedValue, initState.options);
265
- if (typeof normalizedValue === 'undefined') {
282
+ let option;
283
+ if (!this.isControlled) {
266
284
  // preserve current value when changing from controlled to uncontrolled
267
- option = this.getOption('value', this.normalizeISOTime(prevProps.value));
285
+ if (prevProps.value) {
286
+ option = this.getOption('id', this.getFormattedId(_DateTime.DateTime.parse(prevProps.value, this.locale(), this.timezone())));
287
+ }
288
+ } else if (newValue) {
289
+ option = this.getOption('id', this.getFormattedId(newValue), initState.options);
268
290
  }
269
291
  const outsideVal = this.props.value ? this.props.value : '';
270
292
  // value does not match an existing option
@@ -279,14 +301,10 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
279
301
  });
280
302
  }
281
303
  }
282
-
283
- // value needs to be normalized because e.g. 2022-03-29T19:00Z and
284
- // 2022-03-29T19:00:00.000Z refer to the same time in the same timezone.
285
- normalizeISOTime(value) {
286
- if (!value) {
287
- return value;
288
- }
289
- return _DateTime.DateTime.parse(value, this.locale(), this.timezone()).toISOString();
304
+ getFormattedId(date) {
305
+ // ISO8601 strings may contain a space. Remove any spaces before using the
306
+ // date as the id.
307
+ return date.toISOString().replace(/\s/g, '');
290
308
  }
291
309
  getInitialState() {
292
310
  const initialOptions = this.generateOptions();
@@ -294,7 +312,8 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
294
312
  return {
295
313
  inputValue: initialSelection ? initialSelection.label : '',
296
314
  options: initialOptions,
297
- filteredOptions: initialOptions,
315
+ // 288 = 5 min step
316
+ filteredOptions: initialOptions.length > 288 ? initialOptions.filter(opt => opt.value.minute() % this.props.step === 0) : initialOptions,
298
317
  isShowingOptions: false,
299
318
  highlightedOptionId: initialSelection ? initialSelection.id : void 0,
300
319
  selectedOptionId: initialSelection ? initialSelection.id : void 0
@@ -308,16 +327,18 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
308
327
  format = _this$props10.format;
309
328
  const initialValue = value || defaultValue;
310
329
  if (typeof initialValue === 'string') {
330
+ const date = _DateTime.DateTime.parse(initialValue, this.locale(), this.timezone());
311
331
  // get option based on value or defaultValue, if provided
312
- const option = this.getOption('value', this.normalizeISOTime(initialValue), options);
332
+ const option = this.getOption('value', date, options);
313
333
  if (option) {
314
334
  // value matches an existing option
315
335
  return option;
316
336
  }
317
337
  // value does not match an existing option
318
- const date = _DateTime.DateTime.parse(initialValue, this.locale(), this.timezone());
319
338
  return {
320
- label: format ? date.format(format) : date.toISOString()
339
+ id: this.getFormattedId(date),
340
+ label: format ? date.format(format) : date.toISOString(),
341
+ value: date
321
342
  };
322
343
  }
323
344
  // otherwise, return first option, if desired
@@ -326,11 +347,6 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
326
347
  }
327
348
  return void 0;
328
349
  }
329
- getFormattedId(date) {
330
- // ISO8601 strings may contain a space. Remove any spaces before using the
331
- // date as the id.
332
- return date.toISOString().replace(/\s/g, '');
333
- }
334
350
  getBaseDate() {
335
351
  let baseDate;
336
352
  const baseValue = this.props.value || this.props.defaultValue;
@@ -347,9 +363,12 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
347
363
  generateOptions() {
348
364
  const date = this.getBaseDate();
349
365
  const options = [];
366
+ const step = this.props.step ? this.props.step : 30;
367
+ const maxMinute = this.props.allowNonStepInput ? 60 : 60 / step;
368
+ const minuteStep = this.props.allowNonStepInput ? 1 : step;
350
369
  for (let hour = 0; hour < 24; hour++) {
351
- for (let minute = 0; minute < 60 / this.props.step; minute++) {
352
- const minutes = minute * this.props.step;
370
+ for (let minute = 0; minute < maxMinute; minute++) {
371
+ const minutes = minute * minuteStep;
353
372
  const newDate = date.set({
354
373
  hour: hour,
355
374
  minute: minutes
@@ -357,8 +376,7 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
357
376
  // store time options
358
377
  options.push({
359
378
  id: this.getFormattedId(newDate),
360
- // iso no spaces
361
- value: newDate.toISOString(),
379
+ value: newDate.clone(),
362
380
  label: this.props.format ? newDate.format(this.props.format) : newDate.toISOString()
363
381
  });
364
382
  }
@@ -366,58 +384,38 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
366
384
  return options;
367
385
  }
368
386
  filterOptions(inputValue) {
369
- var _this$state;
370
- return (_this$state = this.state) === null || _this$state === void 0 ? void 0 : _this$state.options.filter(option => option.label.toLowerCase().startsWith(inputValue.toLowerCase()));
371
- }
372
- matchValue() {
373
- const _this$state2 = this.state,
374
- inputValue = _this$state2.inputValue,
375
- filteredOptions = _this$state2.filteredOptions,
376
- highlightedOptionId = _this$state2.highlightedOptionId,
377
- selectedOptionId = _this$state2.selectedOptionId;
378
-
379
- // an option matching user input exists
380
- if (filteredOptions.length === 1) {
381
- const onlyOption = filteredOptions[0];
382
- // automatically select the matching option
383
- if (onlyOption.label.toLowerCase() === inputValue.toLowerCase()) {
384
- return {
385
- inputValue: onlyOption.label,
386
- selectedOptionId: onlyOption.id,
387
- filteredOptions: this.filterOptions('')
388
- };
389
- }
390
- }
391
- // no match found, return selected option label to input
392
- const selectedOption = this.getOption('id', selectedOptionId);
393
- if (selectedOption) {
394
- return {
395
- inputValue: selectedOption.label
396
- };
397
- }
398
- // input value is from highlighted option, not user input
399
- if (highlightedOptionId) {
400
- if (inputValue === this.getOption('id', highlightedOptionId).label) {
401
- return {
402
- inputValue: '',
403
- filteredOptions: this.filterOptions('')
404
- };
387
+ var _this$state3;
388
+ let inputNoSeconds = inputValue;
389
+ // if the input contains seconds disregard them (e.g. if format = LTS)
390
+ if (inputValue.length > 5) {
391
+ // e.g. "5:34:"
392
+ const input = this.parseInputText(inputValue);
393
+ if (input.isValid()) {
394
+ input.set({
395
+ second: 0
396
+ });
397
+ inputNoSeconds = input.format(this.props.format);
405
398
  }
406
399
  }
407
- // if input was completely cleared, ensure it stays clear
408
- // e.g. defaultValue defined, but no selection yet made
409
- if (inputValue === '') {
410
- return {
411
- inputValue: ''
412
- };
400
+ if (this.props.allowNonStepInput && inputNoSeconds.length < 3) {
401
+ var _this$state2;
402
+ // could show too many results, show only step values
403
+ return (_this$state2 = this.state) === null || _this$state2 === void 0 ? void 0 : _this$state2.options.filter(option => {
404
+ return option.label.toLowerCase().startsWith(inputNoSeconds.toLowerCase()) && option.value.minute() % this.props.step == 0;
405
+ });
413
406
  }
414
- return void 0;
407
+ return (_this$state3 = this.state) === null || _this$state3 === void 0 ? void 0 : _this$state3.options.filter(option => option.label.toLowerCase().startsWith(inputNoSeconds.toLowerCase()));
415
408
  }
409
+
410
+ // Called when the input is blurred (=when clicking outside, tabbing away),
411
+ // when pressing ESC. NOT called when an item is selected via Enter/click,
412
+ // (but in this case it will be called later when the input is blurred.)
413
+ // Called when an option is selected via mouse click or Enter.
416
414
  renderOptions() {
417
- const _this$state3 = this.state,
418
- filteredOptions = _this$state3.filteredOptions,
419
- highlightedOptionId = _this$state3.highlightedOptionId,
420
- selectedOptionId = _this$state3.selectedOptionId;
415
+ const _this$state4 = this.state,
416
+ filteredOptions = _this$state4.filteredOptions,
417
+ highlightedOptionId = _this$state4.highlightedOptionId,
418
+ selectedOptionId = _this$state4.selectedOptionId;
421
419
  if (filteredOptions.length < 1) {
422
420
  return this.renderEmptyOption();
423
421
  }
@@ -467,9 +465,9 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
467
465
  onKeyDown = _this$props11.onKeyDown,
468
466
  mountNode = _this$props11.mountNode,
469
467
  rest = (0, _objectWithoutProperties2.default)(_this$props11, _excluded);
470
- const _this$state4 = this.state,
471
- inputValue = _this$state4.inputValue,
472
- isShowingOptions = _this$state4.isShowingOptions;
468
+ const _this$state5 = this.state,
469
+ inputValue = _this$state5.inputValue,
470
+ isShowingOptions = _this$state5.isShowingOptions;
473
471
  return /*#__PURE__*/_react.default.createElement(_Select.Select, Object.assign({
474
472
  mountNode: mountNode,
475
473
  renderLabel: renderLabel,
@@ -494,7 +492,7 @@ let TimeSelect = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2
494
492
  renderAfterInput: renderAfterInput,
495
493
  isShowingOptions: isShowingOptions,
496
494
  onRequestShowOptions: this.handleShowOptions,
497
- onRequestHideOptions: this.handleHideOptions,
495
+ onRequestHideOptions: this.handleBlurOrEsc,
498
496
  onRequestHighlightOption: this.handleHighlightOption,
499
497
  onRequestSelectOption: this.handleSelectOption,
500
498
  onInputChange: this.handleInputChange,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-time-select",
3
- "version": "8.37.1-snapshot-13",
3
+ "version": "8.38.0",
4
4
  "description": "A component for selecting time values.",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "module": "./es/index.js",
@@ -24,21 +24,21 @@
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
26
  "@babel/runtime": "^7.21.0",
27
- "@instructure/shared-types": "8.37.1-snapshot-13",
28
- "@instructure/ui-form-field": "8.37.1-snapshot-13",
29
- "@instructure/ui-i18n": "8.37.1-snapshot-13",
30
- "@instructure/ui-position": "8.37.1-snapshot-13",
31
- "@instructure/ui-prop-types": "8.37.1-snapshot-13",
32
- "@instructure/ui-react-utils": "8.37.1-snapshot-13",
33
- "@instructure/ui-select": "8.37.1-snapshot-13",
34
- "@instructure/ui-test-locator": "8.37.1-snapshot-13",
35
- "@instructure/ui-testable": "8.37.1-snapshot-13",
36
- "@instructure/ui-utils": "8.37.1-snapshot-13",
27
+ "@instructure/shared-types": "8.38.0",
28
+ "@instructure/ui-form-field": "8.38.0",
29
+ "@instructure/ui-i18n": "8.38.0",
30
+ "@instructure/ui-position": "8.38.0",
31
+ "@instructure/ui-prop-types": "8.38.0",
32
+ "@instructure/ui-react-utils": "8.38.0",
33
+ "@instructure/ui-select": "8.38.0",
34
+ "@instructure/ui-test-locator": "8.38.0",
35
+ "@instructure/ui-testable": "8.38.0",
36
+ "@instructure/ui-utils": "8.38.0",
37
37
  "prop-types": "^15.8.1"
38
38
  },
39
39
  "devDependencies": {
40
- "@instructure/ui-babel-preset": "8.37.1-snapshot-13",
41
- "@instructure/ui-test-utils": "8.37.1-snapshot-13",
40
+ "@instructure/ui-babel-preset": "8.38.0",
41
+ "@instructure/ui-test-utils": "8.38.0",
42
42
  "moment-timezone": "^0.5.43"
43
43
  },
44
44
  "peerDependencies": {
@@ -2,7 +2,7 @@
2
2
  describes: TimeSelect
3
3
  ---
4
4
 
5
- `TimeSelect` component is a higher level abstraction of [Select](#Select) specifically for selecting time values. The list of possible values can be configured via the component's props. If you need to select times and dates, be sure to check out the documentation around [Time and Date patterns](#TimeDate).
5
+ `TimeSelect` component is a higher level abstraction of [Select](#Select) specifically for selecting time values. The list of possible values can be configured via the component's props.
6
6
 
7
7
  ### Uncontrolled
8
8