@jobber/components 7.14.2 → 7.15.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.
Files changed (65) hide show
  1. package/dist/Autocomplete/index.cjs +4 -3
  2. package/dist/Autocomplete/index.mjs +3 -2
  3. package/dist/DataList/components/DataListSearch/index.cjs +2 -1
  4. package/dist/DataList/components/DataListSearch/index.mjs +2 -1
  5. package/dist/DataList/index.cjs +2 -1
  6. package/dist/DataList/index.mjs +2 -1
  7. package/dist/DataTable/index.cjs +2 -1
  8. package/dist/DataTable/index.mjs +2 -1
  9. package/dist/DatePicker/index.cjs +0 -1
  10. package/dist/DatePicker/index.mjs +0 -1
  11. package/dist/DatePicker-cjs.js +782 -4
  12. package/dist/DatePicker-es.js +782 -4
  13. package/dist/FormField/index.cjs +14 -13
  14. package/dist/FormField/index.mjs +5 -4
  15. package/dist/FormField-cjs.js +4 -3
  16. package/dist/FormField-es.js +2 -1
  17. package/dist/FormFieldPostFix-cjs.js +2 -237
  18. package/dist/FormFieldPostFix-es.js +3 -228
  19. package/dist/FormFieldWrapper-cjs.js +242 -0
  20. package/dist/FormFieldWrapper-es.js +231 -0
  21. package/dist/InputDate/index.cjs +2 -2
  22. package/dist/InputDate/index.mjs +2 -2
  23. package/dist/InputEmail/index.cjs +2 -1
  24. package/dist/InputEmail/index.mjs +2 -1
  25. package/dist/InputEmail-cjs.js +3 -2
  26. package/dist/InputEmail-es.js +2 -1
  27. package/dist/InputNumber/index.cjs +2 -1
  28. package/dist/InputNumber/index.mjs +2 -1
  29. package/dist/InputPassword/index.cjs +2 -1
  30. package/dist/InputPassword/index.mjs +2 -1
  31. package/dist/InputPhoneNumber/index.cjs +2 -1
  32. package/dist/InputPhoneNumber/index.mjs +2 -1
  33. package/dist/InputPhoneNumber-cjs.js +3 -2
  34. package/dist/InputPhoneNumber-es.js +2 -1
  35. package/dist/InputText/index.cjs +3 -2
  36. package/dist/InputText/index.mjs +2 -1
  37. package/dist/InputTime/InputTime.d.ts +1 -1
  38. package/dist/InputTime/InputTime.types.d.ts +10 -24
  39. package/dist/InputTime/hooks/useInputTimeActions.d.ts +2 -2
  40. package/dist/InputTime/index.cjs +16 -350
  41. package/dist/InputTime/index.d.ts +2 -4
  42. package/dist/InputTime/index.mjs +15 -353
  43. package/dist/InputTime-cjs.js +300 -0
  44. package/dist/InputTime-es.js +298 -0
  45. package/dist/RecurringSelect/index.cjs +2 -1
  46. package/dist/RecurringSelect/index.mjs +2 -1
  47. package/dist/Select/index.cjs +2 -1
  48. package/dist/Select/index.mjs +2 -1
  49. package/dist/Select-cjs.js +3 -2
  50. package/dist/Select-es.js +2 -1
  51. package/dist/Tabs-es.js +1 -1
  52. package/dist/_baseEach-es.js +2 -2
  53. package/dist/_getAllKeys-es.js +1 -1
  54. package/dist/debounce-es.js +1 -1
  55. package/dist/docs/InputTime/InputTime.md +45 -27
  56. package/dist/docs/usage-guidelines/usage-guidelines.md +0 -1
  57. package/dist/index.cjs +13 -13
  58. package/dist/index.mjs +3 -3
  59. package/dist/isTypedArray-es.js +1 -1
  60. package/dist/styles.css +7 -2
  61. package/dist/useScrollToActive-es.js +1 -1
  62. package/package.json +2 -2
  63. package/dist/InputTime/InputTime.rebuilt.d.ts +0 -3
  64. package/dist/omit-cjs.js +0 -783
  65. package/dist/omit-es.js +0 -781
