@jobber/components 6.12.1 → 6.13.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.
@@ -103,7 +103,7 @@ export interface CommonFormFieldProps {
103
103
  * Experimental:
104
104
  * Determine which version of the FormField to use.
105
105
  * Right now this isn't used but it will be used in the future
106
- * to allow us to release new versions of our form inputs without breaking existing functionality
106
+ * to allow us to release new versions of our form inputs without breaking existing functionality.
107
107
  */
108
108
  version?: 1;
109
109
  }
@@ -1,28 +1,2 @@
1
- import { CommonFormFieldProps, FormFieldProps } from "../FormField";
2
- interface InputDateProps extends Omit<CommonFormFieldProps, "clearable">, Pick<FormFieldProps, "readonly" | "disabled" | "onEnter" | "onFocus" | "inputRef" | "validations" | "placeholder" | "onChange" | "onBlur"> {
3
- /**
4
- * A Date object value
5
- * (e.g., `new Date("11/11/2011")`)
6
- * */
7
- readonly value?: Date;
8
- onChange(newValue: Date): void;
9
- /**
10
- * The maximum selectable date.
11
- */
12
- readonly maxDate?: Date;
13
- /**
14
- * The minimum selectable date.
15
- */
16
- readonly minDate?: Date;
17
- /**
18
- * Whether to show the calendar icon
19
- * @default true
20
- */
21
- readonly showIcon?: boolean;
22
- /**
23
- * Text to display instead of a date value
24
- */
25
- readonly emptyValueLabel?: string;
26
- }
1
+ import { InputDateProps } from "./InputDate.types";
27
2
  export declare function InputDate(inputProps: InputDateProps): JSX.Element;
28
- export {};
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ import { InputDateRebuiltProps } from "./InputDate.types";
3
+ export declare const InputDateRebuilt: React.ForwardRefExoticComponent<InputDateRebuiltProps & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,56 @@
1
+ import { CommonFormFieldProps, FormFieldProps } from "../FormField";
2
+ import { InputTextRebuiltProps } from "../InputText/InputText.types";
3
+ export interface InputDateRebuiltProps extends Omit<InputTextRebuiltProps, "clearable" | "onChange" | "value" | "prefix" | "suffix" | "multiline" | "rows" | "type" | "version"> {
4
+ /**
5
+ * A Date object value
6
+ * (e.g., `new Date("11/11/2011")`)
7
+ * */
8
+ readonly value?: Date;
9
+ /**
10
+ * The maximum selectable date.
11
+ */
12
+ readonly maxDate?: Date;
13
+ /**
14
+ * The minimum selectable date.
15
+ */
16
+ readonly minDate?: Date;
17
+ /**
18
+ * Whether to show the calendar icon
19
+ * @default true
20
+ */
21
+ readonly showIcon?: boolean;
22
+ /**
23
+ * Text to display instead of a date value
24
+ */
25
+ readonly emptyValueLabel?: string;
26
+ /**
27
+ * Version 2 is highly experimental, avoid using it unless you have talked with Atlantis first.
28
+ */
29
+ readonly version: 2;
30
+ readonly onChange: (newValue: Date, event?: React.ChangeEvent<HTMLInputElement>) => void;
31
+ }
32
+ export interface InputDateProps extends Omit<CommonFormFieldProps, "clearable">, Pick<FormFieldProps, "readonly" | "disabled" | "onEnter" | "onFocus" | "inputRef" | "validations" | "placeholder" | "onChange" | "onBlur"> {
33
+ /**
34
+ * A Date object value
35
+ * (e.g., `new Date("11/11/2011")`)
36
+ * */
37
+ readonly value?: Date;
38
+ onChange(newValue: Date): void;
39
+ /**
40
+ * The maximum selectable date.
41
+ */
42
+ readonly maxDate?: Date;
43
+ /**
44
+ * The minimum selectable date.
45
+ */
46
+ readonly minDate?: Date;
47
+ /**
48
+ * Whether to show the calendar icon
49
+ * @default true
50
+ */
51
+ readonly showIcon?: boolean;
52
+ /**
53
+ * Text to display instead of a date value
54
+ */
55
+ readonly emptyValueLabel?: string;
56
+ }
@@ -1,7 +1,16 @@
1
1
  'use strict';
2
2
 
3
- var InputDate = require('../InputDate-cjs.js');
4
- require('../omit-cjs.js');
3
+ var React = require('react');
4
+ var omit = require('../omit-cjs.js');
5
+ var FormField = require('../FormField-cjs.js');
6
+ require('../tslib.es6-cjs.js');
7
+ require('react-hook-form');
8
+ require('framer-motion');
9
+ require('@jobber/design');
10
+ require('classnames');
11
+ require('react-router-dom');
12
+ var DatePicker = require('../DatePicker-cjs.js');
13
+ var InputText_index = require('../InputText/index.cjs');
5
14
  require('../_commonjsHelpers-cjs.js');
6
15
  require('../_baseGet-cjs.js');
7
16
  require('../isTypedArray-cjs.js');
@@ -13,28 +22,140 @@ require('../keysIn-cjs.js');
13
22
  require('../_baseAssignValue-cjs.js');
14
23
  require('../_baseFlatten-cjs.js');
15
24
  require('../_setToString-cjs.js');
