@commercetools-uikit/time-input 14.0.1 → 14.0.4

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/README.md CHANGED
@@ -49,23 +49,15 @@ export default Example;
49
49
  | `name` | `string` | | | Used as HTML name of the input component. |
50
50
  | `autoComplete` | `string` | | | Used as HTML autocomplete of the input component. |
51
51
  | `value` | `string` | | | Value of the input |
52
- | `onChange` | `Function`<br/>[See signature.](#signature-onChange) || | Called with an event holding the new value. |
53
- | `onBlur` | `FocusEventHandler` | | | Called when input is blurred&#xA;<br/> |
54
- | `onFocus` | `FocusEventHandler` | | | Called when input is focused&#xA;<br/>&#xA;Signature: `(event) => void` |
52
+ | `onChange` | `ChangeEventHandler` | | | Called with an event holding the new value. |
53
+ | `onBlur` | `FocusEventHandler` | | | Called when input is blurred |
54
+ | `onFocus` | `FocusEventHandler` | | | Called when input is focused |
55
55
  | `isAutofocussed` | `boolean` | | | Focus the input on initial render |
56
56
  | `isDisabled` | `boolean` | | | Indicates that the input cannot be modified (e.g not authorized, or changes currently saving). |
57
57
  | `placeholder` | `string` | | | Placeholder text for the input |
58
58
  | `hasError` | `boolean` | | | Indicates if the input has invalid values |
59
59
  | `isReadOnly` | `boolean` | | | Indicates that the field is displaying read-only content |
60
60
 
61
- ## Signatures
62
-
63
- ### Signature `onChange`
64
-
65
- ```ts
66
- (event: TEvent) => void
67
- ```
68
-
69
61
  ## `value`
70
62
 
71
63
  The value after the field has been blurred is always either valid or an empty string. The input automatically formats the value on blur by calling `onChange` with the formatted value - or with an empty value in case the input was not a valid time.
@@ -6,10 +6,10 @@ var _defineProperty = require('@babel/runtime-corejs3/helpers/defineProperty');
6
6
  var _pt = require('prop-types');
7
7
  var _padStartInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/pad-start');
8
8
  var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
9
+ var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
9
10
  var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
10
11
  var _Object$getOwnPropertySymbols = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols');
11
12
  var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/filter');
12
- var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
13
13
  var _forEachInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/for-each');
14
14
  var _Object$getOwnPropertyDescriptors = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors');
15
15
  var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/object/define-properties');
@@ -33,10 +33,10 @@ function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e };
33
33
  var _pt__default = /*#__PURE__*/_interopDefault(_pt);
34
34
  var _padStartInstanceProperty__default = /*#__PURE__*/_interopDefault(_padStartInstanceProperty);
35
35
  var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
36
+ var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
36
37
  var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
37
38
  var _Object$getOwnPropertySymbols__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertySymbols);
38
39
  var _filterInstanceProperty__default = /*#__PURE__*/_interopDefault(_filterInstanceProperty);
39
- var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
40
40
  var _forEachInstanceProperty__default = /*#__PURE__*/_interopDefault(_forEachInstanceProperty);
41
41
  var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptors);
42
42
  var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
@@ -190,14 +190,14 @@ ClearSection.propTypes = process.env.NODE_ENV !== "production" ? {
190
190
  onClear: _pt__default["default"].func.isRequired
191
191
  } : {};
192
192
  ClearSection.displayName = 'ClearSection';
