@jobber/components 6.86.4 → 6.86.5

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.
@@ -1,7 +1,6 @@
1
- import type { ChangeEvent, ReactElement, RefObject } from "react";
1
+ import type { ChangeEvent, ReactElement } from "react";
2
2
  import React from "react";
3
3
  import type { DatePickerProps as ReactDatePickerProps } from "react-datepicker";
4
- import type ReactDatePicker from "react-datepicker";
5
4
  export interface DatePickerActivatorProps extends Pick<ReactDatePickerProps, "value" | "id" | "ariaDescribedBy" | "ariaInvalid" | "ariaLabelledBy" | "ariaRequired"> {
6
5
  readonly activator?: ReactElement | ((props: DatePickerActivatorProps) => ReactElement);
7
6
  readonly fullWidth?: boolean;
@@ -10,6 +9,5 @@ export interface DatePickerActivatorProps extends Pick<ReactDatePickerProps, "va
10
9
  onClick?(): void;
11
10
  onFocus?(): void;
12
11
  onKeyDown?(): void;
13
- readonly pickerRef: RefObject<ReactDatePicker>;
14
12
  }
15
13
  export declare const DatePickerActivator: React.ForwardRefExoticComponent<DatePickerActivatorProps & React.RefAttributes<HTMLElement>>;