16
- require('react');
17
- require('../FormField-cjs.js');
18
- require('framer-motion');
19
- require('@jobber/design');
20
- require('classnames');
21
25
  require('../Button-cjs.js');
22
- require('react-router-dom');
23
26
  require('../Icon-cjs.js');
24
27
  require('../Typography-cjs.js');
25
28
  require('../Text-cjs.js');
26
29
  require('../useFormFieldFocus-cjs.js');
27
30
  require('../InputValidation-cjs.js');
28
31
  require('../Spinner-cjs.js');
29
- require('../tslib.es6-cjs.js');
30
- require('react-hook-form');
31
- require('../DatePicker-cjs.js');
32
32
  require('../index-cjs.js');
33
33
  require('react-dom');
34
34
  require('react-popper');
35
35
  require('../useRefocusOnActivator-cjs.js');
36
36
  require('../AtlantisContext-cjs.js');
37
+ require('../useSafeLayoutEffect-cjs.js');
38
+
39
+ function InputDate$1(inputProps) {
40
+ const formFieldActionsRef = React.useRef(null);
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 => {
42
+ const { onChange, onClick, value } = activatorProps;
43
+ const newActivatorProps = omit.omit(activatorProps, ["activator"]);
44
+ const [isFocused, setIsFocused] = React.useState(false);
45
+ const suffix = inputProps.showIcon !== false
46
+ ? {
47
+ icon: "calendar",
48
+ ariaLabel: "Show calendar",
49
+ onClick: onClick && onClick,
50
+ }
51
+ : undefined;
52
+ // Set form field to formatted date string immediately, to avoid validations
53
+ // triggering incorrectly when it blurs (to handle the datepicker UI click)
54
+ React.useEffect(() => {
55
+ var _a;
56
+ value && ((_a = formFieldActionsRef.current) === null || _a === void 0 ? void 0 : _a.setValue(value));
57
+ }, [value]);
58
+ const showEmptyValueLabel = !value && !isFocused;
59
+ return (
60
+ // We prevent the picker from opening on focus for keyboard navigation, so to maintain a good UX for mouse users we want to open the picker on click
61
+ React.createElement("div", { onClick: onClick },
62
+ React.createElement(FormField.FormField, Object.assign({}, newActivatorProps, inputProps, { value: showEmptyValueLabel ? inputProps.emptyValueLabel || "" : value, placeholder: inputProps.placeholder, onChange: (_, event) => {
63
+ onChange && onChange(event);
64
+ }, onBlur: () => {
65
+ inputProps.onBlur && inputProps.onBlur();
66
+ activatorProps.onBlur && activatorProps.onBlur();
67
+ setIsFocused(false);
68
+ }, onFocus: () => {
69
+ inputProps.onFocus && inputProps.onFocus();
70
+ activatorProps.onFocus && activatorProps.onFocus();
71
+ setIsFocused(true);
72
+ }, onKeyUp: event => {
73
+ var _a;
74
+ if (inputProps.showIcon === false &&
75
+ event.key === "ArrowDown") {
76
+ (_a = activatorProps.onClick) === null || _a === void 0 ? void 0 : _a.call(activatorProps);
77
+ }
78
+ }, actionsRef: formFieldActionsRef, suffix: suffix }))));
79
+ } }));
80
+ }
81
+
82
+ /**
83
+ * Combines the actions on the InputDate such as onChange, onFocus, onBlur to forward event handler passed to the InputDate component to the DatePicker component.
84
+ * DO not repeat this pattern. We are doing this as a proof of concept relating to the refactoring of Form inputs to see what can be removed.
85
+ */
86
+ function useInputDateActivatorActions({ onChange, onBlur, onFocus, }) {
87
+ const [isFocused, setIsFocused] = React.useState(false);
88
+ function handleChange(_, event) {
89
+ onChange === null || onChange === void 0 ? void 0 : onChange(event);
90
+ }
91
+ function handleFocus(event) {
92
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
93
+ setIsFocused(true);
94
+ }
95
+ function handleBlur(event) {
96
+ setIsFocused(false);
97
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
98
+ }
99
+ return {
100
+ handleBlur,
101
+ handleChange,
102
+ handleFocus,
103
+ isFocused,
104
+ };
105
+ }
37
106
 