@@ -0,0 +1,242 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var jobberHooks = require('@jobber/hooks');
5
+ var framerMotion = require('framer-motion');
6
+ var design = require('@jobber/design');
7
+ var classnames = require('classnames');
8
+ var Button = require('./Button-cjs.js');
9
+ var Icon = require('./Icon-cjs.js');
10
+ var Text = require('./Text-cjs.js');
11
+ var useFormFieldFocus = require('./useFormFieldFocus-cjs.js');
12
+ var InputValidation = require('./InputValidation-cjs.js');
13
+
14
+ var formFieldStyles = {"container":"YL-mNv-Bl6g-","wrapper":"_8lhbGTQ-hhg-","disabled":"Tz9LK9ABKMk-","horizontalWrapper":"b5mv1x1H7YE-","textarea":"hGr6YW4AeLM-","safari":"QBCWi9GBgMs-","timeInputLabel":"_0pmqVa2zSE4-","miniLabel":"F1t76G6bDKo-","large":"_9tjyT9QUtP8-","text":"QmMiyoAWp-g-","invalid":"XWDSfe6weSY-","small":"Sw5O4I0lMJg-","inline":"SaORbL7SYWY-","center":"ozy2UoT2vsg-","right":"_3TJdT91YD3c-","maxLength":"W6GrMqLy2qk-","inputWrapper":"-LmjnYRU0r0-","childrenWrapper":"yVXYv6hkuOA-","input":"vtSDcuzNr9Q-","emptyPhoneNumber":"MVhuQuzUBUs-","label":"Dgk00tzlODA-","select":"NwQGiWBWIsc-","externalLabel":"Qb8zQ8n-8vc-","postfix":"yTDzs9h1otI-","affixIcon":"m0YpdssD2dY-","suffix":"_-3mMnjSh6ok-","affixLabel":"-Wzcb0pBh5I-","description":"DHX5ijY3xIw-","toolbar":"AL-2brNI7dk-","spinning":"_8Rzv7CcDW80-"};
15
+
16
+ /**
17
+ * @internal Reach out to UX Foundations if using this component since it is possible it might change
18
+ */
19
+ function AffixLabel({ label, variation = "prefix", labelRef, }) {
20
+ const affixLabelClass = classnames(formFieldStyles.affixLabel, {
21
+ [formFieldStyles.suffix]: variation === "suffix",
22
+ });
23
+ if (!label)
24
+ return null;
25
+ return (React.createElement("div", { ref: labelRef, className: affixLabelClass }, label));
26
+ }
27
+ function AffixIcon({ icon, onClick, ariaLabel, variation = "prefix", size, }) {
28
+ const affixIconClass = classnames(formFieldStyles.affixIcon, {
29
+ [formFieldStyles.suffix]: variation === "suffix",
30
+ });
31
+ const iconSize = size === "small" ? "small" : "base";
32
+ if (!icon)
33
+ return null;
34
+ return (React.createElement("div", { className: affixIconClass }, onClick ? (React.createElement(Button.Button
35
+ /**
36
+ * We can cast the ariaLabel here as a `Suffix`
37
+ * requires an ariaLabel if there is an action
38
+ */
39
+ , {
40
+ /**
41
+ * We can cast the ariaLabel here as a `Suffix`
42
+ * requires an ariaLabel if there is an action
43
+ */
44
+ ariaLabel: ariaLabel, icon: icon, onClick: onClick, variation: "subtle", type: "tertiary", size: iconSize })) : (React.createElement(Icon.Icon, { name: icon, size: iconSize, color: "greyBlue" }))));
45
+ }
46
+
47
+ function FormFieldDescription({ id, description, visible = true, }) {
48
+ if (!visible)
49
+ return null;
50
+ const useStringFormat = !description || typeof description === "string";
51
+ return (React.createElement("div", { id: id, className: formFieldStyles.description }, useStringFormat ? (React.createElement(Text.Text, { size: "small", variation: "subdued" }, description)) : (description)));
52
+ }
53
+
54
+ var styles = {"clearInput":"YmRTd-KeXv4-","spinning":"B25z9B8I3gs-"};
55
+
56
+ function ClearAction({ onClick, visible, }) {
57
+ if (!visible)
58
+ return null;
59
+ return (React.createElement("button", { className: styles.clearInput, onClick: onClick, type: "button", "aria-label": "Clear input", "data-testid": "ATL-FormField-clearButton" },
60
+ React.createElement(Icon.Icon, { name: "remove", size: "small" })));
61
+ }
62
+
63
+ function useToolbar(props) {
64
+ const isToolbarVisible = props.toolbar !== undefined &&
65
+ (props.toolbarVisibility === "always" || props.focused);
66
+ const toolbarAnimationEnd = { opacity: 0, height: 0 };
67
+ const toolbarAnimationStart = { opacity: 1, height: "auto" };
68
+ return {
69
+ isToolbarVisible,
70
+ toolbarAnimationEnd,
71
+ toolbarAnimationStart,
72
+ };
73
+ }
74
+
75
+ function useIsSafari() {
76
+ return (globalThis === null || globalThis === void 0 ? void 0 : globalThis.navigator)
77
+ ? /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
78
+ : false;
79
+ }
80
+
81
+ /**
82
+ * Hook for getting the correct styles for the FormField and its children
83
+ */
84
+ function useFormFieldWrapperStyles({ size, align, placeholder, value, invalid, error, max, prefixRef, suffixRef, maxLength, type, disabled, inline, showMiniLabel = true, }) {
85
+ const isSafari = useIsSafari();
86
+ const wrapperClasses = classnames(formFieldStyles.wrapper, size && formFieldStyles[size], align && formFieldStyles[align], {
87
+ [formFieldStyles.miniLabel]: (showMiniLabel && placeholder && value !== "") ||
88
+ (placeholder && type === "select") ||
89
+ // Naively assume that if the the type is tel, it is the InputPhoneNumber
90
+ (placeholder && type === "tel"),
91
+ [formFieldStyles.text]: type === "textarea" || type === "text",
92
+ [formFieldStyles.textarea]: type === "textarea",
93
+ [formFieldStyles.safari]: isSafari && type === "textarea",
94
+ [formFieldStyles.select]: type === "select",
95
+ [formFieldStyles.invalid]: invalid !== null && invalid !== void 0 ? invalid : error,
96
+ [formFieldStyles.disabled]: disabled,
97
+ [formFieldStyles.maxLength]: maxLength,
98
+ [formFieldStyles.timeInputLabel]: placeholder && type === "time" && placeholder && value === "",
99
+ });
100
+ const containerClasses = classnames(formFieldStyles.container, {
101
+ [formFieldStyles.inline]: inline,
102
+ });
103
+ const wrapperInlineStyle = {
104
+ ["--formField-maxLength"]: maxLength || max,
105
+ };
106
+ const [labelStyle, setLabelStyle] = React.useState({
107
+ paddingLeft: undefined,
108
+ paddingRight: undefined,
109
+ });
110
+ React.useEffect(() => {
111
+ var _a, _b;
112
+ setLabelStyle(getAffixPaddding({
113
+ value,
114
+ type,
115
+ prefixWidth: ((_a = prefixRef === null || prefixRef === void 0 ? void 0 : prefixRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0,
116
+ suffixWidth: ((_b = suffixRef === null || suffixRef === void 0 ? void 0 : suffixRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth) || 0,
117
+ }));
118
+ }, [value]);
119
+ return {
120
+ inputStyle: formFieldStyles.input,
121
+ wrapperClasses,
122
+ containerClasses,
123
+ wrapperInlineStyle,
124
+ labelStyle,
125
+ setLabelStyle,
126
+ };
127
+ }
128
+ function getAffixPaddding({ value, type, prefixWidth, suffixWidth, }) {
129
+ const hasValue = value !== "";
130
+ const newPadding = {
131
+ paddingLeft: undefined,
132
+ paddingRight: undefined,
133
+ };
134
+ // Naively assume that if the the type is tel, it is the InputPhoneNumber
135
+ if (type === "tel")
136
+ return newPadding;
137
+ if (prefixWidth && !hasValue) {
138
+ newPadding.paddingLeft = offset(prefixWidth);
139
+ }
140
+ if (suffixWidth && !hasValue) {
141
+ newPadding.paddingRight = offset(suffixWidth);
142
+ }
143
+ function offset(width) {
144
+ return `calc(${width}px + var(--space-smallest)`;
145
+ }
146
+ return newPadding;
147
+ }
148
+
149
+ function FormFieldWrapper({ align, description, descriptionIdentifier, placeholder, value, children, invalid, error, size, prefix, suffix, max, maxLength, type, disabled, inline, identifier, clearable, onClear, readonly, toolbar, toolbarVisibility = "while-editing", showMiniLabel = true, wrapperRef, }) {
150
+ const prefixRef = React.useRef(null);
151
+ const suffixRef = React.useRef(null);
152
+ const { wrapperClasses, containerClasses, wrapperInlineStyle, labelStyle } = useFormFieldWrapperStyles({
153
+ align,
154
+ max,
155
+ maxLength,
156
+ prefixRef,
157
+ suffixRef,
158
+ placeholder,
159
+ value,
160
+ invalid,
161
+ error,
162
+ type,
163
+ disabled,
164
+ inline,
165
+ size,
166
+ showMiniLabel,
167
+ });
168
+ const { focused } = useFormFieldFocus.useFormFieldFocus({ wrapperRef });
169
+ const showClear = jobberHooks.useShowClear({
170
+ clearable,
171
+ multiline: type === "textarea",
172
+ focused,
173
+ hasValue: Boolean(value),
174
+ disabled,
175
+ readonly,
176
+ });
177
+ const { isToolbarVisible, toolbarAnimationEnd, toolbarAnimationStart } = useToolbar({
178
+ focused,
179
+ toolbar,
180
+ toolbarVisibility,
181
+ });
182
+ return (React.createElement("div", { className: containerClasses },
183
+ React.createElement("div", { className: wrapperClasses, style: wrapperInlineStyle, "data-testid": "Form-Field-Wrapper", ref: wrapperRef },
184
+ React.createElement(FormFieldInputHorizontalWrapper, null,
185
+ React.createElement(AffixIcon, Object.assign({}, prefix, { size: size })),
186
+ React.createElement(FormFieldInputWrapperStyles, null,
187
+ (showMiniLabel || !value) && (React.createElement(FormFieldLabel, { htmlFor: identifier, style: (prefixRef === null || prefixRef === void 0 ? void 0 : prefixRef.current) || (suffixRef === null || suffixRef === void 0 ? void 0 : suffixRef.current)
188
+ ? labelStyle
189
+ : undefined }, placeholder)),
190
+ React.createElement(AffixLabel, Object.assign({}, prefix, { labelRef: prefixRef })),
191
+ React.createElement(FormFieldWrapperMain, null, children),
192
+ React.createElement(AffixLabel, Object.assign({}, suffix, { labelRef: suffixRef, variation: "suffix" }))),
193
+ React.createElement(ClearAction, { onClick: onClear, visible: showClear }),
194
+ React.createElement(AffixIcon, Object.assign({}, suffix, { variation: "suffix", size: size }))),
195
+ React.createElement(FormFieldWrapperToolbar, { toolbarVisibility: toolbarVisibility, isToolbarVisible: isToolbarVisible, toolbarAnimationEnd: toolbarAnimationEnd, toolbarAnimationStart: toolbarAnimationStart, toolbar: toolbar })),
196
+ React.createElement(FormFieldDescription, { visible: !!description && !inline, id: descriptionIdentifier, description: description }),
197
+ React.createElement(InputValidation.InputValidation, { message: error, visible: !!error && !inline })));
198
+ }
199
+ /**
200
+ * @internal Reach out to UX Foundations if using this component since it is possible it might change
201
+ */
202
+ function FormFieldInputHorizontalWrapper({ children, }) {
203
+ return React.createElement("div", { className: formFieldStyles.horizontalWrapper }, children);
204
+ }
205
+ /**
206
+ * @internal Reach out to UX Foundations if using this component since it is possible it might change
207
+ */
208
+ function FormFieldInputWrapperStyles({ children, }) {
209
+ return React.createElement("div", { className: formFieldStyles.inputWrapper }, children);
210
+ }
211
+ /**
212
+ * @internal Reach out to UX Foundations if using this component since it is possible it might change
213
+ */
214
+ function FormFieldWrapperMain({ children, tabIndex = -1, }) {
215
+ return (React.createElement("div", { className: formFieldStyles.childrenWrapper, tabIndex: tabIndex }, children));
216
+ }
217
+ function FormFieldLabel({ children, htmlFor, style, external = false, }) {
218
+ if (!children)
219
+ return null;
220
+ return (React.createElement("label", { className: external ? formFieldStyles.externalLabel : formFieldStyles.label, htmlFor: htmlFor, style: style }, children));
221
+ }
222
+ /**
223
+ * @internal Reach out to UX Foundations if using this component since it is possible it might change
224
+ */
225
+ function FormFieldWrapperToolbar({ toolbar, isToolbarVisible, toolbarAnimationEnd, toolbarAnimationStart, toolbarVisibility, }) {
226
+ return (React.createElement(framerMotion.AnimatePresence, { initial: toolbarVisibility === "always" ? false : true }, isToolbarVisible && (React.createElement(framerMotion.motion.div, { key: "toolbar", initial: toolbarAnimationEnd, animate: toolbarAnimationStart, exit: toolbarAnimationEnd, transition: {
227
+ duration: design.tokens["timing-base"] / 1000,
228
+ ease: "easeInOut",
229
+ }, tabIndex: -1 },
230
+ React.createElement("div", { className: formFieldStyles.toolbar, "data-testid": "ATL-InputText-Toolbar" }, toolbar)))));
231
+ }
232
+
233
+ exports.AffixIcon = AffixIcon;
234
+ exports.AffixLabel = AffixLabel;
235
+ exports.FormFieldInputHorizontalWrapper = FormFieldInputHorizontalWrapper;
236
+ exports.FormFieldInputWrapperStyles = FormFieldInputWrapperStyles;
237
+ exports.FormFieldLabel = FormFieldLabel;
238
+ exports.FormFieldWrapper = FormFieldWrapper;
239
+ exports.FormFieldWrapperMain = FormFieldWrapperMain;
240
+ exports.FormFieldWrapperToolbar = FormFieldWrapperToolbar;
241
+ exports.formFieldStyles = formFieldStyles;
242
+ exports.useFormFieldWrapperStyles = useFormFieldWrapperStyles;
@@ -0,0 +1,231 @@
1
+ import React__default, { useState, useEffect, useRef } from 'react';
2
+ import { useShowClear } from '@jobber/hooks';
3
+ import { AnimatePresence, motion } from 'framer-motion';
4
+ import { tokens } from '@jobber/design';
5
+ import classnames from 'classnames';
6
+ import { B as Button } from './Button-es.js';
7
+ import { I as Icon } from './Icon-es.js';
8
+ import { T as Text } from './Text-es.js';
9
+ import { u as useFormFieldFocus } from './useFormFieldFocus-es.js';
10
+ import { I as InputValidation } from './InputValidation-es.js';
11
+
12
+ var formFieldStyles = {"container":"YL-mNv-Bl6g-","wrapper":"_8lhbGTQ-hhg-","disabled":"Tz9LK9ABKMk-","horizontalWrapper":"b5mv1x1H7YE-","textarea":"hGr6YW4AeLM-","safari":"QBCWi9GBgMs-","timeInputLabel":"_0pmqVa2zSE4-","miniLabel":"F1t76G6bDKo-","large":"_9tjyT9QUtP8-","text":"QmMiyoAWp-g-","invalid":"XWDSfe6weSY-","small":"Sw5O4I0lMJg-","inline":"SaORbL7SYWY-","center":"ozy2UoT2vsg-","right":"_3TJdT91YD3c-","maxLength":"W6GrMqLy2qk-","inputWrapper":"-LmjnYRU0r0-","childrenWrapper":"yVXYv6hkuOA-","input":"vtSDcuzNr9Q-","emptyPhoneNumber":"MVhuQuzUBUs-","label":"Dgk00tzlODA-","select":"NwQGiWBWIsc-","externalLabel":"Qb8zQ8n-8vc-","postfix":"yTDzs9h1otI-","affixIcon":"m0YpdssD2dY-","suffix":"_-3mMnjSh6ok-","affixLabel":"-Wzcb0pBh5I-","description":"DHX5ijY3xIw-","toolbar":"AL-2brNI7dk-","spinning":"_8Rzv7CcDW80-"};
13
+
14
+ /**
15
+ * @internal Reach out to UX Foundations if using this component since it is possible it might change
16
+ */
17
+ function AffixLabel({ label, variation = "prefix", labelRef, }) {
18
+ const affixLabelClass = classnames(formFieldStyles.affixLabel, {
19
+ [formFieldStyles.suffix]: variation === "suffix",
20
+ });
21
+ if (!label)
22
+ return null;
23
+ return (React__default.createElement("div", { ref: labelRef, className: affixLabelClass }, label));
24
+ }
25
+ function AffixIcon({ icon, onClick, ariaLabel, variation = "prefix", size, }) {
26
+ const affixIconClass = classnames(formFieldStyles.affixIcon, {
27
+ [formFieldStyles.suffix]: variation === "suffix",
28
+ });
29
+ const iconSize = size === "small" ? "small" : "base";
30
+ if (!icon)
31
+ return null;
32
+ return (React__default.createElement("div", { className: affixIconClass }, onClick ? (React__default.createElement(Button
33
+ /**
34
+ * We can cast the ariaLabel here as a `Suffix`
35
+ * requires an ariaLabel if there is an action
36
+ */
37
+ , {
38
+ /**
39
+ * We can cast the ariaLabel here as a `Suffix`
40
+ * requires an ariaLabel if there is an action
41
+ */
42
+ ariaLabel: ariaLabel, icon: icon, onClick: onClick, variation: "subtle", type: "tertiary", size: iconSize })) : (React__default.createElement(Icon, { name: icon, size: iconSize, color: "greyBlue" }))));
43
+ }
44
+
45
+ function FormFieldDescription({ id, description, visible = true, }) {
46
+ if (!visible)
47
+ return null;
48
+ const useStringFormat = !description || typeof description === "string";
49
+ return (React__default.createElement("div", { id: id, className: formFieldStyles.description }, useStringFormat ? (React__default.createElement(Text, { size: "small", variation: "subdued" }, description)) : (description)));
50
+ }
51
+
52
+ var styles = {"clearInput":"YmRTd-KeXv4-","spinning":"B25z9B8I3gs-"};
53
+
54
+ function ClearAction({ onClick, visible, }) {
55
+ if (!visible)
56
+ return null;
57
+ return (React__default.createElement("button", { className: styles.clearInput, onClick: onClick, type: "button", "aria-label": "Clear input", "data-testid": "ATL-FormField-clearButton" },
58
+ React__default.createElement(Icon, { name: "remove", size: "small" })));
59
+ }
60
+
61
+ function useToolbar(props) {
62
+ const isToolbarVisible = props.toolbar !== undefined &&
63
+ (props.toolbarVisibility === "always" || props.focused);
64
+ const toolbarAnimationEnd = { opacity: 0, height: 0 };
65
+ const toolbarAnimationStart = { opacity: 1, height: "auto" };
66
+ return {
67
+ isToolbarVisible,
68
+ toolbarAnimationEnd,
69
+ toolbarAnimationStart,
70
+ };
71
+ }
72
+
73
+ function useIsSafari() {
74
+ return (globalThis === null || globalThis === void 0 ? void 0 : globalThis.navigator)
75
+ ? /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
76
+ : false;
77
+ }
78
+
79
+ /**
80
+ * Hook for getting the correct styles for the FormField and its children
81
+ */
82
+ function useFormFieldWrapperStyles({ size, align, placeholder, value, invalid, error, max, prefixRef, suffixRef, maxLength, type, disabled, inline, showMiniLabel = true, }) {
83
+ const isSafari = useIsSafari();
84
+ const wrapperClasses = classnames(formFieldStyles.wrapper, size && formFieldStyles[size], align && formFieldStyles[align], {
85
+ [formFieldStyles.miniLabel]: (showMiniLabel && placeholder && value !== "") ||
86
+ (placeholder && type === "select") ||
87
+ // Naively assume that if the the type is tel, it is the InputPhoneNumber
88
+ (placeholder && type === "tel"),
89
+ [formFieldStyles.text]: type === "textarea" || type === "text",
90
+ [formFieldStyles.textarea]: type === "textarea",
91
+ [formFieldStyles.safari]: isSafari && type === "textarea",
92
+ [formFieldStyles.select]: type === "select",
93
+ [formFieldStyles.invalid]: invalid !== null && invalid !== void 0 ? invalid : error,
94
+ [formFieldStyles.disabled]: disabled,
95
+ [formFieldStyles.maxLength]: maxLength,
96
+ [formFieldStyles.timeInputLabel]: placeholder && type === "time" && placeholder && value === "",
97
+ });
98
+ const containerClasses = classnames(formFieldStyles.container, {
99
+ [formFieldStyles.inline]: inline,
100
+ });
101
+ const wrapperInlineStyle = {
102
+ ["--formField-maxLength"]: maxLength || max,
103
+ };
104
+ const [labelStyle, setLabelStyle] = useState({
105
+ paddingLeft: undefined,
106
+ paddingRight: undefined,
107
+ });
108
+ useEffect(() => {
109
+ var _a, _b;
110
+ setLabelStyle(getAffixPaddding({
111
+ value,
112
+ type,
113
+ prefixWidth: ((_a = prefixRef === null || prefixRef === void 0 ? void 0 : prefixRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0,
114
+ suffixWidth: ((_b = suffixRef === null || suffixRef === void 0 ? void 0 : suffixRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth) || 0,
115
+ }));
116
+ }, [value]);
117
+ return {
118
+ inputStyle: formFieldStyles.input,
119
+ wrapperClasses,
120
+ containerClasses,
121
+ wrapperInlineStyle,
122
+ labelStyle,
123
+ setLabelStyle,
124
+ };
125
+ }
126
+ function getAffixPaddding({ value, type, prefixWidth, suffixWidth, }) {
127
+ const hasValue = value !== "";
128
+ const newPadding = {
129
+ paddingLeft: undefined,
130
+ paddingRight: undefined,
131
+ };
132
+ // Naively assume that if the the type is tel, it is the InputPhoneNumber
133
+ if (type === "tel")
134
+ return newPadding;
135
+ if (prefixWidth && !hasValue) {
136
+ newPadding.paddingLeft = offset(prefixWidth);
137
+ }
138
+ if (suffixWidth && !hasValue) {
139
+ newPadding.paddingRight = offset(suffixWidth);
140
+ }
141
+ function offset(width) {
142
+ return `calc(${width}px + var(--space-smallest)`;
143
+ }
144
+ return newPadding;
145
+ }
146
+
147
+ function FormFieldWrapper({ align, description, descriptionIdentifier, placeholder, value, children, invalid, error, size, prefix, suffix, max, maxLength, type, disabled, inline, identifier, clearable, onClear, readonly, toolbar, toolbarVisibility = "while-editing", showMiniLabel = true, wrapperRef, }) {
148
+ const prefixRef = useRef(null);
149
+ const suffixRef = useRef(null);
150
+ const { wrapperClasses, containerClasses, wrapperInlineStyle, labelStyle } = useFormFieldWrapperStyles({
151
+ align,
152
+ max,
153
+ maxLength,
154
+ prefixRef,
155
+ suffixRef,
156
+ placeholder,
157
+ value,
158
+ invalid,
159
+ error,
160
+ type,
161
+ disabled,
162
+ inline,
163
+ size,
164
+ showMiniLabel,
165
+ });
166
+ const { focused } = useFormFieldFocus({ wrapperRef });
167
+ const showClear = useShowClear({
168
+ clearable,
169
+ multiline: type === "textarea",
170
+ focused,
171
+ hasValue: Boolean(value),
172
+ disabled,
173
+ readonly,
174
+ });
175
+ const { isToolbarVisible, toolbarAnimationEnd, toolbarAnimationStart } = useToolbar({
176
+ focused,
177
+ toolbar,
178
+ toolbarVisibility,
179
+ });
180
+ return (React__default.createElement("div", { className: containerClasses },
181
+ React__default.createElement("div", { className: wrapperClasses, style: wrapperInlineStyle, "data-testid": "Form-Field-Wrapper", ref: wrapperRef },
182
+ React__default.createElement(FormFieldInputHorizontalWrapper, null,
183
+ React__default.createElement(AffixIcon, Object.assign({}, prefix, { size: size })),
184
+ React__default.createElement(FormFieldInputWrapperStyles, null,
185
+ (showMiniLabel || !value) && (React__default.createElement(FormFieldLabel, { htmlFor: identifier, style: (prefixRef === null || prefixRef === void 0 ? void 0 : prefixRef.current) || (suffixRef === null || suffixRef === void 0 ? void 0 : suffixRef.current)
186
+ ? labelStyle
187
+ : undefined }, placeholder)),
188
+ React__default.createElement(AffixLabel, Object.assign({}, prefix, { labelRef: prefixRef })),
189
+ React__default.createElement(FormFieldWrapperMain, null, children),
190
+ React__default.createElement(AffixLabel, Object.assign({}, suffix, { labelRef: suffixRef, variation: "suffix" }))),
191
+ React__default.createElement(ClearAction, { onClick: onClear, visible: showClear }),
192
+ React__default.createElement(AffixIcon, Object.assign({}, suffix, { variation: "suffix", size: size }))),
193
+ React__default.createElement(FormFieldWrapperToolbar, { toolbarVisibility: toolbarVisibility, isToolbarVisible: isToolbarVisible, toolbarAnimationEnd: toolbarAnimationEnd, toolbarAnimationStart: toolbarAnimationStart, toolbar: toolbar })),
194
+ React__default.createElement(FormFieldDescription, { visible: !!description && !inline, id: descriptionIdentifier, description: description }),
195
+ React__default.createElement(InputValidation, { message: error, visible: !!error && !inline })));
196
+ }
197
+ /**
198
+ * @internal Reach out to UX Foundations if using this component since it is possible it might change
199
+ */
200
+ function FormFieldInputHorizontalWrapper({ children, }) {
201
+ return React__default.createElement("div", { className: formFieldStyles.horizontalWrapper }, children);
202
+ }
203
+ /**
204
+ * @internal Reach out to UX Foundations if using this component since it is possible it might change
205
+ */
206
+ function FormFieldInputWrapperStyles({ children, }) {
207
+ return React__default.createElement("div", { className: formFieldStyles.inputWrapper }, children);
208
+ }
209
+ /**
210
+ * @internal Reach out to UX Foundations if using this component since it is possible it might change
211
+ */
212
+ function FormFieldWrapperMain({ children, tabIndex = -1, }) {
213
+ return (React__default.createElement("div", { className: formFieldStyles.childrenWrapper, tabIndex: tabIndex }, children));
214
+ }
215
+ function FormFieldLabel({ children, htmlFor, style, external = false, }) {
216
+ if (!children)
217
+ return null;
218
+ return (React__default.createElement("label", { className: external ? formFieldStyles.externalLabel : formFieldStyles.label, htmlFor: htmlFor, style: style }, children));
219
+ }
220
+ /**
221
+ * @internal Reach out to UX Foundations if using this component since it is possible it might change
222
+ */
223
+ function FormFieldWrapperToolbar({ toolbar, isToolbarVisible, toolbarAnimationEnd, toolbarAnimationStart, toolbarVisibility, }) {
224
+ return (React__default.createElement(AnimatePresence, { initial: toolbarVisibility === "always" ? false : true }, isToolbarVisible && (React__default.createElement(motion.div, { key: "toolbar", initial: toolbarAnimationEnd, animate: toolbarAnimationStart, exit: toolbarAnimationEnd, transition: {
225
+ duration: tokens["timing-base"] / 1000,
226
+ ease: "easeInOut",
227
+ }, tabIndex: -1 },
228
+ React__default.createElement("div", { className: formFieldStyles.toolbar, "data-testid": "ATL-InputText-Toolbar" }, toolbar)))));
229
+ }
230
+
231
+ export { AffixIcon as A, FormFieldInputHorizontalWrapper as F, FormFieldInputWrapperStyles as a, FormFieldLabel as b, FormFieldWrapper as c, FormFieldWrapperMain as d, FormFieldWrapperToolbar as e, AffixLabel as f, formFieldStyles as g, useFormFieldWrapperStyles as u };
@@ -18,7 +18,6 @@ require('../tslib.es6-cjs.js');
18
18
  require('react-router-dom');
19
19
  require('../Icon-cjs.js');
20
20
  require('@jobber/design');
21
- require('../omit-cjs.js');
22
21
  require('../_commonjsHelpers-cjs.js');
23
22
  require('../_getAllKeys-cjs.js');
24
23
  require('../isTypedArray-cjs.js');
@@ -33,11 +32,12 @@ require('../_setToString-cjs.js');
33
32
  require('../AtlantisContext-cjs.js');
34
33
  require('../InputText/index.cjs');
35
34
  require('../FormField-cjs.js');
36
- require('../FormFieldPostFix-cjs.js');
35
+ require('../FormFieldWrapper-cjs.js');
37
36
  require('framer-motion');
38
37
  require('../Text-cjs.js');
39
38
  require('../useFormFieldFocus-cjs.js');
40
39
  require('../InputValidation-cjs.js');
40
+ require('../FormFieldPostFix-cjs.js');
41
41
  require('../Spinner-cjs.js');
42
42
  require('../useAtlantisFormFieldName-cjs.js');
43
43
  require('react-hook-form');
@@ -16,7 +16,6 @@ import '../tslib.es6-es.js';
16
16
  import 'react-router-dom';
17
17
  import '../Icon-es.js';
18
18
  import '@jobber/design';
19
- import '../omit-es.js';
20
19
  import '../_commonjsHelpers-es.js';
21
20
  import '../_getAllKeys-es.js';
22
21
  import '../isTypedArray-es.js';
@@ -31,11 +30,12 @@ import '../_setToString-es.js';
31
30
  import '../AtlantisContext-es.js';
32
31
  import '../InputText/index.mjs';
33
32
  import '../FormField-es.js';
34
- import '../FormFieldPostFix-es.js';
33
+ import '../FormFieldWrapper-es.js';
35
34
  import 'framer-motion';
36
35
  import '../Text-es.js';
37
36
  import '../useFormFieldFocus-es.js';
38
37
  import '../InputValidation-es.js';
38
+ import '../FormFieldPostFix-es.js';
39
39
  import '../Spinner-es.js';
40
40
  import '../useAtlantisFormFieldName-es.js';
41
41
  import 'react-hook-form';
@@ -3,7 +3,7 @@
3
3
  var InputEmail = require('../InputEmail-cjs.js');
4
4
  require('react');
5
5
  require('../mergeRefs-cjs.js');
6
- require('../FormFieldPostFix-cjs.js');
6
+ require('../FormFieldWrapper-cjs.js');
7
7
  require('@jobber/hooks');
8
8
  require('framer-motion');
9
9
  require('@jobber/design');
@@ -16,6 +16,7 @@ require('../Typography-cjs.js');
16
16
  require('../Text-cjs.js');
17
17
  require('../useFormFieldFocus-cjs.js');
18
18
  require('../InputValidation-cjs.js');
19
+ require('../FormFieldPostFix-cjs.js');
19
20
  require('../Spinner-cjs.js');
20
21
  require('react-hook-form');
21
22
  require('../filterDataAttributes-cjs.js');
@@ -1,7 +1,7 @@
1
1
  export { I as InputEmail } from '../InputEmail-es.js';
2
2
  import 'react';
3
3
  import '../mergeRefs-es.js';
4
- import '../FormFieldPostFix-es.js';
4
+ import '../FormFieldWrapper-es.js';
5
5
  import '@jobber/hooks';
6
6
  import 'framer-motion';
7
7
  import '@jobber/design';
@@ -14,6 +14,7 @@ import '../Typography-es.js';
14
14
  import '../Text-es.js';
15
15
  import '../useFormFieldFocus-es.js';
16
16
  import '../InputValidation-es.js';
17
+ import '../FormFieldPostFix-es.js';
17
18
  import '../Spinner-es.js';
18
19
  import 'react-hook-form';
19
20
  import '../filterDataAttributes-es.js';
@@ -2,6 +2,7 @@
2
2
 
3
3
  var React = require('react');
4
4
  var mergeRefs = require('./mergeRefs-cjs.js');
5
+ var FormFieldWrapper = require('./FormFieldWrapper-cjs.js');
5
6
  var FormFieldPostFix = require('./FormFieldPostFix-cjs.js');
6
7
  require('classnames');
7
8
  require('./tslib.es6-cjs.js');
@@ -100,8 +101,8 @@ const InputEmail = React.forwardRef(function InputEmailInternal(props, ref) {
100
101
  const descriptionVisible = props.description && !props.inline;
101
102
  const isInvalid = Boolean(props.error || props.invalid);
102
103
  const dataAttrs = filterDataAttributes.filterDataAttributes(props);
103
- return (React.createElement(FormFieldPostFix.FormFieldWrapper, { error: props.error || "", invalid: props.invalid, identifier: id, descriptionIdentifier: descriptionIdentifier, size: props.size, inline: props.inline, align: props.align, prefix: props.prefix, suffix: props.suffix, description: props.description, clearable: (_a = props.clearable) !== null && _a !== void 0 ? _a : "never", onClear: handleClear, readonly: props.readOnly, wrapperRef: wrapperRef, disabled: props.disabled, type: "email", value: props.value, placeholder: props.placeholder, name: props.name },
104
- React.createElement("input", Object.assign({ id: id, name: props.name, type: "email", ref: mergedRef, className: FormFieldPostFix.formFieldStyles.input, value: props.value, disabled: props.disabled, readOnly: props.readOnly, autoFocus: props.autoFocus, autoComplete: props.autoComplete, pattern: props.pattern, inputMode: props.inputMode, tabIndex: props.tabIndex, maxLength: props.maxLength, required: props.required, role: props.role, "aria-label": props["aria-label"], "aria-describedby": descriptionVisible ? descriptionIdentifier : props["aria-describedby"], "aria-invalid": isInvalid ? true : undefined, "aria-controls": props["aria-controls"], "aria-expanded": props["aria-expanded"], "aria-activedescendant": props["aria-activedescendant"], "aria-autocomplete": props["aria-autocomplete"], "aria-required": props["aria-required"], onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onClick: handleClick, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, "data-testid": "ATL-InputEmail-input" }, dataAttrs)),
104
+ return (React.createElement(FormFieldWrapper.FormFieldWrapper, { error: props.error || "", invalid: props.invalid, identifier: id, descriptionIdentifier: descriptionIdentifier, size: props.size, inline: props.inline, align: props.align, prefix: props.prefix, suffix: props.suffix, description: props.description, clearable: (_a = props.clearable) !== null && _a !== void 0 ? _a : "never", onClear: handleClear, readonly: props.readOnly, wrapperRef: wrapperRef, disabled: props.disabled, type: "email", value: props.value, placeholder: props.placeholder, name: props.name },
105
+ React.createElement("input", Object.assign({ id: id, name: props.name, type: "email", ref: mergedRef, className: FormFieldWrapper.formFieldStyles.input, value: props.value, disabled: props.disabled, readOnly: props.readOnly, autoFocus: props.autoFocus, autoComplete: props.autoComplete, pattern: props.pattern, inputMode: props.inputMode, tabIndex: props.tabIndex, maxLength: props.maxLength, required: props.required, role: props.role, "aria-label": props["aria-label"], "aria-describedby": descriptionVisible ? descriptionIdentifier : props["aria-describedby"], "aria-invalid": isInvalid ? true : undefined, "aria-controls": props["aria-controls"], "aria-expanded": props["aria-expanded"], "aria-activedescendant": props["aria-activedescendant"], "aria-autocomplete": props["aria-autocomplete"], "aria-required": props["aria-required"], onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onClick: handleClick, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, "data-testid": "ATL-InputEmail-input" }, dataAttrs)),
105
106
  React.createElement(FormFieldPostFix.FormFieldPostFix, { variation: "spinner", visible: (_b = props.loading) !== null && _b !== void 0 ? _b : false })));
106
107
  });
107
108
 
@@ -1,6 +1,7 @@
1
1
  import React__default, { useRef, forwardRef, useId } from 'react';
2
2
  import { m as mergeRefs } from './mergeRefs-es.js';
3
- import { c as FormFieldWrapper, g as formFieldStyles, h as FormFieldPostFix } from './FormFieldPostFix-es.js';
3
+ import { c as FormFieldWrapper, g as formFieldStyles } from './FormFieldWrapper-es.js';
4
+ import { F as FormFieldPostFix } from './FormFieldPostFix-es.js';
4
5
  import 'classnames';
5
6
  import './tslib.es6-es.js';
6
7
  import 'react-hook-form';
@@ -14,9 +14,10 @@ require('framer-motion');
14
14
  require('@jobber/design');
15
15
  require('../Button-cjs.js');
16
16
  require('../Typography-cjs.js');
17
- require('../FormFieldPostFix-cjs.js');
17
+ require('../FormFieldWrapper-cjs.js');
18
18
  require('../useFormFieldFocus-cjs.js');
19
19
  require('../InputValidation-cjs.js');
20
+ require('../FormFieldPostFix-cjs.js');
20
21
  require('../Spinner-cjs.js');
21
22
  require('../useAtlantisFormFieldName-cjs.js');
22
23
  require('../mergeRefs-cjs.js');
@@ -12,9 +12,10 @@ import 'framer-motion';
12
12
  import '@jobber/design';
13
13
  import '../Button-es.js';
14
14
  import '../Typography-es.js';
15
- import '../FormFieldPostFix-es.js';
15
+ import '../FormFieldWrapper-es.js';
16
16
  import '../useFormFieldFocus-es.js';
17
17
  import '../InputValidation-es.js';
18
+ import '../FormFieldPostFix-es.js';
18
19
  import '../Spinner-es.js';
19
20
  import '../useAtlantisFormFieldName-es.js';
20
21
  import '../mergeRefs-es.js';
@@ -3,7 +3,7 @@
3
3
  var InputPassword = require('../InputPassword-cjs.js');
4
4
  require('react');
5
5
  require('../FormField-cjs.js');
6
- require('../FormFieldPostFix-cjs.js');
6
+ require('../FormFieldWrapper-cjs.js');
7
7
  require('@jobber/hooks');
8
8
  require('framer-motion');
9
9
  require('@jobber/design');
@@ -16,6 +16,7 @@ require('../Typography-cjs.js');
16
16
  require('../Text-cjs.js');
17
17
  require('../useFormFieldFocus-cjs.js');
18
18
  require('../InputValidation-cjs.js');
19
+ require('../FormFieldPostFix-cjs.js');
19
20
  require('../Spinner-cjs.js');
20
21
  require('../useAtlantisFormFieldName-cjs.js');
21
22
  require('react-hook-form');
@@ -1,7 +1,7 @@
1
1
  export { I as InputPassword } from '../InputPassword-es.js';
2
2
  import 'react';
3
3
  import '../FormField-es.js';
4
- import '../FormFieldPostFix-es.js';
4
+ import '../FormFieldWrapper-es.js';
5
5
  import '@jobber/hooks';
6
6
  import 'framer-motion';
7
7
  import '@jobber/design';
@@ -14,6 +14,7 @@ import '../Typography-es.js';
14
14
  import '../Text-es.js';
15
15
  import '../useFormFieldFocus-es.js';
16
16
  import '../InputValidation-es.js';
17
+ import '../FormFieldPostFix-es.js';
17
18
  import '../Spinner-es.js';
18
19
  import '../useAtlantisFormFieldName-es.js';
19
20
  import 'react-hook-form';