193
-
194
- var TimeInputBody = function TimeInputBody(props) {
193
+ var TimeInputBody = /*#__PURE__*/react$1.forwardRef(function (props, ref) {
195
194
  var theme = react.useTheme();
196
195
  return jsxRuntime.jsx(Inline__default["default"], {
197
196
  alignItems: "center",
198
197
  children: jsxRuntime.jsxs(StyledInputContainer, {
199
198
  css: getInputContainerStyles(props, theme),
200
199
  children: [jsxRuntime.jsx("input", _objectSpread$1(_objectSpread$1({
200
+ ref: ref,
201
201
  css: getTimeInputStyles(props),
202
202
  id: props.id,
203
203
  name: props.name,
@@ -232,11 +232,7 @@ var TimeInputBody = function TimeInputBody(props) {
232
232
  })]
233
233
  })
234
234
  });
235
- };
236
-
237
- TimeInputBody.propTypes = process.env.NODE_ENV !== "production" ? {
238
- onClear: _pt__default["default"].func.isRequired
239
- } : {};
235
+ });
240
236
  TimeInputBody.displayName = 'TimeInputBody';
241
237
  var TimeInputBody$1 = TimeInputBody;
242
238
 
@@ -278,56 +274,72 @@ var format24hr = function format24hr(_ref) {
278
274
 
279
275
  var hasMilliseconds = function hasMilliseconds(parsedTime) {
280
276
  return parsedTime.milliseconds !== 0;
277
+ }; // Calling `eventTarget.dispatchEvent` does not natively work in React.
278
+ // Instead, we need to grab the element value setter, set the value, and dispatch a change event.
279
+
280
+
281
+ var dispatchReactChangeEvent = function dispatchReactChangeEvent(node, value) {
282
+ var _Object$getOwnPropert;
283
+
284
+ var setValue = (_Object$getOwnPropert = _Object$getOwnPropertyDescriptor__default["default"](node.constructor.prototype, 'value')) === null || _Object$getOwnPropert === void 0 ? void 0 : _Object$getOwnPropert.set;
285
+ setValue === null || setValue === void 0 ? void 0 : setValue.call(node, value);
286
+ node.dispatchEvent(new Event('change', {
287
+ bubbles: true
288
+ }));
281
289
  };
282
290
 
283
291
  var TimeInput = function TimeInput(props) {
284
292
  var id = hooks.useFieldId(props.id, sequentialId);
285
293
  var intl = reactIntl.useIntl();
286
- var prevLocale = hooks.usePrevious(intl.locale);
287
- var name = props.name,
288
- value = props.value,
289
- onBlur = props.onBlur,
290
- onChange = props.onChange;
291
- var emitChange = react$1.useCallback(function (nextValue) {
292
- var event = {
293
- target: {
294
- id: id,
295
- name: name,
296
- value: nextValue
297
- }
298
- };
299
- onChange(event);
300
- }, [id, name, onChange]);
301
- var handleBlur = react$1.useCallback(function (event) {
302
- // check formatting and reformat when necessary
303
- var formattedTime = value && TimeInput.toLocaleTime(value, intl.locale);
304
- if (formattedTime !== value) emitChange(formattedTime); // forward the onBlur call
305
-
306
- if (onBlur) onBlur(event);
307
- }, [intl.locale, value, onBlur, emitChange]);
308
- var onClear = react$1.useCallback(function () {
309
- return emitChange('');
310
- }, [emitChange]); // if locale has changed
311
-
312
- if (typeof prevLocale !== 'undefined' && prevLocale !== intl.locale) {
313
- emitChange(TimeInput.toLocaleTime(value, intl.locale));
294
+ var element = react$1.useRef(null);
295
+
296
+ if (!props.isReadOnly) {
297
+ process.env.NODE_ENV !== "production" ? utils.warning(typeof props.onChange === 'function', 'TimeInput: `onChange` is required when input is not read only.') : void 0;
314
298
  }
315
299
 
300
+ var onBlur = props.onBlur,
301
+ onChange = props.onChange;
302
+ var handleChange = react$1.useCallback(function (event) {
303
+ var rawValue = event.target.value;
304
+ var formattedValue = TimeInput.toLocaleTime(rawValue, intl.locale);
305
+ event.target.value = formattedValue;
306
+ onChange === null || onChange === void 0 ? void 0 : onChange(event);
307
+ }, [intl.locale, onChange]);
308
+ var handleBlur = react$1.useCallback(function (event) {
309
+ var rawValue = event.target.value;
310
+ var formattedValue = TimeInput.toLocaleTime(rawValue, intl.locale);
311
+ event.target.value = formattedValue;
312
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
313
+ }, [intl.locale, onBlur]);
314
+ var handleClear = react$1.useCallback(function () {
315
+ if (element.current) {
316
+ dispatchReactChangeEvent(element.current, '');
317
+ }
318
+ }, []); // if locale has changed trigger a new change event
319
+
320
+ react$1.useEffect(function () {
321
+ if (element.current) {
322
+ dispatchReactChangeEvent(element.current, props.value);
323
+ } // Only subscribe this effect to `intl.locale` changes.
324
+ // eslint-disable-next-line react-hooks/exhaustive-deps
325
+
326
+ }, [intl.locale]);
316
327
  return jsxRuntime.jsx(Constraints__default["default"].Horizontal, {
317
328
  max: props.horizontalConstraint,
318
329
  children: jsxRuntime.jsx(TimeInputBody$1, _objectSpread(_objectSpread({
330
+ ref: element,
319
331
  id: id,
320
332
  name: props.name,
321
333
  autoComplete: props.autoComplete,
322
334
  value: props.value,
323
- onChange: props.onChange,
324
- onFocus: props.onFocus,
335
+ onChange: handleChange,
325
336
  onBlur: handleBlur,
337
+ onFocus: props.onFocus,
326
338
  isAutofocussed: props.isAutofocussed,
327
339
  isDisabled: props.isDisabled,
328
340
  hasError: props.hasError,
329
341
  isReadOnly: props.isReadOnly,
330
- onClear: onClear,
342
+ onClear: handleClear,
331
343
  placeholder: typeof props.placeholder === 'string' ? props.placeholder : intl.formatMessage(messages.placeholder)
332
344
  }, utils.filterDataAttributes(props)), {}, {
333
345
  /* ARIA */
@@ -345,7 +357,7 @@ TimeInput.propTypes = process.env.NODE_ENV !== "production" ? {
345
357
  name: _pt__default["default"].string,
346
358
  autoComplete: _pt__default["default"].string,
347
359
  value: _pt__default["default"].string,
348
- onChange: _pt__default["default"].func.isRequired,
360
+ onChange: _pt__default["default"].func,
349
361
  onBlur: _pt__default["default"].func,
350
362
  onFocus: _pt__default["default"].func,
351
363
  isAutofocussed: _pt__default["default"].bool,
@@ -392,7 +404,7 @@ TimeInput.toLocaleTime = function (time, locale) {
392
404
  var TimeInput$1 = TimeInput;
393
405
 
394
406
  // NOTE: This string will be replaced on build time with the package version.
395
- var version = "14.0.1";
407
+ var version = "14.0.4";
396
408
 
397
409
  exports["default"] = TimeInput$1;
398
410
  exports.version = version;
@@ -6,10 +6,10 @@ var _defineProperty = require('@babel/runtime-corejs3/helpers/defineProperty');
6
6
  require('prop-types');
7
7
  var _padStartInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/pad-start');
8
8
  var _concatInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/concat');
9
+ var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
9
10
  var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
10
11
  var _Object$getOwnPropertySymbols = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols');
11
12
  var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/filter');
12
- var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
13
13
  var _forEachInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/for-each');
14
14
  var _Object$getOwnPropertyDescriptors = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors');
15
15
  var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/object/define-properties');
@@ -32,10 +32,10 @@ function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e };
32
32
 
33
33
  var _padStartInstanceProperty__default = /*#__PURE__*/_interopDefault(_padStartInstanceProperty);
34
34
  var _concatInstanceProperty__default = /*#__PURE__*/_interopDefault(_concatInstanceProperty);
35
+ var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
35
36
  var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
36
37
  var _Object$getOwnPropertySymbols__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertySymbols);
37
38
  var _filterInstanceProperty__default = /*#__PURE__*/_interopDefault(_filterInstanceProperty);
38
- var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
39
39
  var _forEachInstanceProperty__default = /*#__PURE__*/_interopDefault(_forEachInstanceProperty);
40
40
  var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptors);
41
41
  var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
@@ -171,14 +171,14 @@ var ClearSection = function ClearSection(props) {
171
171
  };
172
172
  ClearSection.propTypes = {};
173
173
  ClearSection.displayName = 'ClearSection';
174
-
175
- var TimeInputBody = function TimeInputBody(props) {
174
+ var TimeInputBody = /*#__PURE__*/react$1.forwardRef(function (props, ref) {
176
175
  var theme = react.useTheme();
177
176
  return jsxRuntime.jsx(Inline__default["default"], {
178
177
  alignItems: "center",
179
178
  children: jsxRuntime.jsxs(StyledInputContainer, {
180
179
  css: getInputContainerStyles(props, theme),
181
180
  children: [jsxRuntime.jsx("input", _objectSpread$1(_objectSpread$1({
181
+ ref: ref,
182
182
  css: getTimeInputStyles(props),
183
183
  id: props.id,
184
184
  name: props.name,
@@ -213,9 +213,7 @@ var TimeInputBody = function TimeInputBody(props) {
213
213
  })]
214
214
  })
215
215
  });
216
- };
217
-
218
- TimeInputBody.propTypes = {};
216
+ });
219
217
  TimeInputBody.displayName = 'TimeInputBody';
220
218
  var TimeInputBody$1 = TimeInputBody;
221
219
 
@@ -257,56 +255,70 @@ var format24hr = function format24hr(_ref) {
257
255
 
258
256
  var hasMilliseconds = function hasMilliseconds(parsedTime) {
259
257
  return parsedTime.milliseconds !== 0;
258
+ }; // Calling `eventTarget.dispatchEvent` does not natively work in React.
259
+ // Instead, we need to grab the element value setter, set the value, and dispatch a change event.
260
+
261
+
262
+ var dispatchReactChangeEvent = function dispatchReactChangeEvent(node, value) {
263
+ var _Object$getOwnPropert;
264
+
265
+ var setValue = (_Object$getOwnPropert = _Object$getOwnPropertyDescriptor__default["default"](node.constructor.prototype, 'value')) === null || _Object$getOwnPropert === void 0 ? void 0 : _Object$getOwnPropert.set;
266
+ setValue === null || setValue === void 0 ? void 0 : setValue.call(node, value);
267
+ node.dispatchEvent(new Event('change', {
268
+ bubbles: true
269
+ }));
260
270
  };
261
271
 
262
272
  var TimeInput = function TimeInput(props) {
263
273
  var id = hooks.useFieldId(props.id, sequentialId);
264
274
  var intl = reactIntl.useIntl();
265
- var prevLocale = hooks.usePrevious(intl.locale);
266
- var name = props.name,
267
- value = props.value,
268
- onBlur = props.onBlur,
275
+ var element = react$1.useRef(null);
276
+
277
+ if (!props.isReadOnly) ;
278
+
279
+ var onBlur = props.onBlur,
269
280
  onChange = props.onChange;
270
- var emitChange = react$1.useCallback(function (nextValue) {
271
- var event = {
272
- target: {
273
- id: id,
274
- name: name,
275
- value: nextValue
276
- }
277
- };
278
- onChange(event);
279
- }, [id, name, onChange]);
281
+ var handleChange = react$1.useCallback(function (event) {
282
+ var rawValue = event.target.value;
283
+ var formattedValue = TimeInput.toLocaleTime(rawValue, intl.locale);
284
+ event.target.value = formattedValue;
285
+ onChange === null || onChange === void 0 ? void 0 : onChange(event);
286
+ }, [intl.locale, onChange]);
280
287
  var handleBlur = react$1.useCallback(function (event) {
281
- // check formatting and reformat when necessary
282
- var formattedTime = value && TimeInput.toLocaleTime(value, intl.locale);
283
- if (formattedTime !== value) emitChange(formattedTime); // forward the onBlur call
284
-
285
- if (onBlur) onBlur(event);
286
- }, [intl.locale, value, onBlur, emitChange]);
287
- var onClear = react$1.useCallback(function () {
288
- return emitChange('');
289
- }, [emitChange]); // if locale has changed
290
-
291
- if (typeof prevLocale !== 'undefined' && prevLocale !== intl.locale) {
292
- emitChange(TimeInput.toLocaleTime(value, intl.locale));
293
- }
294
-
288
+ var rawValue = event.target.value;
289
+ var formattedValue = TimeInput.toLocaleTime(rawValue, intl.locale);
290
+ event.target.value = formattedValue;
291
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
292
+ }, [intl.locale, onBlur]);
293
+ var handleClear = react$1.useCallback(function () {
294
+ if (element.current) {
295
+ dispatchReactChangeEvent(element.current, '');
296
+ }
297
+ }, []); // if locale has changed trigger a new change event
298
+
299
+ react$1.useEffect(function () {
300
+ if (element.current) {
301
+ dispatchReactChangeEvent(element.current, props.value);
302
+ } // Only subscribe this effect to `intl.locale` changes.
303
+ // eslint-disable-next-line react-hooks/exhaustive-deps
304
+
305
+ }, [intl.locale]);
295
306
  return jsxRuntime.jsx(Constraints__default["default"].Horizontal, {
296
307
  max: props.horizontalConstraint,
297
308
  children: jsxRuntime.jsx(TimeInputBody$1, _objectSpread(_objectSpread({
309
+ ref: element,
298
310
  id: id,
299
311
  name: props.name,
300
312
  autoComplete: props.autoComplete,
301
313
  value: props.value,
302
- onChange: props.onChange,
303
- onFocus: props.onFocus,
314
+ onChange: handleChange,
304
315
  onBlur: handleBlur,
316
+ onFocus: props.onFocus,
305
317
  isAutofocussed: props.isAutofocussed,
306
318
  isDisabled: props.isDisabled,
307
319
  hasError: props.hasError,
308
320
  isReadOnly: props.isReadOnly,
309
- onClear: onClear,
321
+ onClear: handleClear,
310
322
  placeholder: typeof props.placeholder === 'string' ? props.placeholder : intl.formatMessage(messages.placeholder)
311
323
  }, utils.filterDataAttributes(props)), {}, {
312
324
  /* ARIA */
@@ -355,7 +367,7 @@ TimeInput.toLocaleTime = function (time, locale) {
355
367
  var TimeInput$1 = TimeInput;
356
368
 
357
369
  // NOTE: This string will be replaced on build time with the package version.
358
- var version = "14.0.1";
370
+ var version = "14.0.4";
359
371
 
360
372
  exports["default"] = TimeInput$1;
361
373
  exports.version = version;
@@ -2,19 +2,19 @@ import _defineProperty from '@babel/runtime-corejs3/helpers/esm/defineProperty';
2
2
  import _pt from 'prop-types';
3
3
  import _padStartInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/pad-start';
4
4
  import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/concat';
5
+ import _Object$getOwnPropertyDescriptor from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor';
5
6
  import _Object$keys from '@babel/runtime-corejs3/core-js-stable/object/keys';
6
7
  import _Object$getOwnPropertySymbols from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols';
7
8
  import _filterInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/filter';
8
- import _Object$getOwnPropertyDescriptor from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor';
9
9
  import _forEachInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/for-each';
10
10
  import _Object$getOwnPropertyDescriptors from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors';
11
11
  import _Object$defineProperties from '@babel/runtime-corejs3/core-js-stable/object/define-properties';
12
12
  import _Object$defineProperty from '@babel/runtime-corejs3/core-js-stable/object/define-property';
13
- import { useCallback } from 'react';
13
+ import { forwardRef, useRef, useCallback, useEffect } from 'react';
14
14
  import { defineMessages, useIntl } from 'react-intl';
15
15
  import Constraints from '@commercetools-uikit/constraints';
16
- import { filterDataAttributes, createSequentialId, parseTime } from '@commercetools-uikit/utils';
17
- import { useFieldId, usePrevious } from '@commercetools-uikit/hooks';
16
+ import { filterDataAttributes, createSequentialId, warning, parseTime } from '@commercetools-uikit/utils';
17
+ import { useFieldId } from '@commercetools-uikit/hooks';
18
18
  import { css, useTheme } from '@emotion/react';
19
19
  import { ClockIcon, CloseIcon } from '@commercetools-uikit/icons';
20
20
  import Inline from '@commercetools-uikit/spacings-inline';
@@ -168,14 +168,14 @@ ClearSection.propTypes = process.env.NODE_ENV !== "production" ? {
168
168
  onClear: _pt.func.isRequired
169
169
  } : {};
170
170
  ClearSection.displayName = 'ClearSection';
171
-
172
- var TimeInputBody = function TimeInputBody(props) {
171
+ var TimeInputBody = /*#__PURE__*/forwardRef(function (props, ref) {
173
172
  var theme = useTheme();
174
173
  return jsx(Inline, {
175
174
  alignItems: "center",
176
175
  children: jsxs(StyledInputContainer, {
177
176
  css: getInputContainerStyles(props, theme),
178
177
  children: [jsx("input", _objectSpread$1(_objectSpread$1({
178
+ ref: ref,
179
179
  css: getTimeInputStyles(props),
180
180
  id: props.id,
181
181
  name: props.name,
@@ -210,11 +210,7 @@ var TimeInputBody = function TimeInputBody(props) {
210
210
  })]
211
211
  })
212
212
  });
213
- };
214
-
215
- TimeInputBody.propTypes = process.env.NODE_ENV !== "production" ? {
216
- onClear: _pt.func.isRequired
217
- } : {};
213
+ });
218
214
  TimeInputBody.displayName = 'TimeInputBody';
219
215
  var TimeInputBody$1 = TimeInputBody;
220
216
 
@@ -256,56 +252,72 @@ var format24hr = function format24hr(_ref) {
256
252
 
257
253
  var hasMilliseconds = function hasMilliseconds(parsedTime) {
258
254
  return parsedTime.milliseconds !== 0;
255
+ }; // Calling `eventTarget.dispatchEvent` does not natively work in React.
256
+ // Instead, we need to grab the element value setter, set the value, and dispatch a change event.
257
+
258
+
259
+ var dispatchReactChangeEvent = function dispatchReactChangeEvent(node, value) {
260
+ var _Object$getOwnPropert;
261
+
262
+ var setValue = (_Object$getOwnPropert = _Object$getOwnPropertyDescriptor(node.constructor.prototype, 'value')) === null || _Object$getOwnPropert === void 0 ? void 0 : _Object$getOwnPropert.set;
263
+ setValue === null || setValue === void 0 ? void 0 : setValue.call(node, value);
264
+ node.dispatchEvent(new Event('change', {
265
+ bubbles: true
266
+ }));
259
267
  };
260
268
 
261
269
  var TimeInput = function TimeInput(props) {
262
270
  var id = useFieldId(props.id, sequentialId);
263
271
  var intl = useIntl();
264
- var prevLocale = usePrevious(intl.locale);
265
- var name = props.name,
266
- value = props.value,
267
- onBlur = props.onBlur,
268
- onChange = props.onChange;
269
- var emitChange = useCallback(function (nextValue) {
270
- var event = {
271
- target: {
272
- id: id,
273
- name: name,
274
- value: nextValue
275
- }
276
- };
277
- onChange(event);
278
- }, [id, name, onChange]);
279
- var handleBlur = useCallback(function (event) {
280
- // check formatting and reformat when necessary
281
- var formattedTime = value && TimeInput.toLocaleTime(value, intl.locale);
282
- if (formattedTime !== value) emitChange(formattedTime); // forward the onBlur call
283
-
284
- if (onBlur) onBlur(event);
285
- }, [intl.locale, value, onBlur, emitChange]);
286
- var onClear = useCallback(function () {
287
- return emitChange('');
288
- }, [emitChange]); // if locale has changed
289
-
290
- if (typeof prevLocale !== 'undefined' && prevLocale !== intl.locale) {
291
- emitChange(TimeInput.toLocaleTime(value, intl.locale));
272
+ var element = useRef(null);
273
+
274
+ if (!props.isReadOnly) {
275
+ process.env.NODE_ENV !== "production" ? warning(typeof props.onChange === 'function', 'TimeInput: `onChange` is required when input is not read only.') : void 0;
292
276
  }
293
277
 
278
+ var onBlur = props.onBlur,
279
+ onChange = props.onChange;
280
+ var handleChange = useCallback(function (event) {
281
+ var rawValue = event.target.value;
282
+ var formattedValue = TimeInput.toLocaleTime(rawValue, intl.locale);
283
+ event.target.value = formattedValue;
284
+ onChange === null || onChange === void 0 ? void 0 : onChange(event);
285
+ }, [intl.locale, onChange]);
286
+ var handleBlur = useCallback(function (event) {
287
+ var rawValue = event.target.value;
288
+ var formattedValue = TimeInput.toLocaleTime(rawValue, intl.locale);
289
+ event.target.value = formattedValue;
290
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
291
+ }, [intl.locale, onBlur]);
292
+ var handleClear = useCallback(function () {
293
+ if (element.current) {
294
+ dispatchReactChangeEvent(element.current, '');
295
+ }
296
+ }, []); // if locale has changed trigger a new change event
297
+
298
+ useEffect(function () {
299
+ if (element.current) {
300
+ dispatchReactChangeEvent(element.current, props.value);
301
+ } // Only subscribe this effect to `intl.locale` changes.
302
+ // eslint-disable-next-line react-hooks/exhaustive-deps
303
+
304
+ }, [intl.locale]);
294
305
  return jsx(Constraints.Horizontal, {
295
306
  max: props.horizontalConstraint,
296
307
  children: jsx(TimeInputBody$1, _objectSpread(_objectSpread({
308
+ ref: element,
297
309
  id: id,
298
310
  name: props.name,
299
311
  autoComplete: props.autoComplete,
300
312
  value: props.value,
301
- onChange: props.onChange,
302
- onFocus: props.onFocus,
313
+ onChange: handleChange,
303
314
  onBlur: handleBlur,
315
+ onFocus: props.onFocus,
304
316
  isAutofocussed: props.isAutofocussed,
305
317
  isDisabled: props.isDisabled,
306
318
  hasError: props.hasError,
307
319
  isReadOnly: props.isReadOnly,
308
- onClear: onClear,
320
+ onClear: handleClear,
309
321
  placeholder: typeof props.placeholder === 'string' ? props.placeholder : intl.formatMessage(messages.placeholder)
310
322
  }, filterDataAttributes(props)), {}, {
311
323
  /* ARIA */
@@ -323,7 +335,7 @@ TimeInput.propTypes = process.env.NODE_ENV !== "production" ? {
323
335
  name: _pt.string,
324
336
  autoComplete: _pt.string,
325
337
  value: _pt.string,
326
- onChange: _pt.func.isRequired,
338
+ onChange: _pt.func,
327
339
  onBlur: _pt.func,
328
340
  onFocus: _pt.func,
329
341
  isAutofocussed: _pt.bool,
@@ -370,6 +382,6 @@ TimeInput.toLocaleTime = function (time, locale) {
370
382
  var TimeInput$1 = TimeInput;
371
383
 
372
384
  // NOTE: This string will be replaced on build time with the package version.
373
- var version = "14.0.1";
385
+ var version = "14.0.4";
374
386
 
375
387
  export { TimeInput$1 as default, version };
@@ -1,8 +1,5 @@
1
- import type { KeyboardEvent, MouseEvent } from 'react';
1
+ import { type KeyboardEvent, type MouseEvent } from 'react';
2
2
  import type { TTimeInputProps } from './time-input';
3
- declare type TTimeInputBodyProps = TTimeInputProps & {
4
- onClear: (event: MouseEvent<HTMLButtonElement> | KeyboardEvent<HTMLButtonElement>) => void;
5
- };
6
3
  declare type TClearSectionProps = {
7
4
  isDisabled?: boolean;
8
5
  hasError?: boolean;
@@ -13,8 +10,7 @@ export declare const ClearSection: {
13
10
  (props: TClearSectionProps): import("@emotion/react/jsx-runtime").JSX.Element;
14
11
  displayName: string;
15
12
  };
16
- declare const TimeInputBody: {
17
- (props: TTimeInputBodyProps): import("@emotion/react/jsx-runtime").JSX.Element;
18
- displayName: string;
19
- };
13
+ declare const TimeInputBody: import("react").ForwardRefExoticComponent<TTimeInputProps & {
14
+ onClear: (event: MouseEvent<HTMLButtonElement> | KeyboardEvent<HTMLButtonElement>) => void;
15
+ } & import("react").RefAttributes<HTMLInputElement>>;
20
16
  export default TimeInputBody;
@@ -1,11 +1,4 @@
1
- import { type FocusEventHandler } from 'react';
2
- declare type TEvent = {
3
- target: {
4
- id: string;
5
- name?: string;
6
- value: unknown;
7
- };
8
- };
1
+ import { type FocusEventHandler, type ChangeEventHandler } from 'react';
9
2
  export declare type TTimeInputProps = {
10
3
  id?: string;
11
4
  'aria-invalid'?: boolean;
@@ -14,9 +7,9 @@ export declare type TTimeInputProps = {
14
7
  name?: string;
15
8
  autoComplete?: string;
16
9
  value?: string;
17
- onChange: (event: TEvent) => void;
18
- onBlur?: FocusEventHandler;
19
- onFocus?: FocusEventHandler;
10
+ onChange?: ChangeEventHandler<HTMLInputElement>;
11
+ onBlur?: FocusEventHandler<HTMLInputElement>;
12
+ onFocus?: FocusEventHandler<HTMLInputElement>;
20
13
  isAutofocussed?: boolean;
21
14
  isDisabled?: boolean;
22
15
  placeholder?: string;
@@ -30,6 +23,6 @@ declare const TimeInput: {
30
23
  defaultProps: {
31
24
  horizontalConstraint: string;
32
25
  };
33
- toLocaleTime(time: string, locale: string): string;
26
+ toLocaleTime(time: string | undefined, locale: string): string;
34
27
  };
35
28
  export default TimeInput;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@commercetools-uikit/time-input",
3
3
  "description": "The TimeInput component allows the user to select a time.",
4
- "version": "14.0.1",
4
+ "version": "14.0.4",
5
5
  "bugs": "https://github.com/commercetools/ui-kit/issues",
6
6
  "repository": {
7
7
  "type": "git",
@@ -24,9 +24,9 @@
24
24
  "@commercetools-uikit/accessible-button": "14.0.1",
25
25
  "@commercetools-uikit/constraints": "14.0.1",
26
26
  "@commercetools-uikit/design-system": "14.0.0",
27
- "@commercetools-uikit/hooks": "14.0.1",
27
+ "@commercetools-uikit/hooks": "14.0.3",
28
28
  "@commercetools-uikit/icons": "14.0.1",
29
- "@commercetools-uikit/input-utils": "14.0.1",
29
+ "@commercetools-uikit/input-utils": "14.0.2",
30
30
  "@commercetools-uikit/spacings-inline": "14.0.1",
31
31
  "@commercetools-uikit/utils": "14.0.1",
32
32
  "@emotion/is-prop-valid": "1.1.2",