107
+ const InputDateRebuilt = React.forwardRef(function InputDateInternal(props, inputRefs) {
108
+ const { onChange } = props;
109
+ return (React.createElement(DatePicker.DatePicker, { selected: props.value, onChange: newValue => {
110
+ onChange(newValue);
111
+ }, disabled: props.disabled, readonly: props.readOnly, fullWidth: !props.inline, minDate: props.minDate, maxDate: props.maxDate, smartAutofocus: false, activator: InputDateActivator }));
112
+ function InputDateActivator(activatorProps) {
113
+ const { onClick, value } = activatorProps;
114
+ const newActivatorProps = omit.omit(activatorProps, ["activator", "fullWidth"]);
115
+ const { handleChange, handleFocus, handleBlur, isFocused } = useInputDateActivatorActions({
116
+ onChange: newActivatorProps.onChange,
117
+ onFocus: event => {
118
+ var _a, _b;
119
+ (_a = props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props, event);
120
+ (_b = newActivatorProps.onFocus) === null || _b === void 0 ? void 0 : _b.call(newActivatorProps);
121
+ },
122
+ onBlur: event => {
123
+ var _a, _b;
124
+ (_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, event);
125
+ (_b = newActivatorProps.onBlur) === null || _b === void 0 ? void 0 : _b.call(newActivatorProps);
126
+ },
127
+ });
128
+ const suffix = props.showIcon !== false
129
+ ? {
130
+ icon: "calendar",
131
+ ariaLabel: "Show calendar",
132
+ onClick: onClick && onClick,
133
+ }
134
+ : undefined;
135
+ const showEmptyValueLabel = !value && !isFocused;
136
+ return (
137
+ // We prevent the picker from opening on focus for keyboard navigation, so to maintain a good UX for mouse users we want to open the picker on click
138
+ React.createElement("div", { onClick: onClick },
139
+ React.createElement(InputText_index.InputText, Object.assign({}, newActivatorProps, props, { version: 2, value: showEmptyValueLabel ? props.emptyValueLabel || "" : value || "", ref: inputRefs, suffix: suffix, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: event => {
140
+ var _a, _b;
141
+ if (props.showIcon === false && event.key === "ArrowDown") {
142
+ (_a = activatorProps.onClick) === null || _a === void 0 ? void 0 : _a.call(activatorProps);
143
+ }
144
+ (_b = props.onKeyDown) === null || _b === void 0 ? void 0 : _b.call(props, event);
145
+ }, onChange: handleChange }))));
146
+ }
147
+ });
38
148
 
149
+ function isNewInputDateProps(props) {
150
+ return props.version === 2;
151
+ }
152
+ const InputDate = React.forwardRef(function InputDateShim(props, ref) {
153
+ if (isNewInputDateProps(props)) {
154
+ return React.createElement(InputDateRebuilt, Object.assign({}, props, { ref: ref }));
155
+ }
156
+ else {
157
+ return React.createElement(InputDate$1, Object.assign({}, props));
158
+ }
159
+ });
39
160
 
40
- exports.InputDate = InputDate.InputDate;
161
+ exports.InputDate = InputDate;
@@ -1 +1,4 @@
1
- export { InputDate } from "./InputDate";
1
+ import React from "react";
2
+ import { InputDateProps as InputDateLegacyProps, InputDateRebuiltProps } from "./InputDate.types";
3
+ export type InputDateProps = InputDateLegacyProps | InputDateRebuiltProps;
4
+ export declare const InputDate: React.ForwardRefExoticComponent<InputDateProps & React.RefAttributes<HTMLInputElement>>;
@@ -1,5 +1,14 @@
1
- export { I as InputDate } from '../InputDate-es.js';
2
- import '../omit-es.js';
1
+ import React, { useRef, useState, useEffect, forwardRef } from 'react';
2
+ import { o as omit } from '../omit-es.js';
3
+ import { f as FormField } from '../FormField-es.js';
4
+ import '../tslib.es6-es.js';
5
+ import 'react-hook-form';
6
+ import 'framer-motion';
7
+ import '@jobber/design';
8
+ import 'classnames';
9
+ import 'react-router-dom';
10
+ import { D as DatePicker } from '../DatePicker-es.js';
11
+ import { InputText } from '../InputText/index.mjs';
3
12
  import '../_commonjsHelpers-es.js';
4
13
  import '../_baseGet-es.js';
5
14
  import '../isTypedArray-es.js';
@@ -11,24 +20,140 @@ import '../keysIn-es.js';
11
20
  import '../_baseAssignValue-es.js';
12
21
  import '../_baseFlatten-es.js';
13
22
  import '../_setToString-es.js';
14
- import 'react';
15
- import '../FormField-es.js';
16
- import 'framer-motion';
17
- import '@jobber/design';
18
- import 'classnames';
19
23
  import '../Button-es.js';
20
- import 'react-router-dom';
21
24
  import '../Icon-es.js';
22
25
  import '../Typography-es.js';
23
26
  import '../Text-es.js';
24
27
  import '../useFormFieldFocus-es.js';
25
28
  import '../InputValidation-es.js';
26
29
  import '../Spinner-es.js';
27
- import '../tslib.es6-es.js';
28
- import 'react-hook-form';
29
- import '../DatePicker-es.js';
30
30
  import '../index-es.js';
31
31
  import 'react-dom';
32
32
  import 'react-popper';
33
33
  import '../useRefocusOnActivator-es.js';
34
34
  import '../AtlantisContext-es.js';