@@ -12744,7 +12744,7 @@ function DatePicker({ onChange, onMonthChange, activator, inline, selected, read
12744
12744
  React.useEffect(focusOnSelectedDate, [open]);
12745
12745
  }
12746
12746
  return (React.createElement("div", { className: wrapperClassName, ref: ref, "data-elevation": "elevated" },
12747
- React.createElement(DatePicker$1, { ref: pickerRef, calendarClassName: datePickerClassNames, showPopperArrow: false, selected: selected, inline: inline, disabled: disabled, readOnly: readonly, onChange: handleChange, maxDate: maxDate, preventOpenOnFocus: true, minDate: minDate, useWeekdaysShort: true, customInput: React.createElement(DatePickerActivator, { pickerRef: pickerRef, activator: activator, fullWidth: fullWidth }), renderCustomHeader: props => React.createElement(DatePickerCustomHeader, Object.assign({}, props)), onCalendarOpen: handleCalendarOpen, onCalendarClose: handleCalendarClose, dateFormat: [
12747
+ React.createElement(DatePicker$1, { ref: pickerRef, calendarClassName: datePickerClassNames, showPopperArrow: false, selected: selected, inline: inline, disabled: disabled, readOnly: readonly, onChange: handleChange, maxDate: maxDate, preventOpenOnFocus: true, minDate: minDate, useWeekdaysShort: true, customInput: React.createElement(DatePickerActivator, { activator: activator, fullWidth: fullWidth }), renderCustomHeader: props => React.createElement(DatePickerCustomHeader, Object.assign({}, props)), onCalendarOpen: handleCalendarOpen, onCalendarClose: handleCalendarClose, dateFormat: [
12748
12748
  dateFormat,
12749
12749
  "P",
12750
12750
  "PP",
@@ -12761,8 +12761,8 @@ function DatePicker({ onChange, onMonthChange, activator, inline, selected, read
12761
12761
  * fail).
12762
12762
  */
12763
12763
  function handleChange(value) {
12764
- if (value)
12765
- onChange(value);
12764
+ // TODO: Ticket created to update all DatePicker and InputDate usages to accept Date | null
12765
+ onChange(value);
12766
12766
  }
12767
12767
  function handleCalendarOpen() {
12768
12768
  setOpen(true);
@@ -12742,7 +12742,7 @@ function DatePicker({ onChange, onMonthChange, activator, inline, selected, read
12742
12742
  useEffect(focusOnSelectedDate, [open]);
12743
12743
  }
12744
12744
  return (React__default.createElement("div", { className: wrapperClassName, ref: ref, "data-elevation": "elevated" },
12745
- React__default.createElement(DatePicker$1, { ref: pickerRef, calendarClassName: datePickerClassNames, showPopperArrow: false, selected: selected, inline: inline, disabled: disabled, readOnly: readonly, onChange: handleChange, maxDate: maxDate, preventOpenOnFocus: true, minDate: minDate, useWeekdaysShort: true, customInput: React__default.createElement(DatePickerActivator, { pickerRef: pickerRef, activator: activator, fullWidth: fullWidth }), renderCustomHeader: props => React__default.createElement(DatePickerCustomHeader, Object.assign({}, props)), onCalendarOpen: handleCalendarOpen, onCalendarClose: handleCalendarClose, dateFormat: [
12745
+ React__default.createElement(DatePicker$1, { ref: pickerRef, calendarClassName: datePickerClassNames, showPopperArrow: false, selected: selected, inline: inline, disabled: disabled, readOnly: readonly, onChange: handleChange, maxDate: maxDate, preventOpenOnFocus: true, minDate: minDate, useWeekdaysShort: true, customInput: React__default.createElement(DatePickerActivator, { activator: activator, fullWidth: fullWidth }), renderCustomHeader: props => React__default.createElement(DatePickerCustomHeader, Object.assign({}, props)), onCalendarOpen: handleCalendarOpen, onCalendarClose: handleCalendarClose, dateFormat: [
12746
12746
  dateFormat,
12747
12747
  "P",
12748
12748
  "PP",
@@ -12759,8 +12759,8 @@ function DatePicker({ onChange, onMonthChange, activator, inline, selected, read
12759
12759
  * fail).
12760
12760
  */
12761
12761
  function handleChange(value) {
12762
- if (value)
12763
- onChange(value);
12762
+ // TODO: Ticket created to update all DatePicker and InputDate usages to accept Date | null
12763
+ onChange(value);
12764
12764
  }
12765
12765
  function handleCalendarOpen() {
12766
12766
  setOpen(true);
@@ -53,16 +53,4 @@ export interface InputDateProps extends Omit<CommonFormFieldProps, "clearable">,
53
53
  * Text to display instead of a date value
54
54
  */
55
55
  readonly emptyValueLabel?: string;
56
- /**
57
- * Experimental:
58
- * Whether to replace empty/invalid values with the original value on blur.
59
- *
60
- * This solves an immediate UX problem and is likely to change in the future.
61
- * It prevents the input from retaining empty/invalid values when the user tabs
62
- * into it, clears the value, and tabs away. In this scenario, the original
63
- * value will be restored.
64
- *
65
- * @default false
66
- */
67
- readonly restoreLastValueOnBlur?: boolean;
68
56
  }
@@ -36,154 +36,10 @@ require('../useRefocusOnActivator-cjs.js');
36
36
  require('../AtlantisContext-cjs.js');
37
37
  require('../useSafeLayoutEffect-cjs.js');
38
38
 
39
- function _typeof(o) {
40
- "@babel/helpers - typeof";
41
-
42
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
43
- return typeof o;
44
- } : function (o) {
45
- return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
46
- }, _typeof(o);
47
- }
48
-
49
- function requiredArgs(required, args) {
50
- if (args.length < required) {
51
- throw new TypeError(required + ' argument' + (required > 1 ? 's' : '') + ' required, but only ' + args.length + ' present');
52
- }
53
- }
54
-
55
- /**
56
- * @name isDate
57
- * @category Common Helpers
58
- * @summary Is the given value a date?
59
- *
60
- * @description
61
- * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.
62
- *
63
- * @param {*} value - the value to check
64
- * @returns {boolean} true if the given value is a date
65
- * @throws {TypeError} 1 arguments required
66
- *
67
- * @example
68
- * // For a valid date:
69
- * const result = isDate(new Date())
70
- * //=> true
71
- *
72
- * @example
73
- * // For an invalid date:
74
- * const result = isDate(new Date(NaN))
75
- * //=> true
76
- *
77
- * @example
78
- * // For some value:
79
- * const result = isDate('2014-02-31')
80
- * //=> false
81
- *
82
- * @example
83
- * // For an object:
84
- * const result = isDate({})
85
- * //=> false
86
- */
87
- function isDate(value) {
88
- requiredArgs(1, arguments);
89
- return value instanceof Date || _typeof(value) === 'object' && Object.prototype.toString.call(value) === '[object Date]';
90
- }
91
-
92
- /**
93
- * @name toDate
94
- * @category Common Helpers
95
- * @summary Convert the given argument to an instance of Date.
96
- *
97
- * @description
98
- * Convert the given argument to an instance of Date.
99
- *
100
- * If the argument is an instance of Date, the function returns its clone.
101
- *
102
- * If the argument is a number, it is treated as a timestamp.
103
- *
104
- * If the argument is none of the above, the function returns Invalid Date.
105
- *
106
- * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.
107
- *
108
- * @param {Date|Number} argument - the value to convert
109
- * @returns {Date} the parsed date in the local time zone
110
- * @throws {TypeError} 1 argument required
111
- *
112
- * @example
113
- * // Clone the date:
114
- * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))
115
- * //=> Tue Feb 11 2014 11:30:30
116
- *
117
- * @example
118
- * // Convert the timestamp to date:
119
- * const result = toDate(1392098430000)
120
- * //=> Tue Feb 11 2014 11:30:30
121
- */
122
- function toDate(argument) {
123
- requiredArgs(1, arguments);
124
- var argStr = Object.prototype.toString.call(argument);
125
-
126
- // Clone the date
127
- if (argument instanceof Date || _typeof(argument) === 'object' && argStr === '[object Date]') {
128
- // Prevent the date to lose the milliseconds when passed to new Date() in IE10
129
- return new Date(argument.getTime());
130
- } else if (typeof argument === 'number' || argStr === '[object Number]') {
131
- return new Date(argument);
132
- } else {
133
- if ((typeof argument === 'string' || argStr === '[object String]') && typeof console !== 'undefined') {
134
- // eslint-disable-next-line no-console
135
- console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#string-arguments");
136
- // eslint-disable-next-line no-console
137
- console.warn(new Error().stack);
138
- }
139
- return new Date(NaN);
140
- }
141
- }
142
-
143
- /**
144
- * @name isValid
145
- * @category Common Helpers
146
- * @summary Is the given date valid?
147
- *
148
- * @description
149
- * Returns false if argument is Invalid Date and true otherwise.
150
- * Argument is converted to Date using `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}
151
- * Invalid Date is a Date, whose time value is NaN.
152
- *
153
- * Time value of Date: http://es5.github.io/#x15.9.1.1
154
- *
155
- * @param {*} date - the date to check
156
- * @returns {Boolean} the date is valid
157
- * @throws {TypeError} 1 argument required
158
- *
159
- * @example
160
- * // For the valid date:
161
- * const result = isValid(new Date(2014, 1, 31))
162
- * //=> true
163
- *
164
- * @example
165
- * // For the value, convertable into a date:
166
- * const result = isValid(1393804800000)
167
- * //=> true
168
- *
169
- * @example
170
- * // For the invalid date:
171
- * const result = isValid(new Date(''))
172
- * //=> false
173
- */
174
- function isValid(dirtyDate) {
175
- requiredArgs(1, arguments);
176
- if (!isDate(dirtyDate) && typeof dirtyDate !== 'number') {
177
- return false;
178
- }
179
- var date = toDate(dirtyDate);
180
- return !isNaN(Number(date));
181
- }
182
-
183
39
  function InputDate$1(inputProps) {
184
40
  const formFieldActionsRef = React.useRef(null);
185
41
  return (React.createElement(DatePicker.DatePicker, { selected: inputProps.value, onChange: inputProps.onChange, disabled: inputProps.disabled, readonly: inputProps.readonly, fullWidth: !inputProps.inline, minDate: inputProps.minDate, maxDate: inputProps.maxDate, smartAutofocus: false, activator: activatorProps => {
186
- const { onChange, onClick, value, pickerRef } = activatorProps;
42
+ const { onChange, onClick, value } = activatorProps;
187
43
  const newActivatorProps = omit.omit(activatorProps, ["activator"]);
188
44
  const [isFocused, setIsFocused] = React.useState(false);
189
45
  const suffix = inputProps.showIcon !== false
@@ -206,30 +62,9 @@ function InputDate$1(inputProps) {
206
62
  React.createElement(FormField.FormField, Object.assign({}, newActivatorProps, inputProps, { value: showEmptyValueLabel ? inputProps.emptyValueLabel || "" : value, placeholder: inputProps.placeholder, onChange: (_, event) => {
207
63
  onChange && onChange(event);
208
64
  }, onBlur: () => {
209
- var _a;
210
65
  inputProps.onBlur && inputProps.onBlur();
211
66
  activatorProps.onBlur && activatorProps.onBlur();
212
67
  setIsFocused(false);
213
- /**
214
- * This is an experimental workaround to solve a specific UX problem we have under certain conditions.
215
- * When you click to focus InputDate, ReactDatePicker becomes visible. If you delete the current date and blur
216
- * the input field by clicking away, ReactDatePicker will automatically set the date to whatever date was
217
- * currently selected.
218
- *
219
- * The above works great and is the expected user experience. ReactDatePicker fills in the empty value for us.
220
- *
221
- * However, there's a specific scenario where ReactDatePicker isn't visible: when you tab into the input date.
222
- * When you tab into it, clear the value, and tab away to blur, ReactDatePicker doesn't automatically fill in
223
- * the empty value because it wasn't visible/active.
224
- *
225
- * To solve this, we need to handle the blur event here and check if the value is empty or invalid. If it is,
226
- * we have to call onChange with the original input value which informs ReactDatePicker that is the current value.
227
- */
228
- if (inputProps.restoreLastValueOnBlur) {
229
- if ((!value || !isValid(value)) && inputProps.value) {
230
- (_a = pickerRef.current) === null || _a === void 0 ? void 0 : _a.setSelected(inputProps.value);
231
- }
232
- }
233
68
  }, onFocus: () => {
234
69
  inputProps.onFocus && inputProps.onFocus();
235
70
  activatorProps.onFocus && activatorProps.onFocus();
@@ -34,154 +34,10 @@ import '../useRefocusOnActivator-es.js';
34
34
  import '../AtlantisContext-es.js';
35
35
  import '../useSafeLayoutEffect-es.js';
36
36
 
37
- function _typeof(o) {
38
- "@babel/helpers - typeof";
39
-
40
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
41
- return typeof o;
42
- } : function (o) {
43
- return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
44
- }, _typeof(o);
45
- }
46
-
47
- function requiredArgs(required, args) {
48
- if (args.length < required) {
49
- throw new TypeError(required + ' argument' + (required > 1 ? 's' : '') + ' required, but only ' + args.length + ' present');
50
- }
51
- }
52
-
53
- /**
54
- * @name isDate
55
- * @category Common Helpers
56
- * @summary Is the given value a date?
57
- *
58
- * @description
59
- * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.
60
- *
61
- * @param {*} value - the value to check
62
- * @returns {boolean} true if the given value is a date
63
- * @throws {TypeError} 1 arguments required
64
- *
65
- * @example
66
- * // For a valid date:
67
- * const result = isDate(new Date())
68
- * //=> true
69
- *
70
- * @example
71
- * // For an invalid date:
72
- * const result = isDate(new Date(NaN))
73
- * //=> true
74
- *
75
- * @example
76
- * // For some value:
77
- * const result = isDate('2014-02-31')
78
- * //=> false
79
- *
80
- * @example
81
- * // For an object:
82
- * const result = isDate({})
83
- * //=> false
84
- */
85
- function isDate(value) {
86
- requiredArgs(1, arguments);
87
- return value instanceof Date || _typeof(value) === 'object' && Object.prototype.toString.call(value) === '[object Date]';
88
- }
89
-
90
- /**
91
- * @name toDate
92
- * @category Common Helpers
93
- * @summary Convert the given argument to an instance of Date.
94
- *
95
- * @description
96
- * Convert the given argument to an instance of Date.
97
- *
98
- * If the argument is an instance of Date, the function returns its clone.
99
- *
100
- * If the argument is a number, it is treated as a timestamp.
101
- *
102
- * If the argument is none of the above, the function returns Invalid Date.
103
- *
104
- * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.
105
- *
106
- * @param {Date|Number} argument - the value to convert
107
- * @returns {Date} the parsed date in the local time zone
108
- * @throws {TypeError} 1 argument required
109
- *
110
- * @example
111
- * // Clone the date:
112
- * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))
113
- * //=> Tue Feb 11 2014 11:30:30
114
- *
115
- * @example
116
- * // Convert the timestamp to date:
117
- * const result = toDate(1392098430000)
118
- * //=> Tue Feb 11 2014 11:30:30
119
- */
120
- function toDate(argument) {
121
- requiredArgs(1, arguments);
122
- var argStr = Object.prototype.toString.call(argument);
123
-
124
- // Clone the date
125
- if (argument instanceof Date || _typeof(argument) === 'object' && argStr === '[object Date]') {
126
- // Prevent the date to lose the milliseconds when passed to new Date() in IE10
127
- return new Date(argument.getTime());
128
- } else if (typeof argument === 'number' || argStr === '[object Number]') {
129
- return new Date(argument);
130
- } else {
131
- if ((typeof argument === 'string' || argStr === '[object String]') && typeof console !== 'undefined') {
132
- // eslint-disable-next-line no-console
133
- console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#string-arguments");
134
- // eslint-disable-next-line no-console
135
- console.warn(new Error().stack);
136
- }
137
- return new Date(NaN);
138
- }
139
- }
140
-
141
- /**
142
- * @name isValid
143
- * @category Common Helpers
144
- * @summary Is the given date valid?
145
- *
146
- * @description
147
- * Returns false if argument is Invalid Date and true otherwise.
148
- * Argument is converted to Date using `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}
149
- * Invalid Date is a Date, whose time value is NaN.
150
- *
151
- * Time value of Date: http://es5.github.io/#x15.9.1.1
152
- *
153
- * @param {*} date - the date to check
154
- * @returns {Boolean} the date is valid
155
- * @throws {TypeError} 1 argument required
156
- *
157
- * @example
158
- * // For the valid date:
159
- * const result = isValid(new Date(2014, 1, 31))
160
- * //=> true
161
- *
162
- * @example
163
- * // For the value, convertable into a date:
164
- * const result = isValid(1393804800000)
165
- * //=> true
166
- *
167
- * @example
168
- * // For the invalid date:
169
- * const result = isValid(new Date(''))
170
- * //=> false
171
- */
172
- function isValid(dirtyDate) {
173
- requiredArgs(1, arguments);
174
- if (!isDate(dirtyDate) && typeof dirtyDate !== 'number') {
175
- return false;
176
- }
177
- var date = toDate(dirtyDate);
178
- return !isNaN(Number(date));
179
- }
180
-
181
37
  function InputDate$1(inputProps) {
182
38
  const formFieldActionsRef = useRef(null);
183
39
  return (React__default.createElement(DatePicker, { selected: inputProps.value, onChange: inputProps.onChange, disabled: inputProps.disabled, readonly: inputProps.readonly, fullWidth: !inputProps.inline, minDate: inputProps.minDate, maxDate: inputProps.maxDate, smartAutofocus: false, activator: activatorProps => {
184
- const { onChange, onClick, value, pickerRef } = activatorProps;
40
+ const { onChange, onClick, value } = activatorProps;
185
41
  const newActivatorProps = omit(activatorProps, ["activator"]);
186
42
  const [isFocused, setIsFocused] = useState(false);
187
43
  const suffix = inputProps.showIcon !== false
@@ -204,30 +60,9 @@ function InputDate$1(inputProps) {
204
60
  React__default.createElement(FormField, Object.assign({}, newActivatorProps, inputProps, { value: showEmptyValueLabel ? inputProps.emptyValueLabel || "" : value, placeholder: inputProps.placeholder, onChange: (_, event) => {
205
61
  onChange && onChange(event);
206
62
  }, onBlur: () => {
207
- var _a;
208
63
  inputProps.onBlur && inputProps.onBlur();
209
64
  activatorProps.onBlur && activatorProps.onBlur();
210
65
  setIsFocused(false);
211
- /**
212
- * This is an experimental workaround to solve a specific UX problem we have under certain conditions.
213
- * When you click to focus InputDate, ReactDatePicker becomes visible. If you delete the current date and blur
214
- * the input field by clicking away, ReactDatePicker will automatically set the date to whatever date was
215
- * currently selected.
216
- *
217
- * The above works great and is the expected user experience. ReactDatePicker fills in the empty value for us.
218
- *
219
- * However, there's a specific scenario where ReactDatePicker isn't visible: when you tab into the input date.
220
- * When you tab into it, clear the value, and tab away to blur, ReactDatePicker doesn't automatically fill in
221
- * the empty value because it wasn't visible/active.
222
- *
223
- * To solve this, we need to handle the blur event here and check if the value is empty or invalid. If it is,
224
- * we have to call onChange with the original input value which informs ReactDatePicker that is the current value.
225
- */
226
- if (inputProps.restoreLastValueOnBlur) {
227
- if ((!value || !isValid(value)) && inputProps.value) {
228
- (_a = pickerRef.current) === null || _a === void 0 ? void 0 : _a.setSelected(inputProps.value);
229
- }
230
- }
231
66
  }, onFocus: () => {
232
67
  inputProps.onFocus && inputProps.onFocus();
233
68
  activatorProps.onFocus && activatorProps.onFocus();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "6.86.4",
3
+ "version": "6.86.5",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -543,5 +543,5 @@
543
543
  "> 1%",
544
544
  "IE 10"
545
545
  ],
546
- "gitHead": "ce44648ac1907d316c2df884b5d9c7056e8e2943"
546
+ "gitHead": "69bf4a19f39dc779173c705accb66f3514f80604"
547
547
  }