@instructure/ui-time-select 10.10.1-snapshot-5 → 10.10.1-snapshot-7
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 +5 -2
- package/es/TimeSelect/index.js +63 -47
- package/es/TimeSelect/props.js +3 -2
- package/lib/TimeSelect/index.js +63 -47
- package/lib/TimeSelect/props.js +3 -2
- package/package.json +13 -13
- package/src/TimeSelect/index.tsx +31 -9
- package/src/TimeSelect/props.ts +13 -2
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/TimeSelect/index.d.ts +3 -0
- package/types/TimeSelect/index.d.ts.map +1 -1
- package/types/TimeSelect/props.d.ts +9 -0
- package/types/TimeSelect/props.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
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.10.1-snapshot-
|
|
6
|
+
## [10.10.1-snapshot-7](https://github.com/instructure/instructure-ui/compare/v10.10.0...v10.10.1-snapshot-7) (2025-02-03)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **ui-time-select:** clear input field after setting an empty value ([1993282](https://github.com/instructure/instructure-ui/commit/19932824ebbcc5c927d000d353405ff72c4bf264))
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
|
package/es/TimeSelect/index.js
CHANGED
|
@@ -73,7 +73,8 @@ let TimeSelect = (_dec = withDeterministicId(), _dec2 = testable(), _dec(_class
|
|
|
73
73
|
// needs not to lose selectedOptionId in controlled mode otherwise it'd
|
|
74
74
|
// revert to the default or '' instead of the set value
|
|
75
75
|
selectedOptionId: this.isControlled ? this.state.selectedOptionId : void 0,
|
|
76
|
-
fireChangeOnBlur: void 0
|
|
76
|
+
fireChangeOnBlur: void 0,
|
|
77
|
+
isInputCleared: this.props.allowClearingSelection && value === ''
|
|
77
78
|
});
|
|
78
79
|
}
|
|
79
80
|
this.setState({
|
|
@@ -113,10 +114,11 @@ let TimeSelect = (_dec = withDeterministicId(), _dec2 = testable(), _dec(_class
|
|
|
113
114
|
// when pressing ESC. NOT called when an item is selected via Enter/click,
|
|
114
115
|
// (but in this case it will be called later when the input is blurred.)
|
|
115
116
|
this.handleBlurOrEsc = event => {
|
|
116
|
-
var _this$props$onHideOpt, _this$
|
|
117
|
+
var _this$props$onHideOpt, _this$props8;
|
|
117
118
|
const _this$state = this.state,
|
|
118
119
|
selectedOptionId = _this$state.selectedOptionId,
|
|
119
|
-
inputValue = _this$state.inputValue
|
|
120
|
+
inputValue = _this$state.inputValue,
|
|
121
|
+
isInputCleared = _this$state.isInputCleared;
|
|
120
122
|
let defaultValue = '';
|
|
121
123
|
if (this.props.defaultValue) {
|
|
122
124
|
const date = DateTime.parse(this.props.defaultValue, this.locale(), this.timezone());
|
|
@@ -124,14 +126,17 @@ let TimeSelect = (_dec = withDeterministicId(), _dec2 = testable(), _dec(_class
|
|
|
124
126
|
}
|
|
125
127
|
const selectedOption = this.getOption('id', selectedOptionId);
|
|
126
128
|
let newInputValue = defaultValue;
|
|
127
|
-
if (selectedOption) {
|
|
128
|
-
// If there is a selected option use its value in the input field.
|
|
129
|
-
newInputValue = selectedOption.label;
|
|
130
|
-
}
|
|
131
129
|
// if input was completely cleared, ensure it stays clear
|
|
132
130
|
// e.g. defaultValue defined, but no selection yet made
|
|
133
|
-
|
|
131
|
+
if (inputValue === '' && this.props.allowClearingSelection) {
|
|
134
132
|
newInputValue = '';
|
|
133
|
+
} else if (selectedOption) {
|
|
134
|
+
// If there is a selected option use its value in the input field.
|
|
135
|
+
newInputValue = selectedOption.label;
|
|
136
|
+
} else if (this.props.value) {
|
|
137
|
+
// If controlled and input is cleared and blurred after the first render, it should revert to value
|
|
138
|
+
const date = DateTime.parse(this.props.value, this.locale(), this.timezone());
|
|
139
|
+
newInputValue = this.props.format ? date.format(this.props.format) : date.toISOString();
|
|
135
140
|
}
|
|
136
141
|
this.setState(() => ({
|
|
137
142
|
isShowingOptions: false,
|
|
@@ -148,13 +153,22 @@ let TimeSelect = (_dec = withDeterministicId(), _dec2 = testable(), _dec(_class
|
|
|
148
153
|
value: this.state.fireChangeOnBlur.value.toISOString(),
|
|
149
154
|
inputText: this.state.fireChangeOnBlur.label
|
|
150
155
|
});
|
|
156
|
+
} else if (isInputCleared && event.key !== 'Escape' && this.props.allowClearingSelection) {
|
|
157
|
+
var _this$props$onChange2, _this$props7;
|
|
158
|
+
this.setState(() => ({
|
|
159
|
+
isInputCleared: false
|
|
160
|
+
}));
|
|
161
|
+
(_this$props$onChange2 = (_this$props7 = this.props).onChange) === null || _this$props$onChange2 === void 0 ? void 0 : _this$props$onChange2.call(_this$props7, event, {
|
|
162
|
+
value: '',
|
|
163
|
+
inputText: ''
|
|
164
|
+
});
|
|
151
165
|
}
|
|
152
166
|
// TODO only fire this if handleSelectOption was not called before.
|
|
153
|
-
(_this$props$onHideOpt = (_this$
|
|
167
|
+
(_this$props$onHideOpt = (_this$props8 = this.props).onHideOptions) === null || _this$props$onHideOpt === void 0 ? void 0 : _this$props$onHideOpt.call(_this$props8, event);
|
|
154
168
|
};
|
|
155
169
|
// Called when an option is selected via mouse click or Enter.
|
|
156
170
|
this.handleSelectOption = (event, data) => {
|
|
157
|
-
var _this$props$onHideOpt2, _this$
|
|
171
|
+
var _this$props$onHideOpt2, _this$props10;
|
|
158
172
|
if (data.id === this._emptyOptionId) {
|
|
159
173
|
this.setState({
|
|
160
174
|
isShowingOptions: false
|
|
@@ -182,13 +196,13 @@ let TimeSelect = (_dec = withDeterministicId(), _dec2 = testable(), _dec(_class
|
|
|
182
196
|
});
|
|
183
197
|
}
|
|
184
198
|
if (data.id !== currentSelectedOptionId) {
|
|
185
|
-
var _this$props$
|
|
186
|
-
(_this$props$
|
|
199
|
+
var _this$props$onChange3, _this$props9;
|
|
200
|
+
(_this$props$onChange3 = (_this$props9 = this.props).onChange) === null || _this$props$onChange3 === void 0 ? void 0 : _this$props$onChange3.call(_this$props9, event, {
|
|
187
201
|
value: selectedOption.value.toISOString(),
|
|
188
202
|
inputText: newInputValue
|
|
189
203
|
});
|
|
190
204
|
}
|
|
191
|
-
(_this$props$onHideOpt2 = (_this$
|
|
205
|
+
(_this$props$onHideOpt2 = (_this$props10 = this.props).onHideOptions) === null || _this$props$onHideOpt2 === void 0 ? void 0 : _this$props$onHideOpt2.call(_this$props10, event);
|
|
192
206
|
};
|
|
193
207
|
this.handleHighlightOption = (event, data) => {
|
|
194
208
|
if (data.id === this._emptyOptionId) return;
|
|
@@ -306,15 +320,16 @@ let TimeSelect = (_dec = withDeterministicId(), _dec2 = testable(), _dec(_class
|
|
|
306
320
|
filteredOptions: initialOptions.length > 288 ? initialOptions.filter(opt => opt.value.minute() % this.props.step === 0) : initialOptions,
|
|
307
321
|
isShowingOptions: false,
|
|
308
322
|
highlightedOptionId: initialSelection ? initialSelection.id : void 0,
|
|
309
|
-
selectedOptionId: initialSelection ? initialSelection.id : void 0
|
|
323
|
+
selectedOptionId: initialSelection ? initialSelection.id : void 0,
|
|
324
|
+
isInputCleared: false
|
|
310
325
|
};
|
|
311
326
|
}
|
|
312
327
|
getInitialOption(options) {
|
|
313
|
-
const _this$
|
|
314
|
-
value = _this$
|
|
315
|
-
defaultValue = _this$
|
|
316
|
-
defaultToFirstOption = _this$
|
|
317
|
-
format = _this$
|
|
328
|
+
const _this$props11 = this.props,
|
|
329
|
+
value = _this$props11.value,
|
|
330
|
+
defaultValue = _this$props11.defaultValue,
|
|
331
|
+
defaultToFirstOption = _this$props11.defaultToFirstOption,
|
|
332
|
+
format = _this$props11.format;
|
|
318
333
|
const initialValue = value || defaultValue;
|
|
319
334
|
if (typeof initialValue === 'string') {
|
|
320
335
|
const date = DateTime.parse(initialValue, this.locale(), this.timezone());
|
|
@@ -423,33 +438,33 @@ let TimeSelect = (_dec = withDeterministicId(), _dec2 = testable(), _dec(_class
|
|
|
423
438
|
}, callRenderProp(this.props.renderEmptyOption));
|
|
424
439
|
}
|
|
425
440
|
render() {
|
|
426
|
-
const _this$
|
|
427
|
-
value = _this$
|
|
428
|
-
defaultValue = _this$
|
|
429
|
-
placeholder = _this$
|
|
430
|
-
renderLabel = _this$
|
|
431
|
-
inputRef = _this$
|
|
432
|
-
id = _this$
|
|
433
|
-
listRef = _this$
|
|
434
|
-
renderBeforeInput = _this$
|
|
435
|
-
renderAfterInput = _this$
|
|
436
|
-
isRequired = _this$
|
|
437
|
-
isInline = _this$
|
|
438
|
-
width = _this$
|
|
439
|
-
format = _this$
|
|
440
|
-
step = _this$
|
|
441
|
-
optionsMaxWidth = _this$
|
|
442
|
-
visibleOptionsCount = _this$
|
|
443
|
-
messages = _this$
|
|
444
|
-
placement = _this$
|
|
445
|
-
constrain = _this$
|
|
446
|
-
onFocus = _this$
|
|
447
|
-
onShowOptions = _this$
|
|
448
|
-
onHideOptions = _this$
|
|
449
|
-
onInputChange = _this$
|
|
450
|
-
onKeyDown = _this$
|
|
451
|
-
mountNode = _this$
|
|
452
|
-
rest = _objectWithoutProperties(_this$
|
|
441
|
+
const _this$props12 = this.props,
|
|
442
|
+
value = _this$props12.value,
|
|
443
|
+
defaultValue = _this$props12.defaultValue,
|
|
444
|
+
placeholder = _this$props12.placeholder,
|
|
445
|
+
renderLabel = _this$props12.renderLabel,
|
|
446
|
+
inputRef = _this$props12.inputRef,
|
|
447
|
+
id = _this$props12.id,
|
|
448
|
+
listRef = _this$props12.listRef,
|
|
449
|
+
renderBeforeInput = _this$props12.renderBeforeInput,
|
|
450
|
+
renderAfterInput = _this$props12.renderAfterInput,
|
|
451
|
+
isRequired = _this$props12.isRequired,
|
|
452
|
+
isInline = _this$props12.isInline,
|
|
453
|
+
width = _this$props12.width,
|
|
454
|
+
format = _this$props12.format,
|
|
455
|
+
step = _this$props12.step,
|
|
456
|
+
optionsMaxWidth = _this$props12.optionsMaxWidth,
|
|
457
|
+
visibleOptionsCount = _this$props12.visibleOptionsCount,
|
|
458
|
+
messages = _this$props12.messages,
|
|
459
|
+
placement = _this$props12.placement,
|
|
460
|
+
constrain = _this$props12.constrain,
|
|
461
|
+
onFocus = _this$props12.onFocus,
|
|
462
|
+
onShowOptions = _this$props12.onShowOptions,
|
|
463
|
+
onHideOptions = _this$props12.onHideOptions,
|
|
464
|
+
onInputChange = _this$props12.onInputChange,
|
|
465
|
+
onKeyDown = _this$props12.onKeyDown,
|
|
466
|
+
mountNode = _this$props12.mountNode,
|
|
467
|
+
rest = _objectWithoutProperties(_this$props12, _excluded);
|
|
453
468
|
const _this$state5 = this.state,
|
|
454
469
|
inputValue = _this$state5.inputValue,
|
|
455
470
|
isShowingOptions = _this$state5.isShowingOptions;
|
|
@@ -495,7 +510,8 @@ let TimeSelect = (_dec = withDeterministicId(), _dec2 = testable(), _dec(_class
|
|
|
495
510
|
placement: 'bottom stretch',
|
|
496
511
|
constrain: 'window',
|
|
497
512
|
renderEmptyOption: '---',
|
|
498
|
-
allowNonStepInput: false
|
|
513
|
+
allowNonStepInput: false,
|
|
514
|
+
allowClearingSelection: false
|
|
499
515
|
}, _TimeSelect.contextType = ApplyLocaleContext, _TimeSelect)) || _class) || _class);
|
|
500
516
|
export { TimeSelect };
|
|
501
517
|
export default TimeSelect;
|
package/es/TimeSelect/props.js
CHANGED
|
@@ -59,7 +59,8 @@ const propTypes = {
|
|
|
59
59
|
locale: PropTypes.string,
|
|
60
60
|
timezone: PropTypes.string,
|
|
61
61
|
allowNonStepInput: PropTypes.bool,
|
|
62
|
-
onInputChange: PropTypes.func
|
|
62
|
+
onInputChange: PropTypes.func,
|
|
63
|
+
allowClearingSelection: PropTypes.bool
|
|
63
64
|
};
|
|
64
|
-
const allowedProps = ['renderLabel', 'defaultToFirstOption', 'value', 'defaultValue', 'id', 'format', 'step', 'interaction', 'placeholder', 'isRequired', 'isInline', 'width', 'optionsMaxWidth', 'mountNode', 'visibleOptionsCount', 'messages', 'placement', 'constrain', 'onChange', 'onFocus', 'onBlur', 'onShowOptions', 'onHideOptions', 'inputRef', 'listRef', 'renderEmptyOption', 'renderBeforeInput', 'renderAfterInput', 'locale', 'timezone', 'allowNonStepInput', 'onInputChange'];
|
|
65
|
+
const allowedProps = ['renderLabel', 'defaultToFirstOption', 'value', 'defaultValue', 'id', 'format', 'step', 'interaction', 'placeholder', 'isRequired', 'isInline', 'width', 'optionsMaxWidth', 'mountNode', 'visibleOptionsCount', 'messages', 'placement', 'constrain', 'onChange', 'onFocus', 'onBlur', 'onShowOptions', 'onHideOptions', 'inputRef', 'listRef', 'renderEmptyOption', 'renderBeforeInput', 'renderAfterInput', 'locale', 'timezone', 'allowNonStepInput', 'onInputChange', 'allowClearingSelection'];
|
|
65
66
|
export { propTypes, allowedProps };
|
package/lib/TimeSelect/index.js
CHANGED
|
@@ -85,7 +85,8 @@ let TimeSelect = exports.TimeSelect = (_dec = (0, _withDeterministicId.withDeter
|
|
|
85
85
|
// needs not to lose selectedOptionId in controlled mode otherwise it'd
|
|
86
86
|
// revert to the default or '' instead of the set value
|
|
87
87
|
selectedOptionId: this.isControlled ? this.state.selectedOptionId : void 0,
|
|
88
|
-
fireChangeOnBlur: void 0
|
|
88
|
+
fireChangeOnBlur: void 0,
|
|
89
|
+
isInputCleared: this.props.allowClearingSelection && value === ''
|
|
89
90
|
});
|
|
90
91
|
}
|
|
91
92
|
this.setState({
|
|
@@ -125,10 +126,11 @@ let TimeSelect = exports.TimeSelect = (_dec = (0, _withDeterministicId.withDeter
|
|
|
125
126
|
// when pressing ESC. NOT called when an item is selected via Enter/click,
|
|
126
127
|
// (but in this case it will be called later when the input is blurred.)
|
|
127
128
|
this.handleBlurOrEsc = event => {
|
|
128
|
-
var _this$props$onHideOpt, _this$
|
|
129
|
+
var _this$props$onHideOpt, _this$props8;
|
|
129
130
|
const _this$state = this.state,
|
|
130
131
|
selectedOptionId = _this$state.selectedOptionId,
|
|
131
|
-
inputValue = _this$state.inputValue
|
|
132
|
+
inputValue = _this$state.inputValue,
|
|
133
|
+
isInputCleared = _this$state.isInputCleared;
|
|
132
134
|
let defaultValue = '';
|
|
133
135
|
if (this.props.defaultValue) {
|
|
134
136
|
const date = _DateTime.DateTime.parse(this.props.defaultValue, this.locale(), this.timezone());
|
|
@@ -136,14 +138,17 @@ let TimeSelect = exports.TimeSelect = (_dec = (0, _withDeterministicId.withDeter
|
|
|
136
138
|
}
|
|
137
139
|
const selectedOption = this.getOption('id', selectedOptionId);
|
|
138
140
|
let newInputValue = defaultValue;
|
|
139
|
-
if (selectedOption) {
|
|
140
|
-
// If there is a selected option use its value in the input field.
|
|
141
|
-
newInputValue = selectedOption.label;
|
|
142
|
-
}
|
|
143
141
|
// if input was completely cleared, ensure it stays clear
|
|
144
142
|
// e.g. defaultValue defined, but no selection yet made
|
|
145
|
-
|
|
143
|
+
if (inputValue === '' && this.props.allowClearingSelection) {
|
|
146
144
|
newInputValue = '';
|
|
145
|
+
} else if (selectedOption) {
|
|
146
|
+
// If there is a selected option use its value in the input field.
|
|
147
|
+
newInputValue = selectedOption.label;
|
|
148
|
+
} else if (this.props.value) {
|
|
149
|
+
// If controlled and input is cleared and blurred after the first render, it should revert to value
|
|
150
|
+
const date = _DateTime.DateTime.parse(this.props.value, this.locale(), this.timezone());
|
|
151
|
+
newInputValue = this.props.format ? date.format(this.props.format) : date.toISOString();
|
|
147
152
|
}
|
|
148
153
|
this.setState(() => ({
|
|
149
154
|
isShowingOptions: false,
|
|
@@ -160,13 +165,22 @@ let TimeSelect = exports.TimeSelect = (_dec = (0, _withDeterministicId.withDeter
|
|
|
160
165
|
value: this.state.fireChangeOnBlur.value.toISOString(),
|
|
161
166
|
inputText: this.state.fireChangeOnBlur.label
|
|
162
167
|
});
|
|
168
|
+
} else if (isInputCleared && event.key !== 'Escape' && this.props.allowClearingSelection) {
|
|
169
|
+
var _this$props$onChange2, _this$props7;
|
|
170
|
+
this.setState(() => ({
|
|
171
|
+
isInputCleared: false
|
|
172
|
+
}));
|
|
173
|
+
(_this$props$onChange2 = (_this$props7 = this.props).onChange) === null || _this$props$onChange2 === void 0 ? void 0 : _this$props$onChange2.call(_this$props7, event, {
|
|
174
|
+
value: '',
|
|
175
|
+
inputText: ''
|
|
176
|
+
});
|
|
163
177
|
}
|
|
164
178
|
// TODO only fire this if handleSelectOption was not called before.
|
|
165
|
-
(_this$props$onHideOpt = (_this$
|
|
179
|
+
(_this$props$onHideOpt = (_this$props8 = this.props).onHideOptions) === null || _this$props$onHideOpt === void 0 ? void 0 : _this$props$onHideOpt.call(_this$props8, event);
|
|
166
180
|
};
|
|
167
181
|
// Called when an option is selected via mouse click or Enter.
|
|
168
182
|
this.handleSelectOption = (event, data) => {
|
|
169
|
-
var _this$props$onHideOpt2, _this$
|
|
183
|
+
var _this$props$onHideOpt2, _this$props10;
|
|
170
184
|
if (data.id === this._emptyOptionId) {
|
|
171
185
|
this.setState({
|
|
172
186
|
isShowingOptions: false
|
|
@@ -194,13 +208,13 @@ let TimeSelect = exports.TimeSelect = (_dec = (0, _withDeterministicId.withDeter
|
|
|
194
208
|
});
|
|
195
209
|
}
|
|
196
210
|
if (data.id !== currentSelectedOptionId) {
|
|
197
|
-
var _this$props$
|
|
198
|
-
(_this$props$
|
|
211
|
+
var _this$props$onChange3, _this$props9;
|
|
212
|
+
(_this$props$onChange3 = (_this$props9 = this.props).onChange) === null || _this$props$onChange3 === void 0 ? void 0 : _this$props$onChange3.call(_this$props9, event, {
|
|
199
213
|
value: selectedOption.value.toISOString(),
|
|
200
214
|
inputText: newInputValue
|
|
201
215
|
});
|
|
202
216
|
}
|
|
203
|
-
(_this$props$onHideOpt2 = (_this$
|
|
217
|
+
(_this$props$onHideOpt2 = (_this$props10 = this.props).onHideOptions) === null || _this$props$onHideOpt2 === void 0 ? void 0 : _this$props$onHideOpt2.call(_this$props10, event);
|
|
204
218
|
};
|
|
205
219
|
this.handleHighlightOption = (event, data) => {
|
|
206
220
|
if (data.id === this._emptyOptionId) return;
|
|
@@ -318,15 +332,16 @@ let TimeSelect = exports.TimeSelect = (_dec = (0, _withDeterministicId.withDeter
|
|
|
318
332
|
filteredOptions: initialOptions.length > 288 ? initialOptions.filter(opt => opt.value.minute() % this.props.step === 0) : initialOptions,
|
|
319
333
|
isShowingOptions: false,
|
|
320
334
|
highlightedOptionId: initialSelection ? initialSelection.id : void 0,
|
|
321
|
-
selectedOptionId: initialSelection ? initialSelection.id : void 0
|
|
335
|
+
selectedOptionId: initialSelection ? initialSelection.id : void 0,
|
|
336
|
+
isInputCleared: false
|
|
322
337
|
};
|
|
323
338
|
}
|
|
324
339
|
getInitialOption(options) {
|
|
325
|
-
const _this$
|
|
326
|
-
value = _this$
|
|
327
|
-
defaultValue = _this$
|
|
328
|
-
defaultToFirstOption = _this$
|
|
329
|
-
format = _this$
|
|
340
|
+
const _this$props11 = this.props,
|
|
341
|
+
value = _this$props11.value,
|
|
342
|
+
defaultValue = _this$props11.defaultValue,
|
|
343
|
+
defaultToFirstOption = _this$props11.defaultToFirstOption,
|
|
344
|
+
format = _this$props11.format;
|
|
330
345
|
const initialValue = value || defaultValue;
|
|
331
346
|
if (typeof initialValue === 'string') {
|
|
332
347
|
const date = _DateTime.DateTime.parse(initialValue, this.locale(), this.timezone());
|
|
@@ -435,33 +450,33 @@ let TimeSelect = exports.TimeSelect = (_dec = (0, _withDeterministicId.withDeter
|
|
|
435
450
|
}, (0, _callRenderProp.callRenderProp)(this.props.renderEmptyOption));
|
|
436
451
|
}
|
|
437
452
|
render() {
|
|
438
|
-
const _this$
|
|
439
|
-
value = _this$
|
|
440
|
-
defaultValue = _this$
|
|
441
|
-
placeholder = _this$
|
|
442
|
-
renderLabel = _this$
|
|
443
|
-
inputRef = _this$
|
|
444
|
-
id = _this$
|
|
445
|
-
listRef = _this$
|
|
446
|
-
renderBeforeInput = _this$
|
|
447
|
-
renderAfterInput = _this$
|
|
448
|
-
isRequired = _this$
|
|
449
|
-
isInline = _this$
|
|
450
|
-
width = _this$
|
|
451
|
-
format = _this$
|
|
452
|
-
step = _this$
|
|
453
|
-
optionsMaxWidth = _this$
|
|
454
|
-
visibleOptionsCount = _this$
|
|
455
|
-
messages = _this$
|
|
456
|
-
placement = _this$
|
|
457
|
-
constrain = _this$
|
|
458
|
-
onFocus = _this$
|
|
459
|
-
onShowOptions = _this$
|
|
460
|
-
onHideOptions = _this$
|
|
461
|
-
onInputChange = _this$
|
|
462
|
-
onKeyDown = _this$
|
|
463
|
-
mountNode = _this$
|
|
464
|
-
rest = (0, _objectWithoutProperties2.default)(_this$
|
|
453
|
+
const _this$props12 = this.props,
|
|
454
|
+
value = _this$props12.value,
|
|
455
|
+
defaultValue = _this$props12.defaultValue,
|
|
456
|
+
placeholder = _this$props12.placeholder,
|
|
457
|
+
renderLabel = _this$props12.renderLabel,
|
|
458
|
+
inputRef = _this$props12.inputRef,
|
|
459
|
+
id = _this$props12.id,
|
|
460
|
+
listRef = _this$props12.listRef,
|
|
461
|
+
renderBeforeInput = _this$props12.renderBeforeInput,
|
|
462
|
+
renderAfterInput = _this$props12.renderAfterInput,
|
|
463
|
+
isRequired = _this$props12.isRequired,
|
|
464
|
+
isInline = _this$props12.isInline,
|
|
465
|
+
width = _this$props12.width,
|
|
466
|
+
format = _this$props12.format,
|
|
467
|
+
step = _this$props12.step,
|
|
468
|
+
optionsMaxWidth = _this$props12.optionsMaxWidth,
|
|
469
|
+
visibleOptionsCount = _this$props12.visibleOptionsCount,
|
|
470
|
+
messages = _this$props12.messages,
|
|
471
|
+
placement = _this$props12.placement,
|
|
472
|
+
constrain = _this$props12.constrain,
|
|
473
|
+
onFocus = _this$props12.onFocus,
|
|
474
|
+
onShowOptions = _this$props12.onShowOptions,
|
|
475
|
+
onHideOptions = _this$props12.onHideOptions,
|
|
476
|
+
onInputChange = _this$props12.onInputChange,
|
|
477
|
+
onKeyDown = _this$props12.onKeyDown,
|
|
478
|
+
mountNode = _this$props12.mountNode,
|
|
479
|
+
rest = (0, _objectWithoutProperties2.default)(_this$props12, _excluded);
|
|
465
480
|
const _this$state5 = this.state,
|
|
466
481
|
inputValue = _this$state5.inputValue,
|
|
467
482
|
isShowingOptions = _this$state5.isShowingOptions;
|
|
@@ -507,6 +522,7 @@ let TimeSelect = exports.TimeSelect = (_dec = (0, _withDeterministicId.withDeter
|
|
|
507
522
|
placement: 'bottom stretch',
|
|
508
523
|
constrain: 'window',
|
|
509
524
|
renderEmptyOption: '---',
|
|
510
|
-
allowNonStepInput: false
|
|
525
|
+
allowNonStepInput: false,
|
|
526
|
+
allowClearingSelection: false
|
|
511
527
|
}, _TimeSelect.contextType = _ApplyLocaleContext.ApplyLocaleContext, _TimeSelect)) || _class) || _class);
|
|
512
528
|
var _default = exports.default = TimeSelect;
|
package/lib/TimeSelect/props.js
CHANGED
|
@@ -66,6 +66,7 @@ const propTypes = exports.propTypes = {
|
|
|
66
66
|
locale: _propTypes.default.string,
|
|
67
67
|
timezone: _propTypes.default.string,
|
|
68
68
|
allowNonStepInput: _propTypes.default.bool,
|
|
69
|
-
onInputChange: _propTypes.default.func
|
|
69
|
+
onInputChange: _propTypes.default.func,
|
|
70
|
+
allowClearingSelection: _propTypes.default.bool
|
|
70
71
|
};
|
|
71
|
-
const allowedProps = exports.allowedProps = ['renderLabel', 'defaultToFirstOption', 'value', 'defaultValue', 'id', 'format', 'step', 'interaction', 'placeholder', 'isRequired', 'isInline', 'width', 'optionsMaxWidth', 'mountNode', 'visibleOptionsCount', 'messages', 'placement', 'constrain', 'onChange', 'onFocus', 'onBlur', 'onShowOptions', 'onHideOptions', 'inputRef', 'listRef', 'renderEmptyOption', 'renderBeforeInput', 'renderAfterInput', 'locale', 'timezone', 'allowNonStepInput', 'onInputChange'];
|
|
72
|
+
const allowedProps = exports.allowedProps = ['renderLabel', 'defaultToFirstOption', 'value', 'defaultValue', 'id', 'format', 'step', 'interaction', 'placeholder', 'isRequired', 'isInline', 'width', 'optionsMaxWidth', 'mountNode', 'visibleOptionsCount', 'messages', 'placement', 'constrain', 'onChange', 'onFocus', 'onBlur', 'onShowOptions', 'onHideOptions', 'inputRef', 'listRef', 'renderEmptyOption', 'renderBeforeInput', 'renderAfterInput', 'locale', 'timezone', 'allowNonStepInput', 'onInputChange', 'allowClearingSelection'];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-time-select",
|
|
3
|
-
"version": "10.10.1-snapshot-
|
|
3
|
+
"version": "10.10.1-snapshot-7",
|
|
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.26.0",
|
|
27
|
-
"@instructure/shared-types": "10.10.1-snapshot-
|
|
28
|
-
"@instructure/ui-form-field": "10.10.1-snapshot-
|
|
29
|
-
"@instructure/ui-i18n": "10.10.1-snapshot-
|
|
30
|
-
"@instructure/ui-position": "10.10.1-snapshot-
|
|
31
|
-
"@instructure/ui-prop-types": "10.10.1-snapshot-
|
|
32
|
-
"@instructure/ui-react-utils": "10.10.1-snapshot-
|
|
33
|
-
"@instructure/ui-select": "10.10.1-snapshot-
|
|
34
|
-
"@instructure/ui-testable": "10.10.1-snapshot-
|
|
35
|
-
"@instructure/ui-utils": "10.10.1-snapshot-
|
|
27
|
+
"@instructure/shared-types": "10.10.1-snapshot-7",
|
|
28
|
+
"@instructure/ui-form-field": "10.10.1-snapshot-7",
|
|
29
|
+
"@instructure/ui-i18n": "10.10.1-snapshot-7",
|
|
30
|
+
"@instructure/ui-position": "10.10.1-snapshot-7",
|
|
31
|
+
"@instructure/ui-prop-types": "10.10.1-snapshot-7",
|
|
32
|
+
"@instructure/ui-react-utils": "10.10.1-snapshot-7",
|
|
33
|
+
"@instructure/ui-select": "10.10.1-snapshot-7",
|
|
34
|
+
"@instructure/ui-testable": "10.10.1-snapshot-7",
|
|
35
|
+
"@instructure/ui-utils": "10.10.1-snapshot-7",
|
|
36
36
|
"prop-types": "^15.8.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@instructure/ui-axe-check": "10.10.1-snapshot-
|
|
40
|
-
"@instructure/ui-babel-preset": "10.10.1-snapshot-
|
|
41
|
-
"@instructure/ui-test-utils": "10.10.1-snapshot-
|
|
39
|
+
"@instructure/ui-axe-check": "10.10.1-snapshot-7",
|
|
40
|
+
"@instructure/ui-babel-preset": "10.10.1-snapshot-7",
|
|
41
|
+
"@instructure/ui-test-utils": "10.10.1-snapshot-7",
|
|
42
42
|
"@testing-library/jest-dom": "^6.6.3",
|
|
43
43
|
"@testing-library/react": "^16.0.1",
|
|
44
44
|
"@testing-library/user-event": "^14.5.2",
|
package/src/TimeSelect/index.tsx
CHANGED
|
@@ -74,7 +74,8 @@ class TimeSelect extends Component<TimeSelectProps, TimeSelectState> {
|
|
|
74
74
|
placement: 'bottom stretch',
|
|
75
75
|
constrain: 'window',
|
|
76
76
|
renderEmptyOption: '---',
|
|
77
|
-
allowNonStepInput: false
|
|
77
|
+
allowNonStepInput: false,
|
|
78
|
+
allowClearingSelection: false
|
|
78
79
|
}
|
|
79
80
|
static contextType = ApplyLocaleContext
|
|
80
81
|
|
|
@@ -220,7 +221,8 @@ class TimeSelect extends Component<TimeSelectProps, TimeSelectState> {
|
|
|
220
221
|
: initialOptions,
|
|
221
222
|
isShowingOptions: false,
|
|
222
223
|
highlightedOptionId: initialSelection ? initialSelection.id : undefined,
|
|
223
|
-
selectedOptionId: initialSelection ? initialSelection.id : undefined
|
|
224
|
+
selectedOptionId: initialSelection ? initialSelection.id : undefined,
|
|
225
|
+
isInputCleared: false
|
|
224
226
|
}
|
|
225
227
|
}
|
|
226
228
|
|
|
@@ -338,7 +340,8 @@ class TimeSelect extends Component<TimeSelectProps, TimeSelectState> {
|
|
|
338
340
|
selectedOptionId: this.isControlled
|
|
339
341
|
? this.state.selectedOptionId
|
|
340
342
|
: undefined,
|
|
341
|
-
fireChangeOnBlur: undefined
|
|
343
|
+
fireChangeOnBlur: undefined,
|
|
344
|
+
isInputCleared: this.props.allowClearingSelection && value === ''
|
|
342
345
|
})
|
|
343
346
|
}
|
|
344
347
|
this.setState({
|
|
@@ -386,7 +389,7 @@ class TimeSelect extends Component<TimeSelectProps, TimeSelectState> {
|
|
|
386
389
|
// when pressing ESC. NOT called when an item is selected via Enter/click,
|
|
387
390
|
// (but in this case it will be called later when the input is blurred.)
|
|
388
391
|
handleBlurOrEsc: SelectProps['onRequestHideOptions'] = (event) => {
|
|
389
|
-
const { selectedOptionId, inputValue } = this.state
|
|
392
|
+
const { selectedOptionId, inputValue, isInputCleared } = this.state
|
|
390
393
|
let defaultValue = ''
|
|
391
394
|
if (this.props.defaultValue) {
|
|
392
395
|
const date = DateTime.parse(
|
|
@@ -400,14 +403,23 @@ class TimeSelect extends Component<TimeSelectProps, TimeSelectState> {
|
|
|
400
403
|
}
|
|
401
404
|
const selectedOption = this.getOption('id', selectedOptionId)
|
|
402
405
|
let newInputValue = defaultValue
|
|
403
|
-
if (selectedOption) {
|
|
404
|
-
// If there is a selected option use its value in the input field.
|
|
405
|
-
newInputValue = selectedOption.label
|
|
406
|
-
}
|
|
407
406
|
// if input was completely cleared, ensure it stays clear
|
|
408
407
|
// e.g. defaultValue defined, but no selection yet made
|
|
409
|
-
|
|
408
|
+
if (inputValue === '' && this.props.allowClearingSelection) {
|
|
410
409
|
newInputValue = ''
|
|
410
|
+
} else if (selectedOption) {
|
|
411
|
+
// If there is a selected option use its value in the input field.
|
|
412
|
+
newInputValue = selectedOption.label
|
|
413
|
+
} else if (this.props.value) {
|
|
414
|
+
// If controlled and input is cleared and blurred after the first render, it should revert to value
|
|
415
|
+
const date = DateTime.parse(
|
|
416
|
+
this.props.value,
|
|
417
|
+
this.locale(),
|
|
418
|
+
this.timezone()
|
|
419
|
+
)
|
|
420
|
+
newInputValue = this.props.format
|
|
421
|
+
? date.format(this.props.format)
|
|
422
|
+
: date.toISOString()
|
|
411
423
|
}
|
|
412
424
|
this.setState(() => ({
|
|
413
425
|
isShowingOptions: false,
|
|
@@ -421,6 +433,16 @@ class TimeSelect extends Component<TimeSelectProps, TimeSelectState> {
|
|
|
421
433
|
value: this.state.fireChangeOnBlur.value.toISOString(),
|
|
422
434
|
inputText: this.state.fireChangeOnBlur.label
|
|
423
435
|
})
|
|
436
|
+
} else if (
|
|
437
|
+
isInputCleared &&
|
|
438
|
+
(event as any).key !== 'Escape' &&
|
|
439
|
+
this.props.allowClearingSelection
|
|
440
|
+
) {
|
|
441
|
+
this.setState(() => ({ isInputCleared: false }))
|
|
442
|
+
this.props.onChange?.(event, {
|
|
443
|
+
value: '',
|
|
444
|
+
inputText: ''
|
|
445
|
+
})
|
|
424
446
|
}
|
|
425
447
|
// TODO only fire this if handleSelectOption was not called before.
|
|
426
448
|
this.props.onHideOptions?.(event)
|
package/src/TimeSelect/props.ts
CHANGED
|
@@ -244,6 +244,11 @@ type TimeSelectOwnProps = {
|
|
|
244
244
|
*/
|
|
245
245
|
valueAsISOString?: string
|
|
246
246
|
) => void
|
|
247
|
+
/**
|
|
248
|
+
* Whether to allow for the user to clear the selected option in the input field.
|
|
249
|
+
* If `false`, the input field will return the last selected option after the input is cleared and loses focus.
|
|
250
|
+
*/
|
|
251
|
+
allowClearingSelection: boolean
|
|
247
252
|
}
|
|
248
253
|
|
|
249
254
|
const propTypes: PropValidators<PropKeys> = {
|
|
@@ -278,7 +283,8 @@ const propTypes: PropValidators<PropKeys> = {
|
|
|
278
283
|
locale: PropTypes.string,
|
|
279
284
|
timezone: PropTypes.string,
|
|
280
285
|
allowNonStepInput: PropTypes.bool,
|
|
281
|
-
onInputChange: PropTypes.func
|
|
286
|
+
onInputChange: PropTypes.func,
|
|
287
|
+
allowClearingSelection: PropTypes.bool
|
|
282
288
|
}
|
|
283
289
|
|
|
284
290
|
const allowedProps: AllowedPropKeys = [
|
|
@@ -313,7 +319,8 @@ const allowedProps: AllowedPropKeys = [
|
|
|
313
319
|
'locale',
|
|
314
320
|
'timezone',
|
|
315
321
|
'allowNonStepInput',
|
|
316
|
-
'onInputChange'
|
|
322
|
+
'onInputChange',
|
|
323
|
+
'allowClearingSelection'
|
|
317
324
|
]
|
|
318
325
|
|
|
319
326
|
type TimeSelectOptions = {
|
|
@@ -356,6 +363,10 @@ type TimeSelectState = {
|
|
|
356
363
|
* fire onChange event when the popup closes?
|
|
357
364
|
*/
|
|
358
365
|
fireChangeOnBlur?: TimeSelectOptions
|
|
366
|
+
/**
|
|
367
|
+
* Whether to selected option is cleared
|
|
368
|
+
*/
|
|
369
|
+
isInputCleared: boolean
|
|
359
370
|
}
|
|
360
371
|
|
|
361
372
|
export type { TimeSelectProps, TimeSelectState, TimeSelectOptions }
|