35
+ import '../useSafeLayoutEffect-es.js';
36
+
37
+ function InputDate$1(inputProps) {
38
+ const formFieldActionsRef = useRef(null);
39
+ return (React.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 => {
40
+ const { onChange, onClick, value } = activatorProps;
41
+ const newActivatorProps = omit(activatorProps, ["activator"]);
42
+ const [isFocused, setIsFocused] = useState(false);
43
+ const suffix = inputProps.showIcon !== false
44
+ ? {
45
+ icon: "calendar",
46
+ ariaLabel: "Show calendar",
47
+ onClick: onClick && onClick,
48
+ }
49
+ : undefined;
50
+ // Set form field to formatted date string immediately, to avoid validations
51
+ // triggering incorrectly when it blurs (to handle the datepicker UI click)
52
+ useEffect(() => {
53
+ var _a;
54
+ value && ((_a = formFieldActionsRef.current) === null || _a === void 0 ? void 0 : _a.setValue(value));
55
+ }, [value]);
56
+ const showEmptyValueLabel = !value && !isFocused;
57
+ return (
58
+ // We prevent the picker from opening on focus for keyboard navigation, so to maintain a good UX for mouse users we want to open the picker on click
59
+ React.createElement("div", { onClick: onClick },
60
+ React.createElement(FormField, Object.assign({}, newActivatorProps, inputProps, { value: showEmptyValueLabel ? inputProps.emptyValueLabel || "" : value, placeholder: inputProps.placeholder, onChange: (_, event) => {
61
+ onChange && onChange(event);
62
+ }, onBlur: () => {
63
+ inputProps.onBlur && inputProps.onBlur();
64
+ activatorProps.onBlur && activatorProps.onBlur();
65
+ setIsFocused(false);
66
+ }, onFocus: () => {
67
+ inputProps.onFocus && inputProps.onFocus();
68
+ activatorProps.onFocus && activatorProps.onFocus();
69
+ setIsFocused(true);
70
+ }, onKeyUp: event => {
71
+ var _a;
72
+ if (inputProps.showIcon === false &&
73
+ event.key === "ArrowDown") {
74
+ (_a = activatorProps.onClick) === null || _a === void 0 ? void 0 : _a.call(activatorProps);
75
+ }
76
+ }, actionsRef: formFieldActionsRef, suffix: suffix }))));
77
+ } }));
78
+ }
79
+
80
+ /**
81
+ * Combines the actions on the InputDate such as onChange, onFocus, onBlur to forward event handler passed to the InputDate component to the DatePicker component.
82
+ * DO not repeat this pattern. We are doing this as a proof of concept relating to the refactoring of Form inputs to see what can be removed.
83
+ */
84
+ function useInputDateActivatorActions({ onChange, onBlur, onFocus, }) {
85
+ const [isFocused, setIsFocused] = useState(false);
86
+ function handleChange(_, event) {
87
+ onChange === null || onChange === void 0 ? void 0 : onChange(event);
88
+ }
89
+ function handleFocus(event) {
90
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
91
+ setIsFocused(true);
92
+ }
93
+ function handleBlur(event) {
94
+ setIsFocused(false);
95
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
96
+ }
97
+ return {
98
+ handleBlur,
99
+ handleChange,
100
+ handleFocus,
101
+ isFocused,
102
+ };
103
+ }
104
+
105
+ const InputDateRebuilt = forwardRef(function InputDateInternal(props, inputRefs) {
106
+ const { onChange } = props;
107
+ return (React.createElement(DatePicker, { selected: props.value, onChange: newValue => {
108
+ onChange(newValue);
109
+ }, disabled: props.disabled, readonly: props.readOnly, fullWidth: !props.inline, minDate: props.minDate, maxDate: props.maxDate, smartAutofocus: false, activator: InputDateActivator }));
110
+ function InputDateActivator(activatorProps) {
111
+ const { onClick, value } = activatorProps;
112
+ const newActivatorProps = omit(activatorProps, ["activator", "fullWidth"]);
113
+ const { handleChange, handleFocus, handleBlur, isFocused } = useInputDateActivatorActions({
114
+ onChange: newActivatorProps.onChange,
115
+ onFocus: event => {
116
+ var _a, _b;
117
+ (_a = props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props, event);
118
+ (_b = newActivatorProps.onFocus) === null || _b === void 0 ? void 0 : _b.call(newActivatorProps);
119
+ },
120
+ onBlur: event => {
121
+ var _a, _b;
122
+ (_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, event);
123
+ (_b = newActivatorProps.onBlur) === null || _b === void 0 ? void 0 : _b.call(newActivatorProps);
124
+ },
125
+ });
126
+ const suffix = props.showIcon !== false
127
+ ? {
128
+ icon: "calendar",
129
+ ariaLabel: "Show calendar",
130
+ onClick: onClick && onClick,
131
+ }
132
+ : undefined;
133
+ const showEmptyValueLabel = !value && !isFocused;
134
+ return (
135
+ // We prevent the picker from opening on focus for keyboard navigation, so to maintain a good UX for mouse users we want to open the picker on click
136
+ React.createElement("div", { onClick: onClick },
137
+ React.createElement(InputText, Object.assign({}, newActivatorProps, props, { version: 2, value: showEmptyValueLabel ? props.emptyValueLabel || "" : value || "", ref: inputRefs, suffix: suffix, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: event => {
138
+ var _a, _b;
139
+ if (props.showIcon === false && event.key === "ArrowDown") {
140
+ (_a = activatorProps.onClick) === null || _a === void 0 ? void 0 : _a.call(activatorProps);
141
+ }
142
+ (_b = props.onKeyDown) === null || _b === void 0 ? void 0 : _b.call(props, event);
143
+ }, onChange: handleChange }))));
144
+ }
145
+ });
146
+
147
+ function isNewInputDateProps(props) {
148
+ return props.version === 2;
149
+ }
150
+ const InputDate = forwardRef(function InputDateShim(props, ref) {
151
+ if (isNewInputDateProps(props)) {
152
+ return React.createElement(InputDateRebuilt, Object.assign({}, props, { ref: ref }));
153
+ }
154
+ else {
155
+ return React.createElement(InputDate$1, Object.assign({}, props));
156
+ }
157
+ });
158
+
159
+ export { InputDate };
@@ -0,0 +1,16 @@
1
+ import { ChangeEvent, FocusEvent } from "react";
2
+ import { InputDateRebuiltProps } from "./InputDate.types";
3
+ import { DatePickerActivatorProps } from "../DatePicker/DatePickerActivator";
4
+ export interface useInputDateActivatorActionsProps extends Pick<InputDateRebuiltProps, "onFocus" | "onBlur"> {
5
+ onChange: DatePickerActivatorProps["onChange"];
6
+ }
7
+ /**
8
+ * Combines the actions on the InputDate such as onChange, onFocus, onBlur to forward event handler passed to the InputDate component to the DatePicker component.
9
+ * DO not repeat this pattern. We are doing this as a proof of concept relating to the refactoring of Form inputs to see what can be removed.
10
+ */
11
+ export declare function useInputDateActivatorActions({ onChange, onBlur, onFocus, }: useInputDateActivatorActionsProps): {
12
+ handleBlur: (event: FocusEvent<HTMLInputElement>) => void;
13
+ handleChange: (_: unknown, event?: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
14
+ handleFocus: (event: FocusEvent<HTMLInputElement>) => void;
15
+ isFocused: boolean;
16
+ };
@@ -159,7 +159,7 @@ function insertAtCursor(input, newText) {
159
159
  * Combines the actions on the InputText such as onChange, onEnter, onFocus, onBlur, and onClear to forward information to the consumers of the InputText.
160
160
  * DO not repeat this pattern. We are doing this as a proof of concept relating to the refactoring of Form inputs to see what can be removed.
161
161
  */
162
- function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, }) {
162
+ function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, onKeyDown, }) {
163
163
  function handleClear() {
164
164
  var _a;
165
165
  handleBlur();
@@ -171,6 +171,7 @@ function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, })
171
171
  onChange === null || onChange === void 0 ? void 0 : onChange(newValue, event);
172
172
  }
173
173
  function handleKeyDown(event) {
174
+ onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
174
175
  if (!onEnter)
175
176
  return;
176
177
  if (event.key !== "Enter")
@@ -202,8 +203,8 @@ function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, })
202
203
  function useInputTextFormField(_a) {
203
204
  var { id, name, description, inline, handleChange, handleBlur, handleFocus, handleKeyDown, error } = _a, rest = tslib_es6.__rest(_a, ["id", "name", "description", "inline", "handleChange", "handleBlur", "handleFocus", "handleKeyDown", "error"]);
204
205
  const descriptionIdentifier = `descriptionUUID--${id}`;
205
- const fieldProps = Object.assign(Object.assign(Object.assign({ id, className: FormField.styles.input, name, disabled: rest.disabled, inputMode: rest.inputMode, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus }, (description &&
206
- !inline && { "aria-describedby": descriptionIdentifier })), { "aria-invalid": rest["aria-invalid"] || error || rest.invalid ? true : undefined, autoFocus: rest.autoFocus, invalid: error || rest.invalid ? "true" : undefined, onKeyDown: handleKeyDown }), rest);
206
+ const fieldProps = Object.assign(Object.assign(Object.assign(Object.assign({}, rest), { id, className: FormField.styles.input, name, disabled: rest.disabled, inputMode: rest.inputMode, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus }), (description &&
207
+ !inline && { "aria-describedby": descriptionIdentifier })), { "aria-invalid": rest["aria-invalid"] || error || rest.invalid ? true : undefined, autoFocus: rest.autoFocus, invalid: error || rest.invalid ? "true" : undefined, onKeyDown: handleKeyDown });
207
208
  return { fieldProps, descriptionIdentifier };
208
209
  }
209
210
 
@@ -229,6 +230,7 @@ const InputTextSPAR = React.forwardRef(function InputTextInternal(props, inputRe
229
230
  onChange: props.onChange,
230
231
  onBlur: props.onBlur,
231
232
  onFocus: props.onFocus,
233
+ onKeyDown: props.onKeyDown,
232
234
  onEnter: props.onEnter,
233
235
  inputRef: inputTextRef,
234
236
  });
@@ -157,7 +157,7 @@ function insertAtCursor(input, newText) {
157
157
  * Combines the actions on the InputText such as onChange, onEnter, onFocus, onBlur, and onClear to forward information to the consumers of the InputText.
158
158
  * DO not repeat this pattern. We are doing this as a proof of concept relating to the refactoring of Form inputs to see what can be removed.
159
159
  */
160
- function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, }) {
160
+ function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, onKeyDown, }) {
161
161
  function handleClear() {
162
162
  var _a;
163
163
  handleBlur();
@@ -169,6 +169,7 @@ function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, })
169
169
  onChange === null || onChange === void 0 ? void 0 : onChange(newValue, event);
170
170
  }
171
171
  function handleKeyDown(event) {
172
+ onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
172
173
  if (!onEnter)
173
174
  return;
174
175
  if (event.key !== "Enter")
@@ -200,8 +201,8 @@ function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, })
200
201
  function useInputTextFormField(_a) {
201
202
  var { id, name, description, inline, handleChange, handleBlur, handleFocus, handleKeyDown, error } = _a, rest = __rest(_a, ["id", "name", "description", "inline", "handleChange", "handleBlur", "handleFocus", "handleKeyDown", "error"]);
202
203
  const descriptionIdentifier = `descriptionUUID--${id}`;
203
- const fieldProps = Object.assign(Object.assign(Object.assign({ id, className: styles.input, name, disabled: rest.disabled, inputMode: rest.inputMode, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus }, (description &&
204
- !inline && { "aria-describedby": descriptionIdentifier })), { "aria-invalid": rest["aria-invalid"] || error || rest.invalid ? true : undefined, autoFocus: rest.autoFocus, invalid: error || rest.invalid ? "true" : undefined, onKeyDown: handleKeyDown }), rest);
204
+ const fieldProps = Object.assign(Object.assign(Object.assign(Object.assign({}, rest), { id, className: styles.input, name, disabled: rest.disabled, inputMode: rest.inputMode, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus }), (description &&
205
+ !inline && { "aria-describedby": descriptionIdentifier })), { "aria-invalid": rest["aria-invalid"] || error || rest.invalid ? true : undefined, autoFocus: rest.autoFocus, invalid: error || rest.invalid ? "true" : undefined, onKeyDown: handleKeyDown });
205
206
  return { fieldProps, descriptionIdentifier };
206
207
  }
207
208
 
@@ -227,6 +228,7 @@ const InputTextSPAR = forwardRef(function InputTextInternal(props, inputRefs) {
227
228
  onChange: props.onChange,
228
229
  onBlur: props.onBlur,
229
230
  onFocus: props.onFocus,
231
+ onKeyDown: props.onKeyDown,
230
232
  onEnter: props.onEnter,
231
233
  inputRef: inputTextRef,
232
234
  });
@@ -1,13 +1,13 @@
1
1
  import { ChangeEvent, FocusEvent, KeyboardEvent } from "react";
2
2
  import { InputTextRebuiltProps } from "./InputText.types";
3
- export interface useInputTextActionsProps extends Pick<InputTextRebuiltProps, "onChange" | "onEnter" | "onFocus" | "onBlur"> {
3
+ export interface useInputTextActionsProps extends Pick<InputTextRebuiltProps, "onChange" | "onEnter" | "onFocus" | "onBlur" | "onKeyDown"> {
4
4
  inputRef?: React.RefObject<HTMLInputElement | HTMLTextAreaElement>;
5
5
  }
6
6
  /**
7
7
  * Combines the actions on the InputText such as onChange, onEnter, onFocus, onBlur, and onClear to forward information to the consumers of the InputText.
8
8
  * DO not repeat this pattern. We are doing this as a proof of concept relating to the refactoring of Form inputs to see what can be removed.
9
9
  */
10
- export declare function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, }: useInputTextActionsProps): {
10
+ export declare function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, onKeyDown, }: useInputTextActionsProps): {
11
11
  handleClear: () => void;
12
12
  handleChange: (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
13
13
  handleKeyDown: (event: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
@@ -50,15 +50,25 @@ export interface UseInputTextFormFieldReturn {
50
50
  */
51
51
  export declare function useInputTextFormField({ id, name, description, inline, handleChange, handleBlur, handleFocus, handleKeyDown, error, ...rest }: useInputTextFormFieldProps): {
52
52
  fieldProps: {
53
- invalid: string | boolean | undefined;
53
+ "aria-invalid": boolean | undefined;
54
+ autoFocus: boolean | undefined;
55
+ invalid: string | undefined;
56
+ onKeyDown: (event: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
57
+ "aria-describedby"?: string | undefined;
58
+ id: string;
59
+ className: string;
60
+ name: string;
61
+ disabled: boolean | undefined;
62
+ inputMode: "none" | "text" | "search" | "tel" | "url" | "email" | "numeric" | "decimal" | undefined;
63
+ onChange: (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
64
+ onBlur: () => void;
65
+ onFocus: (event: FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
54
66
  accept?: string | undefined;
55
67
  alt?: string | undefined;
56
68
  autoComplete?: string | undefined;
57
- autoFocus: boolean | undefined;
58
69
  capture?: boolean | "user" | "environment" | undefined;
59
70
  checked?: boolean | undefined;
60
71
  crossOrigin?: "anonymous" | "use-credentials" | "" | undefined;
61
- disabled: boolean | undefined;
62
72
  enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined;
63
73
  form?: string | undefined;
64
74
  formAction?: string | undefined;
@@ -83,13 +93,11 @@ export declare function useInputTextFormField({ id, name, description, inline, h
83
93
  type?: import("react").HTMLInputTypeAttribute | undefined;
84
94
  value?: string | ReadonlyArray<string> | number | undefined;
85
95
  width?: number | string | undefined;
86
- onChange: (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
87
96
  defaultChecked?: boolean | undefined;
88
97
  defaultValue?: string | number | ReadonlyArray<string> | undefined;
89
98
  suppressContentEditableWarning?: boolean | undefined;
90
99
  suppressHydrationWarning?: boolean | undefined;
91
100
  accessKey?: string | undefined;
92
- className: string;
93
101
  contentEditable?: (boolean | "false" | "true") | "inherit" | undefined;
94
102
  contextMenu?: string | undefined;
95
103
  dir?: string | undefined;
@@ -125,7 +133,6 @@ export declare function useInputTextFormField({ id, name, description, inline, h
125
133
  results?: number | undefined;
126
134
  security?: string | undefined;
127
135
  unselectable?: "on" | "off" | undefined;
128
- inputMode: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined;
129
136
  is?: string | undefined;
130
137
  'aria-activedescendant'?: string | undefined;
131
138
  'aria-atomic'?: (boolean | "false" | "true") | undefined;
@@ -137,7 +144,6 @@ export declare function useInputTextFormField({ id, name, description, inline, h
137
144
  'aria-colspan'?: number | undefined;
138
145
  'aria-controls'?: string | undefined;
139
146
  'aria-current'?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined;
140
- "aria-describedby"?: string | undefined;
141
147
  'aria-details'?: string | undefined;
142
148
  'aria-disabled'?: (boolean | "false" | "true") | undefined;
143
149
  'aria-dropeffect'?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined;
@@ -147,7 +153,6 @@ export declare function useInputTextFormField({ id, name, description, inline, h
147
153
  'aria-grabbed'?: (boolean | "false" | "true") | undefined;
148
154
  'aria-haspopup'?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined;
149
155
  'aria-hidden'?: (boolean | "false" | "true") | undefined;
150
- "aria-invalid": boolean | "false" | "true" | "grammar" | "spelling" | undefined;
151
156
  'aria-keyshortcuts'?: string | undefined;
152
157
  'aria-label'?: string | undefined;
153
158
  'aria-labelledby'?: string | undefined;
@@ -191,9 +196,7 @@ export declare function useInputTextFormField({ id, name, description, inline, h
191
196
  onCompositionStartCapture?: import("react").CompositionEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
192
197
  onCompositionUpdate?: import("react").CompositionEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
193
198
  onCompositionUpdateCapture?: import("react").CompositionEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
194
- onFocus: import("react").FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
195
199
  onFocusCapture?: import("react").FocusEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
196
- onBlur: import("react").FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
197
200
  onBlurCapture?: import("react").FocusEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
198
201
  onChangeCapture?: import("react").FormEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
199
202
  onBeforeInput?: import("react").FormEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
@@ -210,7 +213,6 @@ export declare function useInputTextFormField({ id, name, description, inline, h
210
213
  onLoadCapture?: import("react").ReactEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
211
214
  onError?: import("react").ReactEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
212
215
  onErrorCapture?: import("react").ReactEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
213
- onKeyDown: import("react").KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>;
214
216
  onKeyDownCapture?: import("react").KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
215
217
  onKeyPress?: import("react").KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
216
218
  onKeyPressCapture?: import("react").KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
@@ -340,8 +342,6 @@ export declare function useInputTextFormField({ id, name, description, inline, h
340
342
  onAnimationIterationCapture?: import("react").AnimationEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
341
343
  onTransitionEnd?: import("react").TransitionEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
342
344
  onTransitionEndCapture?: import("react").TransitionEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
343
- id: string;
344
- name: string;
345
345
  };
346
346
  descriptionIdentifier: string;
347
347
  };
package/dist/index.cjs CHANGED
@@ -49,7 +49,7 @@ var Grid = require('./Grid-cjs.js');
49
49
  var Heading = require('./Heading-cjs.js');
50
50
  var InlineLabel = require('./InlineLabel-cjs.js');
51
51
  var InputAvatar = require('./InputAvatar-cjs.js');
52
- var InputDate = require('./InputDate-cjs.js');
52
+ var InputDate_index = require('./InputDate/index.cjs');
53
53
  var InputEmail = require('./InputEmail-cjs.js');
54
54
  var InputFile = require('./InputFile-cjs.js');
55
55
  var InputGroup = require('./InputGroup-cjs.js');
@@ -244,7 +244,7 @@ exports.Grid = Grid.Grid;
244
244
  exports.Heading = Heading.Heading;
245
245
  exports.InlineLabel = InlineLabel.InlineLabel;
246
246
  exports.InputAvatar = InputAvatar.InputAvatar;
247
- exports.InputDate = InputDate.InputDate;
247
+ exports.InputDate = InputDate_index.InputDate;
248
248
  exports.InputEmail = InputEmail.InputEmail;
249
249
  exports.validationMessage = InputEmail.validationMessage;
250
250
  exports.InputFile = InputFile.InputFile;
package/dist/index.mjs CHANGED
@@ -47,7 +47,7 @@ export { G as GRID_TEST_ID, a as Grid } from './Grid-es.js';
47
47
  export { H as Heading } from './Heading-es.js';
48
48
  export { I as InlineLabel } from './InlineLabel-es.js';
49
49
  export { I as InputAvatar } from './InputAvatar-es.js';
50
- export { I as InputDate } from './InputDate-es.js';
50
+ export { InputDate } from './InputDate/index.mjs';
51
51
  export { I as InputEmail, v as validationMessage } from './InputEmail-es.js';
52
52
  export { I as InputFile, u as updateFiles } from './InputFile-es.js';
53
53
  export { I as InputGroup } from './InputGroup-es.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "6.12.1",
3
+ "version": "6.13.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -488,5 +488,5 @@
488
488
  "> 1%",
489
489
  "IE 10"
490
490
  ],
491
- "gitHead": "1a784622c21bff8c1719a88909490843f0941b7b"
491
+ "gitHead": "f0244f2c2569fdaf6722ca6f48df1342774d78e9"
492
492
  }
@@ -1,57 +0,0 @@
1
- 'use strict';
2
-
3
- var omit = require('./omit-cjs.js');
4
- var React = require('react');
5
- var FormField = require('./FormField-cjs.js');
6
- require('./tslib.es6-cjs.js');
7
- require('react-hook-form');
8
- require('framer-motion');
9
- require('@jobber/design');
10
- require('classnames');
11
- require('react-router-dom');
12
- var DatePicker = require('./DatePicker-cjs.js');
13
-
14
- function InputDate(inputProps) {
15
- const formFieldActionsRef = React.useRef(null);
16
- 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 => {
17
- const { onChange, onClick, value } = activatorProps;
18
- const newActivatorProps = omit.omit(activatorProps, ["activator"]);
19
- const [isFocused, setIsFocused] = React.useState(false);
20
- const suffix = inputProps.showIcon !== false
21
- ? {
22
- icon: "calendar",
23
- ariaLabel: "Show calendar",
24
- onClick: onClick && onClick,
25
- }
26
- : undefined;
27
- // Set form field to formatted date string immediately, to avoid validations
28
- // triggering incorrectly when it blurs (to handle the datepicker UI click)
29
- React.useEffect(() => {
30
- var _a;
31
- value && ((_a = formFieldActionsRef.current) === null || _a === void 0 ? void 0 : _a.setValue(value));
32
- }, [value]);
33
- const showEmptyValueLabel = !value && !isFocused;
34
- return (
35
- // We prevent the picker from opening on focus for keyboard navigation, so to maintain a good UX for mouse users we want to open the picker on click
36
- React.createElement("div", { onClick: onClick },
37
- React.createElement(FormField.FormField, Object.assign({}, newActivatorProps, inputProps, { value: showEmptyValueLabel ? inputProps.emptyValueLabel || "" : value, placeholder: inputProps.placeholder, onChange: (_, event) => {
38
- onChange && onChange(event);
39
- }, onBlur: () => {
40
- inputProps.onBlur && inputProps.onBlur();
41
- activatorProps.onBlur && activatorProps.onBlur();
42
- setIsFocused(false);
43
- }, onFocus: () => {
44
- inputProps.onFocus && inputProps.onFocus();
45
- activatorProps.onFocus && activatorProps.onFocus();
46
- setIsFocused(true);
47
- }, onKeyUp: event => {
48
- var _a;
49
- if (inputProps.showIcon === false &&
50
- event.key === "ArrowDown") {
51
- (_a = activatorProps.onClick) === null || _a === void 0 ? void 0 : _a.call(activatorProps);
52
- }
53
- }, actionsRef: formFieldActionsRef, suffix: suffix }))));
54
- } }));
55
- }
56
-
57
- exports.InputDate = InputDate;
@@ -1,55 +0,0 @@
1
- import { o as omit } from './omit-es.js';
2
- import React, { useRef, useState, useEffect } from 'react';
3
- import { f as FormField } from './FormField-es.js';
4
- import './tslib.es6-es.js';
5
- import 'react-hook-form';
6
- import 'framer-motion';
7
- import '@jobber/design';
8
- import 'classnames';
9
- import 'react-router-dom';
10
- import { D as DatePicker } from './DatePicker-es.js';
11
-
12
- function InputDate(inputProps) {
13
- const formFieldActionsRef = useRef(null);
14
- return (React.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 => {
15
- const { onChange, onClick, value } = activatorProps;
16
- const newActivatorProps = omit(activatorProps, ["activator"]);
17
- const [isFocused, setIsFocused] = useState(false);
18
- const suffix = inputProps.showIcon !== false
19
- ? {
20
- icon: "calendar",
21
- ariaLabel: "Show calendar",
22
- onClick: onClick && onClick,
23
- }
24
- : undefined;
25
- // Set form field to formatted date string immediately, to avoid validations
26
- // triggering incorrectly when it blurs (to handle the datepicker UI click)
27
- useEffect(() => {
28
- var _a;
29
- value && ((_a = formFieldActionsRef.current) === null || _a === void 0 ? void 0 : _a.setValue(value));
30
- }, [value]);
31
- const showEmptyValueLabel = !value && !isFocused;
32
- return (
33
- // We prevent the picker from opening on focus for keyboard navigation, so to maintain a good UX for mouse users we want to open the picker on click
34
- React.createElement("div", { onClick: onClick },
35
- React.createElement(FormField, Object.assign({}, newActivatorProps, inputProps, { value: showEmptyValueLabel ? inputProps.emptyValueLabel || "" : value, placeholder: inputProps.placeholder, onChange: (_, event) => {
36
- onChange && onChange(event);
37
- }, onBlur: () => {
38
- inputProps.onBlur && inputProps.onBlur();
39
- activatorProps.onBlur && activatorProps.onBlur();
40
- setIsFocused(false);
41
- }, onFocus: () => {
42
- inputProps.onFocus && inputProps.onFocus();
43
- activatorProps.onFocus && activatorProps.onFocus();
44
- setIsFocused(true);
45
- }, onKeyUp: event => {
46
- var _a;
47
- if (inputProps.showIcon === false &&
48
- event.key === "ArrowDown") {
49
- (_a = activatorProps.onClick) === null || _a === void 0 ? void 0 : _a.call(activatorProps);
50
- }
51
- }, actionsRef: formFieldActionsRef, suffix: suffix }))));
52
- } }));
53
- }
54
-
55
- export { InputDate as I };