@trackunit/react-form-components 0.0.304 → 0.0.308

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js CHANGED
@@ -1,18 +1,18 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useNamespaceTranslation, registerTranslations } from '@trackunit/i18n-library-translation';
3
+ import { IconButton, Icon, Tooltip, Heading, Text, MenuItem, Tag, Spinner } from '@trackunit/react-components';
3
4
  import * as React from 'react';
4
- import React__default, { forwardRef, useState, useMemo, useRef, useImperativeHandle, useCallback, useEffect, cloneElement } from 'react';
5
+ import React__default, { useMemo, forwardRef, useCallback, cloneElement, useState, useEffect, useRef, useImperativeHandle } from 'react';
6
+ import { useCopyToClipboard } from 'react-use';
5
7
  import { v4 } from 'uuid';
6
- import { Tooltip, Text, MenuItem, Icon, Tag, Spinner, IconButton, Heading } from '@trackunit/react-components';
7
8
  import { cvaMerge } from '@trackunit/css-class-variance-utilities';
9
+ import { format } from 'date-fns';
10
+ import parsePhoneNumberFromString, { isSupportedCountry, getCountries, getCountryCallingCode, isValidPhoneNumber, parsePhoneNumberFromString as parsePhoneNumberFromString$1 } from 'libphonenumber-js';
8
11
  import ReactSelect, { components } from 'react-select';
9
12
  export { default as ValueType } from 'react-select';
10
13
  import ReactAsyncCreatableSelect from 'react-select/async-creatable';
11
14
  import ReactCreatableSelect from 'react-select/creatable';
12
15
  import ReactAsyncSelect from 'react-select/async';
13
- import { useCopyToClipboard } from 'react-use';
14
- import { format } from 'date-fns';
15
- import parsePhoneNumberFromString, { isSupportedCountry, getCountries, getCountryCallingCode, isValidPhoneNumber, parsePhoneNumberFromString as parsePhoneNumberFromString$1 } from 'libphonenumber-js';
16
16
 
17
17
  var defaultTranslations = {
18
18
  "clearIndicator.icon.tooltip.clearAll": "Clear all",
@@ -69,6 +69,65 @@ const setupLibraryTranslations = () => {
69
69
  registerTranslations(translations);
70
70
  };
71
71
 
72
+ const cvaActionButton = cvaMerge(["drop-shadow-none", "rounded-md"], {
73
+ variants: {
74
+ size: {
75
+ small: ["w-6", "h-6"],
76
+ medium: ["w-8", "h-8"],
77
+ },
78
+ },
79
+ defaultVariants: {
80
+ size: "medium",
81
+ },
82
+ });
83
+ const cvaActionContainer = cvaMerge(["flex", "items-center", "m-1"]);
84
+
85
+ /**
86
+ * The ActionButton component is a wrapper over IconButton to perform an action when the onClick event is triggered.
87
+ *
88
+ * @param {ActionButtonProps} props - The props for the ActionButton component
89
+ * @returns {JSX.Element} ActionButton component
90
+ */
91
+ const ActionButton = ({ type, value, dataTestId, iconSize, disabled, key, className }) => {
92
+ const [, copyToClipboard] = useCopyToClipboard();
93
+ const elementKey = useMemo(() => key !== null && key !== void 0 ? key : `ActionButton-${v4()}`, [key]);
94
+ const getIconName = () => {
95
+ switch (type) {
96
+ case "PHONE_NUMBER":
97
+ return "PhoneArrowUpRight";
98
+ case "WEB_ADDRESS":
99
+ return "ArrowTopRightOnSquare";
100
+ case "EMAIL":
101
+ return "Envelope";
102
+ case "COPY":
103
+ default:
104
+ return "ClipboardDocument";
105
+ }
106
+ };
107
+ const ButtonAction = () => {
108
+ var _a, _b;
109
+ switch (type) {
110
+ case "EMAIL":
111
+ return window.open(`mailto:${value}`);
112
+ case "WEB_ADDRESS":
113
+ if (value) {
114
+ return window.open(value, "_blank", "noopener,noreferrer");
115
+ }
116
+ return null;
117
+ case "PHONE_NUMBER":
118
+ return window.open(`tel:${value}`);
119
+ case "COPY":
120
+ return copyToClipboard((_b = (_a = value === null || value === void 0 ? void 0 : value.current) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : "");
121
+ default:
122
+ return null;
123
+ }
124
+ };
125
+ if (ButtonAction === null) {
126
+ return null;
127
+ }
128
+ return (jsx("div", { className: cvaActionContainer({ className }), children: jsx(IconButton, { className: cvaActionButton({ size: iconSize }), dataTestId: dataTestId || "testIconButtonId", disabled: disabled, icon: jsx(Icon, { name: getIconName(), size: "small" }), onClick: ButtonAction, size: "small", variant: "secondary" }) }, elementKey));
129
+ };
130
+
72
131
  /******************************************************************************
73
132
  Copyright (c) Microsoft Corporation.
74
133
 
@@ -106,95 +165,137 @@ function __awaiter(thisArg, _arguments, P, generator) {
106
165
  });
107
166
  }
108
167
 
109
- const cvaLabel = cvaMerge([
110
- "text-base",
111
- "text-slate-700",
112
- "truncate",
113
- "hover:text-slate-800",
114
- "group-hover:text-slate-800",
115
- "active:text-slate-800",
116
- "group-active:text-slate-800",
117
- ], {
168
+ const cvaInputBase = cvaMerge([
169
+ "component-baseInput-shadow",
170
+ "component-baseInput-border",
171
+ "component-baseInput-background",
172
+ "border-slate-300",
173
+ "focus-within:ring-2",
174
+ "focus-within:ring-inset",
175
+ "focus-within:ring-primary-500",
176
+ "focus-within:border-slate-400",
177
+ "hover:border-slate-400",
178
+ "hover:bg-slate-50",
179
+ "transition",
180
+ ]);
181
+ const cvaInputBaseDisabled = cvaMerge(["bg-slate-100", "hover:bg-slate-100", "hover:border-slate-300"]);
182
+ const cvaInputBaseInvalid = cvaMerge(["border-danger-600", "focus-within:ring-danger-600"]);
183
+ const cvaInput = cvaMerge(["relative", "flex", "h-10", cvaInputBase()], {
118
184
  variants: {
185
+ size: {
186
+ small: ["h-8"],
187
+ medium: ["h-10"],
188
+ },
189
+ disabled: {
190
+ true: cvaInputBaseDisabled(),
191
+ false: "",
192
+ },
119
193
  invalid: {
120
- true: "text-red-600 hover:text-red-700 active:text-red-700 group-hover:text-red-700 group-active:text-red-700",
194
+ true: cvaInputBaseInvalid(),
121
195
  false: "",
122
196
  },
197
+ },
198
+ });
199
+ const cvaInputField = cvaMerge([
200
+ "w-full",
201
+ "px-3",
202
+ "border-0",
203
+ "bg-transparent",
204
+ "text-base",
205
+ "text-slate-900",
206
+ "placeholder-slate-400",
207
+ "focus-visible:outline-none",
208
+ ], {
209
+ variants: {
210
+ size: {
211
+ small: ["py-1"],
212
+ medium: ["py-2"],
213
+ },
123
214
  disabled: {
124
- true: "text-slate-400 hover:text-slate-400 group-hover:text-slate-400",
215
+ true: ["text-slate-700"],
125
216
  false: "",
126
217
  },
127
218
  },
128
- defaultVariants: {
129
- invalid: false,
130
- disabled: false,
131
- },
132
219
  });
133
-
134
- /**
135
- * The Label component is used for labels for input fields.
136
- * This component is **not used directly**, but is part of the FormGroup and Field components.
137
- *
138
- * @param {LabelProps} props - The props for the Label component
139
- * @returns {JSX.Element} Label component
140
- */
141
- const Label = ({ id, htmlFor, children, className, dataTestId, disabled, isInvalid, }) => {
142
- return (jsx("label", { id: id || "", htmlFor: htmlFor || "", className: cvaLabel({ invalid: isInvalid, disabled, className }), "data-testid": dataTestId, children: children }));
143
- };
144
-
145
- const cvaFormGroup = cvaMerge(["component-formGroup-gap"], {
220
+ const cvaInputAddon = cvaMerge([
221
+ "flex",
222
+ "justify-center",
223
+ "items-center",
224
+ "px-3",
225
+ "border-slate-300",
226
+ "text-slate-500",
227
+ "bg-slate-50",
228
+ ]);
229
+ const cvaInputAddonBefore = cvaMerge([cvaInputAddon(), "border-r", "rounded-l-lg"]);
230
+ const cvaInputAddonAfter = cvaMerge([cvaInputAddon(), "border-l", "rounded-r-lg"]);
231
+ const cvaInputPrefix = cvaMerge([
232
+ "flex",
233
+ "justify-center",
234
+ "items-center",
235
+ "text-slate-400",
236
+ "hover:component-search-prefix",
237
+ "component-baseInput-prefix",
238
+ "component-search-borderless",
239
+ "px-3",
240
+ ], {
146
241
  variants: {
147
242
  disabled: {
148
- true: "pointer-events-none",
243
+ true: ["text-slate-500"],
149
244
  false: "",
150
245
  },
151
246
  },
152
247
  });
153
- const cvaFormGroupContainerBefore = cvaMerge(["flex", "gap-1", "mb-1"]);
154
- const cvaFormGroupContainerAfter = cvaMerge(["flex", "justify-between", "mt-1", "text-xs", "text-slate-500"], {
248
+ const cvaInputSuffix = cvaMerge(["flex", "justify-center", "items-center", "text-slate-400", "px-3"], {
155
249
  variants: {
156
- invalid: {
157
- true: "text-danger-500",
250
+ disabled: {
251
+ true: ["text-slate-500"],
158
252
  false: "",
159
253
  },
160
254
  },
161
255
  });
162
- const cvaHelpAddon = cvaMerge(["ml-auto"]);
163
256
 
164
257
  /**
165
- * The FormGroup component should be used to wrap any Input element that needs a label.
166
- * Besides a label the component supplies an optional Tooltip, HelpText and HelpAddon support.
258
+ * A base input component that can be used for text inputs, password inputs, etc.
259
+ * A reference to the input element is provided as the `ref` prop.
260
+ * Extends props from [React.InputHTMLAttributes](https://reactjs.org/docs/dom-elements.html#input)
167
261
  *
168
- * @param {FormGroupProps} props - The props for the FormGroup component
169
- * @returns {JSX.Element} FormGroup component
262
+ * For specific input types make sure to use the corresponding input component.
263
+ * This is a base used by our other input components such as TextInput, NumberInput, PasswordInput, etc.
170
264
  */
171
- const FormGroup = ({ isInvalid, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, tipIconProps, disabled = false, }) => {
172
- return (jsxs("div", { className: cvaFormGroup({ disabled, className }), "data-testid": dataTestId, children: [jsxs("div", { className: cvaFormGroupContainerBefore(), children: [jsx(Label, { className: "component-formGroup-font", dataTestId: dataTestId && `${dataTestId}-label`, htmlFor: htmlFor, id: htmlFor + "-label", children: label }), tip && (jsx(Tooltip, { dataTestId: dataTestId && `${dataTestId}-tooltip`, iconProps: tipIconProps, label: tip, placement: "bottom" }))] }), children, jsxs("div", { className: cvaFormGroupContainerAfter({ invalid: isInvalid }), children: [helpText && jsx("span", { "data-testid": dataTestId && `${dataTestId}-helpText`, children: helpText }), helpAddon && (jsx("span", { className: cvaHelpAddon(), "data-testid": dataTestId && `${dataTestId}-helpAddon`, children: helpAddon }))] })] }));
173
- };
265
+ const BaseInput = React.forwardRef((_a, ref) => {
266
+ var { className, isInvalid, dataTestId, prefix, suffix, addonBefore, addonAfter, actions, fieldSize = "medium", nonInteractive = false, showDefaultActions = false, type, inputClassName, addonBeforeClassName } = _a, rest = __rest(_a, ["className", "isInvalid", "dataTestId", "prefix", "suffix", "addonBefore", "addonAfter", "actions", "fieldSize", "nonInteractive", "showDefaultActions", "type", "inputClassName", "addonBeforeClassName"]);
267
+ const isReadOnlyWithPlaceholder = useMemo(() => !!rest.readOnly && !!rest.placeholder && !rest.value, [rest.readOnly, rest.placeholder, rest.value]);
268
+ const renderAsDisabled = rest.disabled || rest.readOnly;
269
+ const innerRef = React.useRef(null);
270
+ React.useImperativeHandle(ref, () => innerRef.current, []);
271
+ return (jsxs("div", { className: cvaInput({
272
+ disabled: renderAsDisabled,
273
+ invalid: isInvalid,
274
+ size: fieldSize,
275
+ className,
276
+ }), "data-testid": dataTestId && `${dataTestId}-container`, children: [addonBefore && addonBefore !== undefined ? (jsx("div", { className: cvaInputAddonBefore({ className: addonBeforeClassName }), "data-testid": dataTestId && `${dataTestId}-addonBefore`, children: addonBefore })) : null, prefix && addonBefore !== prefix ? (jsx("div", { className: cvaInputPrefix({
277
+ disabled: renderAsDisabled,
278
+ }), "data-testid": dataTestId && `${dataTestId}-prefix`, children: prefix })) : null, jsx("input", Object.assign({ className: cvaInputField({ size: fieldSize, disabled: renderAsDisabled, className: inputClassName }), "data-testid": dataTestId, ref: innerRef, type: isReadOnlyWithPlaceholder ? "text" : type }, rest, { readOnly: rest.readOnly || nonInteractive })), suffix && addonBefore !== suffix ? (jsx("div", { className: cvaInputSuffix({
279
+ disabled: renderAsDisabled,
280
+ }), "data-testid": dataTestId && `${dataTestId}-suffix`, children: suffix })) : null, rest.readOnly === true && showDefaultActions ? (jsx(ActionButton, { type: "COPY", value: innerRef }, "default-copy-action")) : null, actions && addonBefore !== actions ? actions : null, addonAfter && addonAfter !== undefined && addonBefore !== addonAfter ? (jsx("div", { className: cvaInputAddonAfter(), "data-testid": dataTestId && `${dataTestId}-addonAfter`, children: addonAfter })) : null] }));
281
+ });
174
282
 
175
- const cvaSelect = cvaMerge([
176
- "relative",
177
- "flex",
178
- "shadow-sm",
179
- "rounded-lg",
180
- "border",
181
- "border-slate-300",
182
- "focus-within:ring-2",
183
- "focus-within:ring-inset",
184
- "focus-within:ring-primary-600",
185
- "focus-within:border-slate-400",
186
- "hover:border-slate-400",
187
- "hover:bg-slate-50",
188
- "bg-white",
189
- "transition",
283
+ const cvaLabel = cvaMerge([
284
+ "text-base",
285
+ "text-slate-700",
286
+ "truncate",
287
+ "hover:text-slate-800",
288
+ "group-hover:text-slate-800",
289
+ "active:text-slate-800",
290
+ "group-active:text-slate-800",
190
291
  ], {
191
292
  variants: {
192
293
  invalid: {
193
- true: "border-red-600 text-red-600 focus-within:ring-red-600 hover:border-red-600",
294
+ true: "text-red-600 hover:text-red-700 active:text-red-700 group-hover:text-red-700 group-active:text-red-700",
194
295
  false: "",
195
296
  },
196
297
  disabled: {
197
- true: "!bg-slate-100",
298
+ true: "text-slate-400 hover:text-slate-400 group-hover:text-slate-400",
198
299
  false: "",
199
300
  },
200
301
  },
@@ -203,94 +304,15 @@ const cvaSelect = cvaMerge([
203
304
  disabled: false,
204
305
  },
205
306
  });
206
- const cvaSelectIcon = cvaMerge("mr-2 flex cursor-pointer items-center justify-center text-slate-400 hover:text-slate-500");
207
- const cvaSelectPrefix = cvaMerge(["flex", "justify-center", "items-center", "text-slate-400", "pl-2"]);
208
- const cvaSelectXIcon = cvaMerge([
209
- "mr-2 flex cursor-pointer items-center justify-center text-slate-400 hover:text-slate-500",
210
- "ml-1",
211
- ]);
212
- const cvaSelectMenuList = cvaMerge(["min-w-min", "shadow-md", "rounded-lg", "z-20", "bg-white", "p-1", "border", "border-slate-300", "gap-1", "grid"], {
213
- variants: {
214
- menuIsOpen: {
215
- true: "animate-fade-in-fast",
216
- false: "animate-fade-out-fast",
217
- },
218
- },
219
- });
220
- const cvaSelectDynamicTagContainer = cvaMerge(["h-full", "flex", "gap-1", "items-center"], {
221
- variants: {
222
- visible: { true: "visible", false: "invisible" },
223
- },
224
- });
225
- const cvaSelectCounter = cvaMerge(["overflow-hidden", "whitespace-nowrap"]);
226
- const cvaSelectMenu = cvaMerge(["relative", "p-1", "grid", "gap-1"]);
227
307
 
228
308
  /**
229
- * The SelectContainer component.
309
+ * The CheckIcon component is used by the checkbox to display the checked state.
230
310
  *
231
- * @param {SelectContainerProps} props - The props for the SelectContainer component
232
- * @returns {JSX.Element} SelectContainer component
311
+ * @param {CheckIconProps} props - The props for the CheckIcon component
312
+ * @returns {JSX.Element} CheckIcon component
233
313
  */
234
- const SelectContainer = ({ children, label, hideLabel, id, hasError, error, description, info, dataTestId, isDisabled, }) => {
235
- return (jsxs("label", { className: cvaSelect({ invalid: hasError, disabled: isDisabled }), "data-testid": dataTestId, children: [label && !hideLabel && jsx(Label, { htmlFor: id, children: label }), children, (hasError || info) && jsx(Text, { size: "small", children: hasError ? error : info })] }));
236
- };
237
-
238
- /**
239
- * @param {MultiValue<Option> | SingleValue<Option>} arg option to check type
240
- * @returns {arg is MultiValue<Option> } is Multivalue
241
- */
242
- function isMultiValue(arg) {
243
- return Array.isArray(arg);
244
- }
245
- function isGroupBase(arg) {
246
- return arg.options !== undefined;
247
- }
248
- const isSelectedOption = (option, selected) => {
249
- if (isGroupBase(option)) {
250
- return false;
251
- }
252
- return isMultiValue(selected)
253
- ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
254
- selected.some(v => v.value === option.value)
255
- : // eslint-disable-next-line @typescript-eslint/no-explicit-any
256
- option.value === (selected === null || selected === void 0 ? void 0 : selected.value);
257
- };
258
- const removeSelectedFromGroups = (group, selected) => {
259
- if (isGroupBase(group)) {
260
- return Object.assign(Object.assign({}, group), { options: group.options.filter(option => !isSelectedOption(option, selected)) });
261
- }
262
- return group;
263
- };
264
- /**
265
- * @template IsMulti
266
- * @template Group
267
- * @param {OptionsOrGroups<Option, Group> | undefined} options An array of options to select from
268
- * @param {PropsValue<Option> | undefined} value Selected values
269
- * @returns {OptionsOrGroups<Option, Group>} An array of ordered options with selected on top
270
- */
271
- const getOrderedOptions = (options, value) => {
272
- if (value && options) {
273
- const orderedValues = isMultiValue(value)
274
- ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
275
- [...value].sort((a, b) => a.label.localeCompare(b.label))
276
- : [value];
277
- const selectableOptions = options
278
- .filter(option => !isSelectedOption(option, value))
279
- .map(option => removeSelectedFromGroups(option, value));
280
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
281
- return orderedValues.concat(selectableOptions) || [];
282
- }
283
- return options || [];
284
- };
285
-
286
- /**
287
- * The CheckIcon component is used by the checkbox to display the checked state.
288
- *
289
- * @param {CheckIconProps} props - The props for the CheckIcon component
290
- * @returns {JSX.Element} CheckIcon component
291
- */
292
- const CheckIcon = ({ className, dataTestId }) => {
293
- return (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: className, "data-testid": dataTestId, fill: "none", viewBox: "0 0 10 10", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m2 5.5 2 2L8.5 3" }) }));
314
+ const CheckIcon = ({ className, dataTestId }) => {
315
+ return (jsx("svg", { className: className, "data-testid": dataTestId, fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 10 10", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "m2 5.5 2 2L8.5 3", strokeLinecap: "round", strokeLinejoin: "round" }) }));
294
316
  };
295
317
 
296
318
  const cvaCheckbox = cvaMerge([
@@ -423,7 +445,7 @@ const cvaCheckboxIcon = cvaMerge(["w-2.5", "h-2.5", "text-white"]);
423
445
  * @param {IndeterminateIconProps} props - The props for the IndeterminateIcon component
424
446
  * @returns {JSX.Element} IndeterminateIcon component
425
447
  */
426
- const IndeterminateIcon = ({ className }) => (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: className, fill: "none", viewBox: "0 0 10 10", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 5h4" }) }));
448
+ const IndeterminateIcon = ({ className }) => (jsx("svg", { className: className, fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 10 10", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M3 5h4", strokeLinecap: "round", strokeLinejoin: "round" }) }));
427
449
 
428
450
  /**
429
451
  * Checkboxes are used when there are multiple items to select in a list. Users can select zero, one, or any number of items.
@@ -459,719 +481,174 @@ const Checkbox = React.forwardRef((_a, ref) => {
459
481
  onLabelRefChange && labelRef && onLabelRefChange(labelRef);
460
482
  }, [labelRef, onLabelRefChange]);
461
483
  const uuid = rest.id;
462
- return (jsxs("label", { "data-testid": dataTestId && `${dataTestId}-container`, htmlFor: uuid, className: cvaCheckboxContainer({ className }), ref: internalRef, onKeyDown: onKeyPress, onClick: e => stopPropagation && e.stopPropagation(), children: [jsx("input", Object.assign({ type: "checkbox", className: cvaCheckboxInput(), checked: !indeterminate && checked, onChange: onChange, disabled: disabled, "data-testid": dataTestId, readOnly: readOnly, "aria-checked": !indeterminate && checked, id: uuid }, rest, { ref: ref })), jsx("span", { id: uuid, tabIndex: isReadonly ? -1 : tabIndex, className: cvaCheckbox({
484
+ return (jsxs("label", { className: cvaCheckboxContainer({ className }), "data-testid": dataTestId && `${dataTestId}-container`, htmlFor: uuid, onClick: e => stopPropagation && e.stopPropagation(), onKeyDown: onKeyPress, ref: internalRef, children: [jsx("input", Object.assign({ "aria-checked": !indeterminate && checked, checked: !indeterminate && checked, className: cvaCheckboxInput(), "data-testid": dataTestId, disabled: disabled, id: uuid, onChange: onChange, readOnly: readOnly, type: "checkbox" }, rest, { ref: ref })), jsx("span", { className: cvaCheckbox({
463
485
  disabled: isReadonly,
464
486
  invalid: isReadonly ? false : isInvalid,
465
487
  state: indeterminate ? "indeterminate" : checked ? "selected" : "deselected",
466
- }), children: icon }), label && (jsx("span", { className: "flex", children: jsx("span", { id: `checkbox-label-${label}`, ref: labelReference => setLabelRef(labelReference), className: cvaLabel({
488
+ }), id: uuid, tabIndex: isReadonly ? -1 : tabIndex, children: icon }), label && (jsx("span", { className: "flex", children: jsx("span", { className: cvaLabel({
467
489
  invalid: isReadonly ? false : isInvalid,
468
490
  disabled: isReadonly,
469
491
  className: "cursor-pointer",
470
- }), children: label }) })), suffix] }));
492
+ }), id: `checkbox-label-${label}`, ref: labelReference => setLabelRef(labelReference), children: label }) })), suffix] }));
471
493
  });
472
494
 
473
495
  /**
474
- * A single select menu item is a basic wrapper around Menu item designed to be used as a single value render in Select list
496
+ * A wrapper around BaseInput with a pop-up day picker.
475
497
  *
476
- * @param {SelectMenuItemProps} props - The props for the SingleSelectMenuItem
477
- * @returns {JSX.Element} SingleSelectMenuItem
498
+ * NOTE: If shown with a label, please use the `DateField` component instead.
478
499
  */
479
- const SingleSelectMenuItem = ({ label, icon, onClick, selected, dataTestId, focused, disabled, }) => {
480
- return (jsx(MenuItem, { dataTestId: dataTestId, label: label, prefix: icon, onClick: onClick, selected: selected, disabled: disabled, focused: focused, suffix: selected ? jsx(Icon, { name: "Check", size: "small" }) : undefined }));
481
- };
500
+ const DateInput = forwardRef((_a, ref) => {
501
+ var { min, max, defaultValue, value } = _a, rest = __rest(_a, ["min", "max", "defaultValue", "value"]);
502
+ const formatDateToInputString = (date) => date instanceof Date ? format(date, "yyyy-MM-dd") : date;
503
+ // Chrome and Firefox need their default icon to have datepicker functionality.
504
+ const showIcon = !/Chrome/.test(navigator.userAgent) && !/Firefox/.test(navigator.userAgent);
505
+ return (jsx(BaseInput, Object.assign({ defaultValue: formatDateToInputString(defaultValue), max: formatDateToInputString(max), min: formatDateToInputString(min), ref: ref, suffix: showIcon && jsx(Icon, { dataTestId: "calendar", name: "Calendar", size: "medium", type: "solid" }), type: "date", value: formatDateToInputString(value) }, rest)));
506
+ });
507
+
482
508
  /**
483
- * A multi select menu item is a basic wrapper around Menu item designed to be used as a multi value render in Select list
509
+ * The Label component is used for labels for input fields.
510
+ * This component is **not used directly**, but is part of the FormGroup and Field components.
484
511
  *
485
- * @param {SelectMenuItemProps} props - The props for the MultiSelectMenuItem
486
- * @returns {JSX.Element} multi select menu item
512
+ * @param {LabelProps} props - The props for the Label component
513
+ * @returns {JSX.Element} Label component
487
514
  */
488
- const MultiSelectMenuItem = ({ label, onClick, selected, dataTestId, focused, disabled, }) => {
489
- return (jsx(MenuItem, { dataTestId: dataTestId, label: label, disabled: disabled, prefix: jsx(Checkbox, { checked: selected, readOnly: false, onChange: () => null, disabled: disabled, onClick: e => {
490
- e.stopPropagation();
491
- } }), onClick: e => {
492
- e.stopPropagation();
493
- onClick && onClick(e);
494
- }, selected: selected, focused: focused }));
515
+ const Label = ({ id, htmlFor, children, className, dataTestId, disabled, isInvalid, }) => {
516
+ return (jsx("label", { className: cvaLabel({ invalid: isInvalid, disabled, className }), "data-testid": dataTestId, htmlFor: htmlFor || "", id: id || "", children: children }));
495
517
  };
496
518
 
519
+ const cvaFormGroup = cvaMerge(["component-formGroup-gap"], {
520
+ variants: {
521
+ disabled: {
522
+ true: "pointer-events-none",
523
+ false: "",
524
+ },
525
+ },
526
+ });
527
+ const cvaFormGroupContainerBefore = cvaMerge(["flex", "gap-1", "mb-1"]);
528
+ const cvaFormGroupContainerAfter = cvaMerge(["flex", "justify-between", "mt-1", "text-xs", "text-slate-500"], {
529
+ variants: {
530
+ invalid: {
531
+ true: "text-danger-500",
532
+ false: "",
533
+ },
534
+ },
535
+ });
536
+ const cvaHelpAddon = cvaMerge(["ml-auto"]);
537
+
497
538
  /**
498
- * Extended Tag component with information about its own width.
499
- * Used in the select component.
539
+ * The FormGroup component should be used to wrap any Input element that needs a label.
540
+ * Besides a label the component supplies an optional Tooltip, HelpText and HelpAddon support.
500
541
  *
501
- * @param {TagProps} props - The props for the tag component
502
- * @returns {JSX.Element} TagWithWidth component
542
+ * @param {FormGroupProps} props - The props for the FormGroup component
543
+ * @returns {JSX.Element} FormGroup component
503
544
  */
504
- const TagWithWidth = (_a) => {
505
- var { onWidthKnown, children } = _a, rest = __rest(_a, ["onWidthKnown", "children"]);
506
- const ref = React__default.useRef(null);
507
- React__default.useLayoutEffect(() => {
508
- var _a;
509
- onWidthKnown && onWidthKnown({ width: ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0 });
510
- }, [ref, onWidthKnown]);
511
- return (jsx(Tag, Object.assign({ ref: ref }, rest, { children: children })));
545
+ const FormGroup = ({ isInvalid, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, tipIconProps, disabled = false, }) => {
546
+ return (jsxs("div", { className: cvaFormGroup({ disabled, className }), "data-testid": dataTestId, children: [jsxs("div", { className: cvaFormGroupContainerBefore(), children: [jsx(Label, { className: "component-formGroup-font", dataTestId: dataTestId && `${dataTestId}-label`, htmlFor: htmlFor, id: htmlFor + "-label", children: label }), tip && (jsx(Tooltip, { dataTestId: dataTestId && `${dataTestId}-tooltip`, iconProps: tipIconProps, label: tip, placement: "bottom" }))] }), children, jsxs("div", { className: cvaFormGroupContainerAfter({ invalid: isInvalid }), children: [helpText && jsx("span", { "data-testid": dataTestId && `${dataTestId}-helpText`, children: helpText }), helpAddon && (jsx("span", { className: cvaHelpAddon(), "data-testid": dataTestId && `${dataTestId}-helpAddon`, children: helpAddon }))] })] }));
512
547
  };
513
548
 
514
549
  /**
515
- * TagsContainer component to display tags in limited space when children can't fit space it displays counter
550
+ * The date field component is used for entering date values.
516
551
  *
517
- * @param {TagsContainerProps} props - The props for the TagContainer
518
- * @returns {JSX.Element} TagsContainer
552
+ * _**Do use**_ the DateField for date input.
553
+ *
554
+ * _**Do not use**_ this fields for non-serialized dates. Use TextField instead.
519
555
  */
520
- const TagsContainer = ({ items, width = "100%", itemsGap = 5, postFix, disabled }) => {
521
- const [isReady, setIsReady] = React__default.useState(false);
522
- const [counterWidth, setCounterWidth] = React__default.useState(0);
523
- const containerRef = React__default.useRef(null);
524
- const availableWidth = React__default.useRef();
525
- const childrenWidth = React__default.useRef([]);
526
- const itemsCount = items.length;
527
- React__default.useLayoutEffect(() => {
528
- var _a;
529
- availableWidth.current = ((_a = containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0;
530
- }, [containerRef]);
531
- const onWidthKnownHandler = ({ width: reportedWidth }) => {
532
- childrenWidth.current.push({ width: reportedWidth + itemsGap });
533
- if (childrenWidth.current.length === itemsCount) {
534
- setIsReady(true);
535
- }
536
- };
537
- const requiredSpace = childrenWidth.current.reduce((previous, current) => {
538
- return previous + current.width;
539
- }, 0);
540
- let counter = 0;
541
- const availableSpace = ((availableWidth === null || availableWidth === void 0 ? void 0 : availableWidth.current) || 0) - counterWidth;
542
- const renderedElements = items
543
- .concat({ text: "", onClick: () => null, disabled: false }) // reserved element for a potential counter
544
- .map((item, index) => {
545
- const spaceNeeded = childrenWidth.current.slice(0, index + 1).reduce((previous, current) => {
546
- return previous + current.width;
547
- }, 0);
548
- const isLast = index === items.length;
549
- const counterRequired = requiredSpace > availableSpace && counter !== 0;
550
- if (isLast && counterRequired) {
551
- return (jsx(TagWithWidth, { onWidthKnown: ({ width: reportedWidth }) => setCounterWidth(reportedWidth), color: "white", disabled: disabled, children: jsxs("div", { "data-testid": "select-counter", className: cvaSelectCounter(), children: ["+", counter] }) }, item.text + index));
556
+ const DateField = forwardRef((_a, ref) => {
557
+ var { label, id, tip, helpText, errorMessage, helpAddon, isInvalid, className, defaultValue, dataTestId } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "errorMessage", "helpAddon", "isInvalid", "className", "defaultValue", "dataTestId"]);
558
+ const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
559
+ const htmlForId = id ? id : "dateField-" + v4();
560
+ return (jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(DateInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref }, rest, { className: className, dataTestId: dataTestId })) }));
561
+ });
562
+
563
+ const cvaDropZone = cvaMerge([
564
+ "flex",
565
+ "component-baseInput-background",
566
+ "justify-center",
567
+ "text-slate-500",
568
+ "rounded-sm",
569
+ "border-2",
570
+ "border-gray-200",
571
+ "border-dashed",
572
+ "hover:bg-slate-100",
573
+ "hover:border-solid",
574
+ "hover:border-primary-500",
575
+ ], {
576
+ variants: {
577
+ size: {
578
+ small: ["p-2"],
579
+ medium: ["p-4"],
580
+ large: ["p-8"],
581
+ },
582
+ disabled: { true: ["bg-slate-100", "hover:bg-slate-100"], false: "" },
583
+ dragActive: { true: ["border-gray-200", "bg-slate-100"], false: "" },
584
+ dropComplete: {
585
+ true: ["border-solid", "border-primary-500", "bg-slate-100", "hover:border-solid", "hover:border-gray-200"],
586
+ false: "",
587
+ },
588
+ invalid: { true: ["border-danger-600", "text-danger-500"], false: "" },
589
+ },
590
+ });
591
+ const cvaDropZoneLabel = cvaMerge([
592
+ "h-full",
593
+ "pt-1",
594
+ "pb-1",
595
+ "gap-2",
596
+ "items-center",
597
+ "flex-col",
598
+ "flex",
599
+ "justify-center",
600
+ ]);
601
+
602
+ /**
603
+ * The Drop Zone can be used to drag and drop files
604
+ *
605
+ * @param {DropZoneProps} props - The props for the DropZone component
606
+ * @returns {JSX.Element} DropZone component
607
+ */
608
+ const DropZone = (_a) => {
609
+ var { className, dataTestId, filesSelected, label, size = "large", isInvalid = false, disabled = false } = _a, rest = __rest(_a, ["className", "dataTestId", "filesSelected", "label", "size", "isInvalid", "disabled"]);
610
+ const [dragActive, setDragActive] = React__default.useState(false);
611
+ const [fileDropped, setFileDropped] = React__default.useState(false);
612
+ // function that handles drag enter, drag leave and drag over
613
+ const handleDrag = (e) => {
614
+ e.preventDefault();
615
+ e.stopPropagation();
616
+ if ((e.type === "dragenter" || e.type === "dragover") && !disabled) {
617
+ setDragActive(true);
552
618
  }
553
- if (isLast) {
554
- return null;
619
+ else if (e.type === "dragleave") {
620
+ setDragActive(false);
555
621
  }
556
- const itemCanFit = spaceNeeded <= availableSpace;
557
- if (itemCanFit) {
558
- return (jsx(TagWithWidth, { onWidthKnown: onWidthKnownHandler, className: "inline-flex shrink-0", onClose: e => {
559
- e.stopPropagation();
560
- item.onClick();
561
- }, color: item.disabled ? "unknown" : "primary", dataTestId: `${item.text}-tag`, disabled: disabled, children: item.text }, item.text + index));
622
+ };
623
+ //function to handle when user clicks on dropzone to upload
624
+ const handleChange = (e) => {
625
+ e.preventDefault();
626
+ e.stopPropagation();
627
+ if (e.target.files && !disabled) {
628
+ filesSelected(e.target.files);
562
629
  }
563
- const fromTheItems = item.text !== "";
564
- if (fromTheItems) {
565
- counter = counter + 1;
630
+ };
631
+ //funtion to handle drop
632
+ const handleDrop = (e) => {
633
+ e.preventDefault();
634
+ e.stopPropagation();
635
+ setDragActive(false);
636
+ if (e.dataTransfer.files && e.dataTransfer.files[0] && !disabled) {
637
+ filesSelected(e.dataTransfer.files);
638
+ setFileDropped(true);
566
639
  }
567
- return null;
568
- })
569
- .filter(element => element !== null);
570
- return (jsxs("div", { style: {
571
- width: `${width}`,
572
- }, className: cvaSelectDynamicTagContainer({ visible: isReady }), ref: containerRef, children: [renderedElements, postFix] }));
640
+ };
641
+ return (jsxs("div", Object.assign({ className: cvaDropZone({ size, dropComplete: fileDropped, dragActive, disabled, invalid: isInvalid, className }), "data-testid": dataTestId, onClick: e => {
642
+ if (disabled) {
643
+ e.preventDefault();
644
+ e.stopPropagation();
645
+ }
646
+ }, onDragEnter: handleDrag, onDragLeave: handleDrag, onDragOver: handleDrag, onDrop: handleDrop }, rest, { children: [jsx("input", { className: "hidden", id: "input-file-upload", onChange: handleChange, title: "Hidden File Input", type: "file" }), jsxs("label", { className: cvaDropZoneLabel(), "data-testid": dataTestId && `${dataTestId}-label`, htmlFor: "input-file-upload", children: [jsx(Icon, { color: isInvalid ? "danger" : "neutral", name: "ArrowUpCircle", style: !isInvalid ? { color: "rgb(156 163 175)" } : {}, type: "solid" }), jsx("span", { children: label })] })] })));
573
647
  };
574
648
 
575
- /**
576
- * A hook to retrieve components override object.
577
- * This complex object includes all the compositional components that are used in react-select. If you wish to overwrite a component, pass in an object with the appropriate namespace.
578
- *
579
- * @template IsMulti
580
- * @template Group
581
- * @param {Partial<SelectComponents<Option, IsMulti, Group>> | undefined} componentsProps a custom component prop that you can to override defaults
582
- * @param {boolean} disabled decide to override disabled variant
583
- * @param {boolean} menuIsOpen menu is open state
584
- * @param {React.MutableRefObject<boolean>} refMenuIsEnabled a flag to block menu from open
585
- * @param {string} dataTestId a test id
586
- * @param {number} maxSelectedDisplayCount a number of max display count
587
- * @param {JSX.Element} dropdownIcon an custom dropdown icon
588
- * @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
589
- */
590
- const useCustomComponents = (componentsProps, disabled, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon) => {
591
- const [t] = useTranslation();
592
- // perhaps it should not be wrap in memo (causing some issues with opening and closing on mobiles)
593
- const customComponents = React.useMemo(() => {
594
- return Object.assign({ ValueContainer: props => {
595
- if (props.isMulti && Array.isArray(props.children) && props.children.length > 0) {
596
- const PLACEHOLDER_KEY = "placeholder";
597
- const key = props && props.children && props.children[0] ? props.children[0].key : "";
598
- const values = props && props.children ? props.children[0] : [];
599
- const tags = key === PLACEHOLDER_KEY ? [] : values;
600
- const searchInput = props && props.children && props.children[1];
601
- return (jsx(components.ValueContainer, Object.assign({}, props, { isDisabled: props.selectProps.isDisabled, children: maxSelectedDisplayCount === undefined ? (jsx(TagsContainer, { width: "100%", items: tags
602
- ? tags.map(({ props: tagProps }) => {
603
- return {
604
- text: tagProps.children,
605
- onClick: disabled
606
- ? undefined
607
- : (e) => {
608
- var _a, _b;
609
- refMenuIsEnabled.current = false;
610
- ((_a = tagProps === null || tagProps === void 0 ? void 0 : tagProps.removeProps) === null || _a === void 0 ? void 0 : _a.onClick) && ((_b = tagProps === null || tagProps === void 0 ? void 0 : tagProps.removeProps) === null || _b === void 0 ? void 0 : _b.onClick(e));
611
- },
612
- disabled: disabled,
613
- };
614
- })
615
- : [], postFix: searchInput, disabled: disabled })) : (jsxs(Fragment, { children: [tags &&
616
- tags.slice(0, maxSelectedDisplayCount).map(({ props: tagProps }) => {
617
- var _a, _b;
618
- return (jsx(Tag, { className: "inline-flex shrink-0", onClose: e => {
619
- var _a, _b;
620
- e.stopPropagation();
621
- refMenuIsEnabled.current = false;
622
- ((_a = tagProps === null || tagProps === void 0 ? void 0 : tagProps.removeProps) === null || _a === void 0 ? void 0 : _a.onClick) && ((_b = tagProps === null || tagProps === void 0 ? void 0 : tagProps.removeProps) === null || _b === void 0 ? void 0 : _b.onClick(e));
623
- }, color: disabled ? "unknown" : "primary", dataTestId: tagProps.children ? `${(_a = tagProps.children) === null || _a === void 0 ? void 0 : _a.toString()}-tag` : undefined, children: tagProps.children }, (_b = tagProps.children) === null || _b === void 0 ? void 0 : _b.toString()));
624
- }), tags && tags.length > maxSelectedDisplayCount && (jsxs(Tag, { color: "neutral", dataTestId: "counter-tag", children: ["+", tags.length - maxSelectedDisplayCount] })), searchInput] })) })));
625
- }
626
- return (jsx(components.ValueContainer, Object.assign({}, props, { isDisabled: props.selectProps.isDisabled, children: props.children })));
627
- }, LoadingIndicator: props => {
628
- return jsx(Spinner, { size: "small", className: "mt-1.5 mr-1" });
629
- }, DropdownIndicator: props => {
630
- const icon = props.selectProps.menuIsOpen ? (jsx(Icon, { name: "ChevronUp", size: "medium" })) : (jsx(Icon, { name: "ChevronDown", size: "medium" }));
631
- return props.selectProps.isLoading ? null : (jsx(components.DropdownIndicator, Object.assign({}, props, { children: jsx("div", { className: cvaSelectIcon(), children: dropdownIcon ? dropdownIcon : icon }) })));
632
- }, IndicatorSeparator: () => null, ClearIndicator: props => {
633
- if (disabled) {
634
- return null;
635
- }
636
- return (jsx(components.ClearIndicator, Object.assign({}, props, { children: jsx("div", { className: cvaSelectXIcon(), onClick: props.clearValue, "data-testid": dataTestId && `${dataTestId}-XMarkIcon`, children: jsx(Icon, { title: t("clearIndicator.icon.tooltip.clearAll"), name: "XCircle", size: "medium" }) }) })));
637
- }, Control: props => {
638
- return jsx(components.Control, Object.assign({}, props, { className: props.isDisabled ? "bg-slate-100" : "" }));
639
- }, SingleValue: props => {
640
- return (jsx(components.SingleValue, Object.assign({}, props, { className: props.isDisabled ? "text-slate-700" : "", children: jsx("div", { "data-testid": dataTestId + "-singleValue", children: props.children }) })));
641
- }, Menu: props => {
642
- return (jsx(components.Menu, Object.assign({}, props, { className: cvaSelectMenuList({ menuIsOpen: props.selectProps.menuIsOpen }) })));
643
- }, MenuList: props => {
644
- return (jsx(components.MenuList, Object.assign({}, props, { innerProps: Object.assign(Object.assign({}, props.innerProps), { onScroll: e => {
645
- const listEl = e.currentTarget;
646
- if (listEl.scrollTop + listEl.clientHeight >= listEl.scrollHeight) {
647
- props.selectProps.onMenuScrollToBottom && props.selectProps.onMenuScrollToBottom(new TouchEvent(""));
648
- }
649
- } }), children: props.children })));
650
- }, Option: props => {
651
- const componentProps = {
652
- label: props.label,
653
- focused: props.isFocused,
654
- selected: props.isSelected,
655
- onClick: props.innerProps.onClick,
656
- };
657
- return (jsx(components.Option, Object.assign({}, props, { innerProps: Object.assign(Object.assign({}, props.innerProps), { role: "option", onClick: () => { } }), children: props.isMulti ? (jsx(MultiSelectMenuItem, Object.assign({}, componentProps, { disabled: disabled, dataTestId: typeof props.label === "string" ? props.label : undefined }))) : (jsx(SingleSelectMenuItem, Object.assign({}, componentProps, { disabled: disabled || props.isDisabled, dataTestId: typeof props.label === "string" ? props.label : undefined }))) })));
658
- } }, componentsProps);
659
- // eslint-disable-next-line react-hooks/exhaustive-deps
660
- }, [componentsProps, disabled, maxSelectedDisplayCount]); // do not add dropdownIcon (it will cause issue with opening/closing list for selects with custom icon)
661
- return customComponents;
662
- };
663
-
664
- /**
665
- * @template IsMulti
666
- * @template Group
667
- * @param {React.RefObject<HTMLDivElement>} refContainer react ref to container element
668
- * @param {React.RefObject<HTMLDivElement>} refPrefix react ref to prefix element
669
- * @param {number | undefined} maxSelectedDisplayCount a number of max display count
670
- * @param {StylesConfig<Option, IsMulti, Group> | undefined} styles a optional object to override styles of react-select
671
- * @returns {StylesConfig<Option, boolean>} styles to override in select
672
- */
673
- const useCustomStyles = (refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled) => {
674
- const customStyles = React.useMemo(() => {
675
- return Object.assign({ control: base => {
676
- return Object.assign(Object.assign({}, base), { border: "0", boxShadow: "0", "&:hover": {
677
- border: "0",
678
- }, marginRight: "2px", backgroundColor: "" });
679
- }, singleValue: base => (Object.assign({}, base)), multiValue: base => (Object.assign({}, base)), multiValueLabel: base => (Object.assign({}, base)), indicatorsContainer: base => (Object.assign(Object.assign({}, base), (disabled && { display: "none" }))), indicatorSeparator: () => ({
680
- width: "0px",
681
- }), menu: base => {
682
- return Object.assign(Object.assign({}, base), { width: "100%", marginTop: "4px", marginBottom: "18px", transition: "all 1s ease-in-out" });
683
- }, input: base => (Object.assign(Object.assign({}, base), { marginLeft: "0px" })), placeholder: base => (Object.assign({}, base)), option: () => ({}), menuPortal: base => (Object.assign(Object.assign({}, base), { width: (refContainer === null || refContainer === void 0 ? void 0 : refContainer.current) ? `${refContainer.current.clientWidth}px` : base.width, transform: (refPrefix === null || refPrefix === void 0 ? void 0 : refPrefix.current) ? `translate(-${refPrefix.current.clientWidth + 2}px)` : "translate(-2px)", backgroundColor: "#ffffff", borderRadius: "var(--border-radius-lg)", zIndex: 20, borderColor: "rgb(var(--color-slate-300))", boxShadow: "var(--tw-ring-inset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)" })), menuList: base => {
684
- return Object.assign(Object.assign({}, base), { position: "relative", padding: "var(--spacing-1)", display: "grid", gap: "var(--spacing-1)", width: "100%", borderRadius: "0px", boxShadow: "none", paddingTop: "0px" });
685
- }, valueContainer: base => {
686
- return Object.assign(Object.assign({}, base), { flexWrap: maxSelectedDisplayCount !== undefined ? "wrap" : "nowrap", gap: "0.25rem" });
687
- }, container: base => (Object.assign(Object.assign({}, base), { border: "none", width: "calc(100% - 2px)", paddingLeft: "2px" })), dropdownIndicator: base => (Object.assign(Object.assign({}, base), { padding: "0px" })), clearIndicator: base => {
688
- return Object.assign(Object.assign({}, base), { padding: "0px" });
689
- } }, styles);
690
- // eslint-disable-next-line react-hooks/exhaustive-deps
691
- }, [refContainer, refPrefix]);
692
- return { customStyles };
693
- };
694
-
695
- /**
696
- * A hook used by selects to share the common code
697
- *
698
- * @param {SelectProps} props - The props for the Select component
699
- * @returns {IUseSelect} Select component
700
- */
701
- const useSelect = (_a) => {
702
- var _b;
703
- var { id, className, dataTestId = "select", prefix, async, dropdownIcon, maxMenuHeight = 200, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix = "", onMenuOpen, onMenuClose, maxSelectedDisplayCount = undefined, isClearable = false, isSearchable = true, onMenuScrollToBottom, styles, filterOption, onInputChange } = _a, props = __rest(_a, ["id", "className", "dataTestId", "prefix", "async", "dropdownIcon", "maxMenuHeight", "label", "hasError", "disabled", "isMulti", "components", "value", "options", "onChange", "isLoading", "classNamePrefix", "onMenuOpen", "onMenuClose", "maxSelectedDisplayCount", "isClearable", "isSearchable", "onMenuScrollToBottom", "styles", "filterOption", "onInputChange"]);
704
- const refContainer = React__default.useRef(null);
705
- const refPrefix = React__default.useRef(null);
706
- const { customStyles } = useCustomStyles(refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled);
707
- const [menuIsOpen, setMenuIsOpen] = React__default.useState((_b = props.menuIsOpen) !== null && _b !== void 0 ? _b : false);
708
- const refMenuIsEnabled = React__default.useRef(true);
709
- const customComponents = useCustomComponents(components, disabled || false, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon);
710
- const menuPlacement = "auto";
711
- const openMenuHandler = () => __awaiter(void 0, void 0, void 0, function* () {
712
- onMenuOpen && onMenuOpen();
713
- if (refMenuIsEnabled.current) {
714
- setMenuIsOpen(true);
715
- }
716
- else {
717
- refMenuIsEnabled.current = true;
718
- }
719
- });
720
- const closeMenuHandler = () => {
721
- setMenuIsOpen(false);
722
- onMenuClose && onMenuClose();
723
- };
724
- const orderedOptions = React__default.useMemo(() => {
725
- return disabled
726
- ? getOrderedOptions(options, value).map(option => {
727
- return Object.assign(Object.assign({}, option), { disabled: true });
728
- })
729
- : getOrderedOptions(options, value);
730
- }, [options, value, disabled]);
731
- return {
732
- refContainer,
733
- refPrefix,
734
- customStyles,
735
- menuIsOpen,
736
- customComponents,
737
- menuPlacement,
738
- openMenuHandler,
739
- closeMenuHandler,
740
- orderedOptions,
741
- };
742
- };
743
-
744
- /**
745
- * The CreatableSelect component.
746
- *
747
- * @param {CreateableSelectProps} props - The props for the CreatableSelect component
748
- * @returns {JSX.Element} CreatableSelect component
749
- */
750
- const CreatableSelect = (props) => {
751
- const { id, dataTestId = "select", async, maxMenuHeight = 200, label, error, disabled, isMulti, value, hideLabel, description, info, options, onChange, isLoading, classNamePrefix = "", filterOption, prefix, onInputChange, placeholder, isClearable, } = props;
752
- const hasError = !!error;
753
- const { refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
754
- const selectProps = {
755
- value,
756
- menuPlacement,
757
- maxMenuHeight,
758
- onChange,
759
- "aria-label": label,
760
- "data-testid": dataTestId,
761
- components: customComponents,
762
- styles: customStyles,
763
- tabSelectsValue: false,
764
- blurInputOnSelect: !isMulti,
765
- menuPortalTarget: document.body,
766
- isSearchable: disabled ? false : true,
767
- menuShouldBlockScroll: true,
768
- menuShouldScrollIntoView: true,
769
- openMenuOnFocus: disabled ? false : true,
770
- menuIsOpen: disabled ? false : menuIsOpen,
771
- openMenuOnClick: true,
772
- closeMenuOnSelect: false,
773
- isMulti: isMulti,
774
- classNamePrefix,
775
- isLoading,
776
- onInputChange,
777
- placeholder,
778
- isClearable,
779
- id,
780
- };
781
- return (jsx(SelectContainer, { label: label, hideLabel: hideLabel, id: id, hasError: hasError, error: error, description: description, info: info, dataTestId: dataTestId, isDisabled: disabled, children: jsxs(Fragment, { children: [prefix !== undefined && (jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId && `${dataTestId}-prefix`, ref: refPrefix, children: prefix })), async ? (jsx(ReactAsyncCreatableSelect, Object.assign({ "aria-label": label, maxMenuHeight: maxMenuHeight, "data-testid": dataTestId, components: customComponents }, props, { onMenuOpen: () => {
782
- !disabled && openMenuHandler();
783
- }, onMenuClose: () => {
784
- closeMenuHandler();
785
- } }))) : (jsx(ReactCreatableSelect, Object.assign({}, selectProps, { options: filterOption ? orderedOptions : options, isMulti: isMulti, onMenuOpen: () => {
786
- !disabled && openMenuHandler();
787
- }, onMenuClose: () => {
788
- closeMenuHandler();
789
- } })))] }) }));
790
- };
791
-
792
- /**
793
- * Selects are input components used to choose a value from a set.
794
- *
795
- * @param {SelectProps} props - The props for the Select component
796
- * @returns {JSX.Element} Select component
797
- */
798
- const Select = (props) => {
799
- const { className } = props, propsNoClassName = __rest(props, ["className"]);
800
- const { id, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, value, options, onChange, isLoading, classNamePrefix = dataTestId ? dataTestId : "select", onMenuScrollToBottom, filterOption, onInputChange, isSearchable, isClearable = false, readOnly, openMenuOnClick = !disabled, openMenuOnFocus = !disabled, } = props;
801
- const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
802
- const selectProps = {
803
- value,
804
- menuPlacement,
805
- maxMenuHeight,
806
- onChange,
807
- "aria-label": label,
808
- "data-testid": dataTestId,
809
- components: customComponents,
810
- styles: customStyles,
811
- tabSelectsValue: false,
812
- blurInputOnSelect: !isMulti,
813
- menuPortalTarget: props.menuPortalTarget || document.body,
814
- isSearchable: disabled || readOnly ? false : isSearchable,
815
- menuShouldBlockScroll: true,
816
- menuShouldScrollIntoView: true,
817
- openMenuOnFocus,
818
- menuIsOpen: !readOnly ? menuIsOpen : false,
819
- openMenuOnClick,
820
- closeMenuOnSelect: false,
821
- isMulti,
822
- classNamePrefix,
823
- isLoading,
824
- isClearable,
825
- id,
826
- onMenuScrollToBottom,
827
- onInputChange,
828
- };
829
- return (jsxs("div", { ref: refContainer, className: cvaSelect({ invalid: hasError, disabled: disabled || readOnly, className }), "data-testid": dataTestId, children: [prefix !== undefined && (jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId && `${dataTestId}-prefix`, ref: refPrefix, children: prefix })), async ? (jsx(ReactAsyncSelect, Object.assign({}, propsNoClassName, selectProps, async, { onMenuOpen: openMenuHandler, onMenuClose: closeMenuHandler }))) : (jsx(ReactSelect, Object.assign({}, propsNoClassName, selectProps, { options: filterOption ? orderedOptions : options, isMulti: isMulti, hideSelectedOptions: false, onMenuOpen: openMenuHandler, onMenuClose: closeMenuHandler })))] }));
830
- };
831
- Select.displayName = "Select";
832
-
833
- /**
834
- * The SelectField component is a Select component wrapped in the FromGroup component.
835
- *
836
- * This means that it can easily be added to any form alongside other Field components.
837
- *
838
- * This is done to make the field compatible with the React-hook-form library.
839
- *
840
- * @param {SelectFieldProps} props - The props for the SelectField component
841
- * @returns {JSX.Element} SelectField component
842
- */
843
- const SelectField = forwardRef((_a, ref) => {
844
- var { className, dataTestId, helpText, helpAddon, tip, label, disabled, isInvalid, errorMessage, name, onBlur, options, value, defaultValue, id, onChange } = _a; __rest(_a, ["className", "dataTestId", "helpText", "helpAddon", "tip", "label", "disabled", "isInvalid", "errorMessage", "name", "onBlur", "options", "value", "defaultValue", "id", "onChange"]);
845
- const [innerValue, setInnerValue] = useState(value || defaultValue);
846
- const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
847
- const htmlFor = useMemo(() => (id ? id : "selectField-" + v4()), [id]);
848
- const innerRef = useRef(null);
849
- useImperativeHandle(ref, () => innerRef.current, []);
850
- const handleChange = useCallback((newValue) => {
851
- setInnerValue(newValue === null || newValue === void 0 ? void 0 : newValue.value);
852
- }, []);
853
- useEffect(() => {
854
- var _a;
855
- if (!innerValue) {
856
- return;
857
- }
858
- const event = new Event("change");
859
- (_a = innerRef.current) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
860
- // The event as unknown as ChangeEvent<HTMLInputElement> assertion is needed because
861
- // the event's type is inferred as Event, which doesn't have a target property, whereas ChangeEvent does.
862
- onChange === null || onChange === void 0 ? void 0 : onChange(event);
863
- }, [onChange, innerValue]);
864
- const selectedOption = useMemo(() => options.find(option => option.value === value), [options, value]);
865
- const defaultSelectedOption = options.find(option => option.value === defaultValue);
866
- return (jsxs(FormGroup, { isInvalid: renderAsInvalid,
867
- htmlFor,
868
- className,
869
- dataTestId,
870
- helpText,
871
- helpAddon,
872
- tip,
873
- label,
874
- disabled, children: [jsx("select", { onChange, ref: innerRef, name, value: innerValue, hidden: true, children: options.map(option => {
875
- return (jsx("option", { value: option.value, children: option.label }, option.value));
876
- }) }), jsx(Select, { id,
877
- isDisabled: disabled,
878
- onBlur,
879
- options,
880
- onChange: handleChange,
881
- value: selectedOption,
882
- defaultValue: defaultSelectedOption })] }));
883
- });
884
-
885
- const cvaActionButton = cvaMerge(["drop-shadow-none", "rounded-md"], {
886
- variants: {
887
- size: {
888
- small: ["w-6", "h-6"],
889
- medium: ["w-8", "h-8"],
890
- },
891
- },
892
- defaultVariants: {
893
- size: "medium",
894
- },
895
- });
896
- const cvaActionContainer = cvaMerge(["flex", "items-center", "m-1"]);
897
-
898
- /**
899
- * The ActionButton component is a wrapper over IconButton to perform an action when the onClick event is triggered.
900
- *
901
- * @param {ActionButtonProps} props - The props for the ActionButton component
902
- * @returns {JSX.Element} ActionButton component
903
- */
904
- const ActionButton = ({ type, value, dataTestId, iconSize, disabled, key, className }) => {
905
- const [, copyToClipboard] = useCopyToClipboard();
906
- const elementKey = useMemo(() => key !== null && key !== void 0 ? key : `ActionButton-${v4()}`, [key]);
907
- const getIconName = () => {
908
- switch (type) {
909
- case "PHONE_NUMBER":
910
- return "PhoneArrowUpRight";
911
- case "WEB_ADDRESS":
912
- return "ArrowTopRightOnSquare";
913
- case "EMAIL":
914
- return "Envelope";
915
- case "COPY":
916
- default:
917
- return "ClipboardDocument";
918
- }
919
- };
920
- const ButtonAction = () => {
921
- var _a, _b;
922
- switch (type) {
923
- case "EMAIL":
924
- return window.open(`mailto:${value}`);
925
- case "WEB_ADDRESS":
926
- if (value) {
927
- return window.open(value, "_blank", "noopener,noreferrer");
928
- }
929
- return null;
930
- case "PHONE_NUMBER":
931
- return window.open(`tel:${value}`);
932
- case "COPY":
933
- return copyToClipboard((_b = (_a = value === null || value === void 0 ? void 0 : value.current) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : "");
934
- default:
935
- return null;
936
- }
937
- };
938
- if (ButtonAction === null) {
939
- return null;
940
- }
941
- return (jsx("div", { className: cvaActionContainer({ className }), children: jsx(IconButton, { disabled: disabled, dataTestId: dataTestId || "testIconButtonId", size: "small", variant: "secondary", icon: jsx(Icon, { size: "small", name: getIconName() }), onClick: ButtonAction, className: cvaActionButton({ size: iconSize }) }) }, elementKey));
942
- };
943
-
944
- const cvaInputBase = cvaMerge([
945
- "component-baseInput-shadow",
946
- "component-baseInput-border",
947
- "component-baseInput-background",
948
- "border-slate-300",
949
- "focus-within:ring-2",
950
- "focus-within:ring-inset",
951
- "focus-within:ring-primary-500",
952
- "focus-within:border-slate-400",
953
- "hover:border-slate-400",
954
- "hover:bg-slate-50",
955
- "transition",
956
- ]);
957
- const cvaInputBaseDisabled = cvaMerge(["bg-slate-100", "hover:bg-slate-100", "hover:border-slate-300"]);
958
- const cvaInputBaseInvalid = cvaMerge(["border-danger-600", "focus-within:ring-danger-600"]);
959
- const cvaInput = cvaMerge(["relative", "flex", "h-10", cvaInputBase()], {
960
- variants: {
961
- size: {
962
- small: ["h-8"],
963
- medium: ["h-10"],
964
- },
965
- disabled: {
966
- true: cvaInputBaseDisabled(),
967
- false: "",
968
- },
969
- invalid: {
970
- true: cvaInputBaseInvalid(),
971
- false: "",
972
- },
973
- },
974
- });
975
- const cvaInputField = cvaMerge([
976
- "w-full",
977
- "px-3",
978
- "border-0",
979
- "bg-transparent",
980
- "text-base",
981
- "text-slate-900",
982
- "placeholder-slate-400",
983
- "focus-visible:outline-none",
984
- ], {
985
- variants: {
986
- size: {
987
- small: ["py-1"],
988
- medium: ["py-2"],
989
- },
990
- disabled: {
991
- true: ["text-slate-700"],
992
- false: "",
993
- },
994
- },
995
- });
996
- const cvaInputAddon = cvaMerge([
997
- "flex",
998
- "justify-center",
999
- "items-center",
1000
- "px-3",
1001
- "border-slate-300",
1002
- "text-slate-500",
1003
- "bg-slate-50",
1004
- ]);
1005
- const cvaInputAddonBefore = cvaMerge([cvaInputAddon(), "border-r", "rounded-l-lg"]);
1006
- const cvaInputAddonAfter = cvaMerge([cvaInputAddon(), "border-l", "rounded-r-lg"]);
1007
- const cvaInputPrefix = cvaMerge([
1008
- "flex",
1009
- "justify-center",
1010
- "items-center",
1011
- "text-slate-400",
1012
- "hover:component-search-prefix",
1013
- "component-baseInput-prefix",
1014
- "component-search-borderless",
1015
- "px-3",
1016
- ], {
1017
- variants: {
1018
- disabled: {
1019
- true: ["text-slate-500"],
1020
- false: "",
1021
- },
1022
- },
1023
- });
1024
- const cvaInputSuffix = cvaMerge(["flex", "justify-center", "items-center", "text-slate-400", "px-3"], {
1025
- variants: {
1026
- disabled: {
1027
- true: ["text-slate-500"],
1028
- false: "",
1029
- },
1030
- },
1031
- });
1032
-
1033
- /**
1034
- * A base input component that can be used for text inputs, password inputs, etc.
1035
- * A reference to the input element is provided as the `ref` prop.
1036
- * Extends props from [React.InputHTMLAttributes](https://reactjs.org/docs/dom-elements.html#input)
1037
- *
1038
- * For specific input types make sure to use the corresponding input component.
1039
- * This is a base used by our other input components such as TextInput, NumberInput, PasswordInput, etc.
1040
- */
1041
- const BaseInput = React.forwardRef((_a, ref) => {
1042
- var { className, isInvalid, dataTestId, prefix, suffix, addonBefore, addonAfter, actions, fieldSize = "medium", nonInteractive = false, showDefaultActions = false, type, inputClassName, addonBeforeClassName } = _a, rest = __rest(_a, ["className", "isInvalid", "dataTestId", "prefix", "suffix", "addonBefore", "addonAfter", "actions", "fieldSize", "nonInteractive", "showDefaultActions", "type", "inputClassName", "addonBeforeClassName"]);
1043
- const isReadOnlyWithPlaceholder = useMemo(() => !!rest.readOnly && !!rest.placeholder && !rest.value, [rest.readOnly, rest.placeholder, rest.value]);
1044
- const renderAsDisabled = rest.disabled || rest.readOnly;
1045
- const innerRef = React.useRef(null);
1046
- React.useImperativeHandle(ref, () => innerRef.current, []);
1047
- return (jsxs("div", { className: cvaInput({
1048
- disabled: renderAsDisabled,
1049
- invalid: isInvalid,
1050
- size: fieldSize,
1051
- className,
1052
- }), "data-testid": dataTestId && `${dataTestId}-container`, children: [addonBefore && addonBefore !== undefined ? (jsx("div", { className: cvaInputAddonBefore({ className: addonBeforeClassName }), "data-testid": dataTestId && `${dataTestId}-addonBefore`, children: addonBefore })) : null, prefix && addonBefore !== prefix ? (jsx("div", { className: cvaInputPrefix({
1053
- disabled: renderAsDisabled,
1054
- }), "data-testid": dataTestId && `${dataTestId}-prefix`, children: prefix })) : null, jsx("input", Object.assign({ ref: innerRef, "data-testid": dataTestId, className: cvaInputField({ size: fieldSize, disabled: renderAsDisabled, className: inputClassName }), type: isReadOnlyWithPlaceholder ? "text" : type }, rest, { readOnly: rest.readOnly || nonInteractive })), suffix && addonBefore !== suffix ? (jsx("div", { className: cvaInputSuffix({
1055
- disabled: renderAsDisabled,
1056
- }), "data-testid": dataTestId && `${dataTestId}-suffix`, children: suffix })) : null, rest.readOnly === true && showDefaultActions ? (jsx(ActionButton, { type: "COPY", value: innerRef }, "default-copy-action")) : null, actions && addonBefore !== actions ? actions : null, addonAfter && addonAfter !== undefined && addonBefore !== addonAfter ? (jsx("div", { className: cvaInputAddonAfter(), "data-testid": dataTestId && `${dataTestId}-addonAfter`, children: addonAfter })) : null] }));
1057
- });
1058
-
1059
- /**
1060
- * A wrapper around BaseInput with a pop-up day picker.
1061
- *
1062
- * NOTE: If shown with a label, please use the `DateField` component instead.
1063
- */
1064
- const DateInput = forwardRef((_a, ref) => {
1065
- var { min, max, defaultValue, value } = _a, rest = __rest(_a, ["min", "max", "defaultValue", "value"]);
1066
- const formatDateToInputString = (date) => date instanceof Date ? format(date, "yyyy-MM-dd") : date;
1067
- // Chrome and Firefox need their default icon to have datepicker functionality.
1068
- const showIcon = !/Chrome/.test(navigator.userAgent) && !/Firefox/.test(navigator.userAgent);
1069
- return (jsx(BaseInput, Object.assign({ type: "date", value: formatDateToInputString(value), defaultValue: formatDateToInputString(defaultValue), min: formatDateToInputString(min), max: formatDateToInputString(max), ref: ref, suffix: showIcon && jsx(Icon, { dataTestId: "calendar", name: "Calendar", size: "medium", type: "solid" }) }, rest)));
1070
- });
1071
-
1072
- /**
1073
- * The date field component is used for entering date values.
1074
- *
1075
- * _**Do use**_ the DateField for date input.
1076
- *
1077
- * _**Do not use**_ this fields for non-serialized dates. Use TextField instead.
1078
- */
1079
- const DateField = forwardRef((_a, ref) => {
1080
- var { label, id, tip, helpText, errorMessage, helpAddon, isInvalid, className, defaultValue, dataTestId } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "errorMessage", "helpAddon", "isInvalid", "className", "defaultValue", "dataTestId"]);
1081
- const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
1082
- const htmlForId = id ? id : "dateField-" + v4();
1083
- return (jsx(FormGroup, { htmlFor: htmlForId, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && errorMessage) || helpText, helpAddon: helpAddon, disabled: rest.disabled, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsx(DateInput, Object.assign({ id: htmlForId, "aria-labelledby": htmlForId + "-label", ref: ref, defaultValue: defaultValue, isInvalid: renderAsInvalid }, rest, { className: className, dataTestId: dataTestId })) }));
1084
- });
1085
-
1086
- const cvaDropZone = cvaMerge([
1087
- "flex",
1088
- "component-baseInput-background",
1089
- "justify-center",
1090
- "text-slate-500",
1091
- "rounded-sm",
1092
- "border-2",
1093
- "border-gray-200",
1094
- "border-dashed",
1095
- "hover:bg-slate-100",
1096
- "hover:border-solid",
1097
- "hover:border-primary-500",
1098
- ], {
1099
- variants: {
1100
- size: {
1101
- small: ["p-2"],
1102
- medium: ["p-4"],
1103
- large: ["p-8"],
1104
- },
1105
- disabled: { true: ["bg-slate-100", "hover:bg-slate-100"], false: "" },
1106
- dragActive: { true: ["border-gray-200", "bg-slate-100"], false: "" },
1107
- dropComplete: {
1108
- true: ["border-solid", "border-primary-500", "bg-slate-100", "hover:border-solid", "hover:border-gray-200"],
1109
- false: "",
1110
- },
1111
- invalid: { true: ["border-danger-600", "text-danger-500"], false: "" },
1112
- },
1113
- });
1114
- const cvaDropZoneLabel = cvaMerge([
1115
- "h-full",
1116
- "pt-1",
1117
- "pb-1",
1118
- "gap-2",
1119
- "items-center",
1120
- "flex-col",
1121
- "flex",
1122
- "justify-center",
1123
- ]);
1124
-
1125
- /**
1126
- * The Drop Zone can be used to drag and drop files
1127
- *
1128
- * @param {DropZoneProps} props - The props for the DropZone component
1129
- * @returns {JSX.Element} DropZone component
1130
- */
1131
- const DropZone = (_a) => {
1132
- var { className, dataTestId, filesSelected, label, size = "large", isInvalid = false, disabled = false } = _a, rest = __rest(_a, ["className", "dataTestId", "filesSelected", "label", "size", "isInvalid", "disabled"]);
1133
- const [dragActive, setDragActive] = React__default.useState(false);
1134
- const [fileDropped, setFileDropped] = React__default.useState(false);
1135
- // function that handles drag enter, drag leave and drag over
1136
- const handleDrag = (e) => {
1137
- e.preventDefault();
1138
- e.stopPropagation();
1139
- if ((e.type === "dragenter" || e.type === "dragover") && !disabled) {
1140
- setDragActive(true);
1141
- }
1142
- else if (e.type === "dragleave") {
1143
- setDragActive(false);
1144
- }
1145
- };
1146
- //function to handle when user clicks on dropzone to upload
1147
- const handleChange = (e) => {
1148
- e.preventDefault();
1149
- e.stopPropagation();
1150
- if (e.target.files && !disabled) {
1151
- filesSelected(e.target.files);
1152
- }
1153
- };
1154
- //funtion to handle drop
1155
- const handleDrop = (e) => {
1156
- e.preventDefault();
1157
- e.stopPropagation();
1158
- setDragActive(false);
1159
- if (e.dataTransfer.files && e.dataTransfer.files[0] && !disabled) {
1160
- filesSelected(e.dataTransfer.files);
1161
- setFileDropped(true);
1162
- }
1163
- };
1164
- return (jsxs("div", Object.assign({ className: cvaDropZone({ size, dropComplete: fileDropped, dragActive, disabled, invalid: isInvalid, className }), "data-testid": dataTestId, onDragEnter: handleDrag, onDragLeave: handleDrag, onDragOver: handleDrag, onDrop: handleDrop, onClick: e => {
1165
- if (disabled) {
1166
- e.preventDefault();
1167
- e.stopPropagation();
1168
- }
1169
- } }, rest, { children: [jsx("input", { title: "Hidden File Input", type: "file", id: "input-file-upload", onChange: handleChange, className: "hidden" }), jsxs("label", { className: cvaDropZoneLabel(), htmlFor: "input-file-upload", "data-testid": dataTestId && `${dataTestId}-label`, children: [jsx(Icon, { type: "solid", name: "ArrowUpCircle", color: isInvalid ? "danger" : "neutral", style: !isInvalid ? { color: "rgb(156 163 175)" } : {} }), jsx("span", { children: label })] })] })));
1170
- };
1171
-
1172
- // Doing the same check as we do on the backend
1173
- // Using OWASP pattern from: https://owasp.org/www-community/OWASP_Validation_Regex_Repository
1174
- const EMAIL_REGEX = /^[a-zA-Z0-9_+&*-]+(?:\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,7}$/;
649
+ // Doing the same check as we do on the backend
650
+ // Using OWASP pattern from: https://owasp.org/www-community/OWASP_Validation_Regex_Repository
651
+ const EMAIL_REGEX = /^[a-zA-Z0-9_+&*-]+(?:\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,7}$/;
1175
652
  /**
1176
653
  * @description Validate given email id.
1177
654
  * @param email The address to validate.
@@ -1202,7 +679,7 @@ const EmailInput = React.forwardRef((_a, ref) => {
1202
679
  return window.open(`mailto:${email}`);
1203
680
  };
1204
681
  const renderAsInvalid = (email && !validateEmailAddress(email)) || isInvalid;
1205
- return (jsx(BaseInput, Object.assign({ dataTestId: dataTestId, ref: ref, type: "email", placeholder: rest.placeholder || "mail@example.com", onChange: e => setEmail(e.target.value), isInvalid: renderAsInvalid, actions: jsx(ActionButton, { disabled: disabled, value: email, type: "EMAIL", onClick: sendEmail, dataTestId: dataTestId && `${dataTestId}-emailIcon`, iconSize: fieldSize }) }, rest)));
682
+ return (jsx(BaseInput, Object.assign({ actions: jsx(ActionButton, { dataTestId: dataTestId && `${dataTestId}-emailIcon`, disabled: disabled, iconSize: fieldSize, onClick: sendEmail, type: "EMAIL", value: email }), dataTestId: dataTestId, isInvalid: renderAsInvalid, onChange: e => setEmail(e.target.value), placeholder: rest.placeholder || "mail@example.com", ref: ref, type: "email" }, rest)));
1206
683
  });
1207
684
 
1208
685
  /**
@@ -1223,7 +700,7 @@ const EmailField = forwardRef((_a, ref) => {
1223
700
  onChange(event);
1224
701
  }
1225
702
  }, [onChange]);
1226
- return (jsx(FormGroup, { htmlFor: htmlForId, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && errorMessage) || helpText, helpAddon: helpAddon, disabled: rest.disabled, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsx(EmailInput, Object.assign({ id: htmlForId, "aria-labelledby": htmlForId + "-label", ref: ref, defaultValue: defaultValue, value: value, onChange: handleChange, isInvalid: renderAsInvalid, disabled: renderAsInvalid }, rest, { className: className, dataTestId: dataTestId })) }));
703
+ return (jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(EmailInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, disabled: renderAsInvalid, id: htmlForId, isInvalid: renderAsInvalid, onChange: handleChange, ref: ref, value: value }, rest, { className: className, dataTestId: dataTestId })) }));
1227
704
  });
1228
705
 
1229
706
  /**
@@ -1246,7 +723,7 @@ const NumberField = forwardRef((_a, ref) => {
1246
723
  var { label, id, tip, helpText, errorMessage, helpAddon, isInvalid, maxLength, className, value, dataTestId } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "errorMessage", "helpAddon", "isInvalid", "maxLength", "className", "value", "dataTestId"]);
1247
724
  const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
1248
725
  const htmlForId = id ? id : "numberField-" + v4();
1249
- return (jsx(FormGroup, { htmlFor: htmlForId, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && errorMessage) || helpText, helpAddon: helpAddon, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsx(NumberInput, Object.assign({ id: htmlForId, "aria-labelledby": htmlForId + "-label", ref: ref, maxLength: maxLength, value: value, isInvalid: renderAsInvalid }, rest, { className: className, dataTestId: dataTestId })) }));
726
+ return (jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(NumberInput, Object.assign({ "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, ref: ref, value: value }, rest, { className: className, dataTestId: dataTestId })) }));
1250
727
  });
1251
728
 
1252
729
  const cvaOptionCardLabel = cvaMerge([
@@ -1267,117 +744,573 @@ const cvaOptionCardLabel = cvaMerge([
1267
744
  ], {
1268
745
  variants: {
1269
746
  disabled: {
1270
- true: [cvaInputBaseDisabled(), "cursor-not-allowed"],
1271
- false: ["cursor-pointer"],
747
+ true: [cvaInputBaseDisabled(), "cursor-not-allowed"],
748
+ false: ["cursor-pointer"],
749
+ },
750
+ },
751
+ });
752
+ const cvaOptionCardContent = cvaMerge(["flex", "flex-col", "items-center"]);
753
+ const cvaOptionCardContainer = cvaMerge(["contents"]);
754
+
755
+ /**
756
+ * A card version of a radio button that includes an icon, headings and a description.
757
+ */
758
+ const OptionCard = forwardRef((_a, ref) => {
759
+ var { icon, heading, subheading, description, disabled, id, value, className, dataTestId } = _a, rest = __rest(_a, ["icon", "heading", "subheading", "description", "disabled", "id", "value", "className", "dataTestId"]);
760
+ const htmlForId = id !== null && id !== void 0 ? id : "option-card-" + v4();
761
+ return (jsxs("div", { className: cvaOptionCardContainer(), "data-testid": dataTestId, children: [jsx("input", Object.assign({ className: "peer hidden", id: htmlForId, ref: ref, type: "radio", value: value }, rest)), jsxs("label", { className: cvaOptionCardLabel({ className, disabled }), htmlFor: htmlForId, children: [disabled && icon && cloneElement(icon, { className: `${icon.props.className} text-secondary-400` }), !disabled && icon, heading && (jsx(Heading, { subtle: disabled, variant: "secondary", children: heading })), (subheading || description) && (jsxs("div", { className: cvaOptionCardContent(), children: [subheading && (jsx(Text, { align: "center", subtle: disabled, type: "span", weight: "thick", children: subheading })), description && (jsx(Text, { align: "center", subtle: true, type: "span", children: description }))] }))] })] }));
762
+ });
763
+
764
+ /**
765
+ * A thin wrapper around the `BaseInput` component for password input fields.
766
+ *
767
+ * NOTE: If shown with a label, please use the `PasswordField` component instead.
768
+ */
769
+ const PasswordInput = forwardRef((props, ref) => (jsx(BaseInput, Object.assign({ ref: ref }, props))));
770
+
771
+ /**
772
+ * Password fields enter a password or other confidential information. Characters are masked as they are typed.
773
+ *
774
+ * _**Do use** when the user has to input a password or something that needs to be obfuscated_
775
+ *
776
+ * _**Do not use** to confirm user actions, such as deleting. Use a checkbox for such flows._
777
+ */
778
+ const PasswordField = forwardRef((_a, ref) => {
779
+ var { id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, dataTestId } = _a, rest = __rest(_a, ["id", "label", "tip", "helpText", "helpAddon", "errorMessage", "isInvalid", "maxLength", "onChange", "className", "value", "dataTestId"]);
780
+ const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
781
+ const htmlFor = id ? id : "passwordField-" + v4();
782
+ const [showPassword, setShowPassword] = useState(false);
783
+ const handleChange = useCallback((event) => {
784
+ onChange === null || onChange === void 0 ? void 0 : onChange(event);
785
+ }, [onChange]);
786
+ return (jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(PasswordInput, Object.assign({}, rest, { actions: jsx(Icon, { className: "absolute top-0 bottom-0 right-2 h-full content-center", color: "neutral", name: showPassword ? "EyeSlash" : "Eye", onClick: () => setShowPassword(prevState => !prevState), size: "small" }), "aria-labelledby": htmlFor + "-label", className: className, dataTestId: dataTestId, disabled: rest.readOnly, id: htmlFor, isInvalid: renderAsInvalid, maxLength: maxLength, onChange: handleChange, ref: ref, type: showPassword ? "text" : "password", value: value })) }));
787
+ });
788
+
789
+ /**
790
+ * @param phoneNumber - a phone number as a string
791
+ * @returns {boolean} true if the phone number starts with a plus sign
792
+ * @example checkIfPhoneNumberHasPlus("123456789") // false
793
+ * checkIfPhoneNumberHasPlus("+123456789") // true
794
+ */
795
+ const checkIfPhoneNumberHasPlus = (phoneNumber) => {
796
+ return phoneNumber.startsWith("+");
797
+ };
798
+ /**
799
+ * @param phoneNumber - a phone number as a string
800
+ * @returns {string|number} the phone number with a plus sign in front of it
801
+ * @example getPhoneNumberWithPlus("123456789") // "+123456789"
802
+ */
803
+ const getPhoneNumberWithPlus = (phoneNumber) => {
804
+ const stringPhoneNumber = phoneNumber.toString();
805
+ return checkIfPhoneNumberHasPlus(stringPhoneNumber) ? stringPhoneNumber : `+${stringPhoneNumber}`;
806
+ };
807
+ /**
808
+ * Generates a flag emoji based on the given country code.
809
+ *
810
+ * @param {string} countryCode - The two-letter country code (ISO 3166-1 alpha-2).
811
+ * @returns {string} - The corresponding flag emoji for the given country code.
812
+ * @example getPhoneNumberWithPlus("DK") // "🇩🇰"
813
+ */
814
+ const countryCodeToFlagEmoji = (countryCode) => {
815
+ let code = countryCode;
816
+ if (countryCode.startsWith("+")) {
817
+ code = getCountryAbbreviation(countryCode.substring(1));
818
+ }
819
+ else if (!isNaN(Number(countryCode))) {
820
+ code = getCountryAbbreviation(countryCode);
821
+ }
822
+ return isSupportedCountry(code.toUpperCase())
823
+ ? code.toUpperCase().replace(/./g, char => String.fromCodePoint(127397 + char.charCodeAt(0)))
824
+ : "";
825
+ };
826
+ /**
827
+ * Retrieves the ISO 3166-1 alpha-2 country code associated with a given international calling code.
828
+ *
829
+ * @param {string} callCode - The international calling code for a country.
830
+ * @returns {string} The abbreviation for a country or an empty string if no matching country is found.
831
+ * @example getCountryAbbreviation("45") // "DK"
832
+ * @example getCountryAbbreviation("+45") // "DK"
833
+ */
834
+ const getCountryAbbreviation = (callCode) => {
835
+ let code = callCode;
836
+ if (callCode.startsWith("+")) {
837
+ code = callCode.substring(1);
838
+ }
839
+ return getCountries().find(c => getCountryCallingCode(c) === code) || "";
840
+ };
841
+
842
+ /**
843
+ * A custom hook for managing phone number input state and validation.
844
+ *
845
+ * @property {Function} getPhoneNumber - A function for get formatted phone number with country code and plus sign
846
+ */
847
+ const usePhoneInput = () => {
848
+ const getPhoneNumber = ({ country, phone }) => {
849
+ if (country) {
850
+ return getPhoneNumberWithPlus(`${country}${phone || ""}`);
851
+ }
852
+ return phone || "";
853
+ };
854
+ return {
855
+ getPhoneNumber,
856
+ };
857
+ };
858
+
859
+ const cvaSelect = cvaMerge([
860
+ "relative",
861
+ "flex",
862
+ "shadow-sm",
863
+ "rounded-lg",
864
+ "border",
865
+ "border-slate-300",
866
+ "focus-within:ring-2",
867
+ "focus-within:ring-inset",
868
+ "focus-within:ring-primary-600",
869
+ "focus-within:border-slate-400",
870
+ "hover:border-slate-400",
871
+ "hover:bg-slate-50",
872
+ "bg-white",
873
+ "transition",
874
+ ], {
875
+ variants: {
876
+ invalid: {
877
+ true: "border-red-600 text-red-600 focus-within:ring-red-600 hover:border-red-600",
878
+ false: "",
879
+ },
880
+ disabled: {
881
+ true: "!bg-slate-100",
882
+ false: "",
1272
883
  },
1273
884
  },
885
+ defaultVariants: {
886
+ invalid: false,
887
+ disabled: false,
888
+ },
1274
889
  });
1275
- const cvaOptionCardContent = cvaMerge(["flex", "flex-col", "items-center"]);
1276
- const cvaOptionCardContainer = cvaMerge(["contents"]);
890
+ const cvaSelectIcon = cvaMerge("mr-2 flex cursor-pointer items-center justify-center text-slate-400 hover:text-slate-500");
891
+ const cvaSelectPrefix = cvaMerge(["flex", "justify-center", "items-center", "text-slate-400", "pl-2"]);
892
+ const cvaSelectXIcon = cvaMerge([
893
+ "mr-2 flex cursor-pointer items-center justify-center text-slate-400 hover:text-slate-500",
894
+ "ml-1",
895
+ ]);
896
+ const cvaSelectMenuList = cvaMerge(["min-w-min", "shadow-md", "rounded-lg", "z-20", "bg-white", "p-1", "border", "border-slate-300", "gap-1", "grid"], {
897
+ variants: {
898
+ menuIsOpen: {
899
+ true: "animate-fade-in-fast",
900
+ false: "animate-fade-out-fast",
901
+ },
902
+ },
903
+ });
904
+ const cvaSelectDynamicTagContainer = cvaMerge(["h-full", "flex", "gap-1", "items-center"], {
905
+ variants: {
906
+ visible: { true: "visible", false: "invisible" },
907
+ },
908
+ });
909
+ const cvaSelectCounter = cvaMerge(["overflow-hidden", "whitespace-nowrap"]);
910
+ const cvaSelectMenu = cvaMerge(["relative", "p-1", "grid", "gap-1"]);
1277
911
 
1278
912
  /**
1279
- * A card version of a radio button that includes an icon, headings and a description.
913
+ * @param {MultiValue<Option> | SingleValue<Option>} arg option to check type
914
+ * @returns {arg is MultiValue<Option> } is Multivalue
1280
915
  */
1281
- const OptionCard = forwardRef((_a, ref) => {
1282
- var { icon, heading, subheading, description, disabled, id, value, className, dataTestId } = _a, rest = __rest(_a, ["icon", "heading", "subheading", "description", "disabled", "id", "value", "className", "dataTestId"]);
1283
- const htmlForId = id !== null && id !== void 0 ? id : "option-card-" + v4();
1284
- return (jsxs("div", { "data-testid": dataTestId, className: cvaOptionCardContainer(), children: [jsx("input", Object.assign({ ref: ref, id: htmlForId, type: "radio", value: value, className: "peer hidden" }, rest)), jsxs("label", { htmlFor: htmlForId, className: cvaOptionCardLabel({ className, disabled }), children: [disabled && icon && cloneElement(icon, { className: `${icon.props.className} text-secondary-400` }), !disabled && icon, heading && (jsx(Heading, { variant: "secondary", subtle: disabled, children: heading })), (subheading || description) && (jsxs("div", { className: cvaOptionCardContent(), children: [subheading && (jsx(Text, { type: "span", weight: "thick", align: "center", subtle: disabled, children: subheading })), description && (jsx(Text, { type: "span", subtle: true, align: "center", children: description }))] }))] })] }));
1285
- });
916
+ function isMultiValue(arg) {
917
+ return Array.isArray(arg);
918
+ }
919
+ function isGroupBase(arg) {
920
+ return arg.options !== undefined;
921
+ }
922
+ const isSelectedOption = (option, selected) => {
923
+ if (isGroupBase(option)) {
924
+ return false;
925
+ }
926
+ return isMultiValue(selected)
927
+ ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
928
+ selected.some(v => v.value === option.value)
929
+ : // eslint-disable-next-line @typescript-eslint/no-explicit-any
930
+ option.value === (selected === null || selected === void 0 ? void 0 : selected.value);
931
+ };
932
+ const removeSelectedFromGroups = (group, selected) => {
933
+ if (isGroupBase(group)) {
934
+ return Object.assign(Object.assign({}, group), { options: group.options.filter(option => !isSelectedOption(option, selected)) });
935
+ }
936
+ return group;
937
+ };
938
+ /**
939
+ * @template IsMulti
940
+ * @template Group
941
+ * @param {OptionsOrGroups<Option, Group> | undefined} options An array of options to select from
942
+ * @param {PropsValue<Option> | undefined} value Selected values
943
+ * @returns {OptionsOrGroups<Option, Group>} An array of ordered options with selected on top
944
+ */
945
+ const getOrderedOptions = (options, value) => {
946
+ if (value && options) {
947
+ const orderedValues = isMultiValue(value)
948
+ ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
949
+ [...value].sort((a, b) => a.label.localeCompare(b.label))
950
+ : [value];
951
+ const selectableOptions = options
952
+ .filter(option => !isSelectedOption(option, value))
953
+ .map(option => removeSelectedFromGroups(option, value));
954
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
955
+ return orderedValues.concat(selectableOptions) || [];
956
+ }
957
+ return options || [];
958
+ };
1286
959
 
1287
960
  /**
1288
- * A thin wrapper around the `BaseInput` component for password input fields.
961
+ * A single select menu item is a basic wrapper around Menu item designed to be used as a single value render in Select list
1289
962
  *
1290
- * NOTE: If shown with a label, please use the `PasswordField` component instead.
963
+ * @param {SelectMenuItemProps} props - The props for the SingleSelectMenuItem
964
+ * @returns {JSX.Element} SingleSelectMenuItem
1291
965
  */
1292
- const PasswordInput = forwardRef((props, ref) => (jsx(BaseInput, Object.assign({ ref: ref }, props))));
966
+ const SingleSelectMenuItem = ({ label, icon, onClick, selected, dataTestId, focused, disabled, }) => {
967
+ return (jsx(MenuItem, { dataTestId: dataTestId, disabled: disabled, focused: focused, label: label, onClick: onClick, prefix: icon, selected: selected, suffix: selected ? jsx(Icon, { name: "Check", size: "small" }) : undefined }));
968
+ };
969
+ /**
970
+ * A multi select menu item is a basic wrapper around Menu item designed to be used as a multi value render in Select list
971
+ *
972
+ * @param {SelectMenuItemProps} props - The props for the MultiSelectMenuItem
973
+ * @returns {JSX.Element} multi select menu item
974
+ */
975
+ const MultiSelectMenuItem = ({ label, onClick, selected, dataTestId, focused, disabled, }) => {
976
+ return (jsx(MenuItem, { dataTestId: dataTestId, disabled: disabled, focused: focused, label: label, onClick: e => {
977
+ e.stopPropagation();
978
+ onClick && onClick(e);
979
+ }, prefix: jsx(Checkbox, { checked: selected, disabled: disabled, onChange: () => null, onClick: e => {
980
+ e.stopPropagation();
981
+ }, readOnly: false }), selected: selected }));
982
+ };
1293
983
 
1294
984
  /**
1295
- * Password fields enter a password or other confidential information. Characters are masked as they are typed.
985
+ * Extended Tag component with information about its own width.
986
+ * Used in the select component.
1296
987
  *
1297
- * _**Do use** when the user has to input a password or something that needs to be obfuscated_
988
+ * @param {TagProps} props - The props for the tag component
989
+ * @returns {JSX.Element} TagWithWidth component
990
+ */
991
+ const TagWithWidth = (_a) => {
992
+ var { onWidthKnown, children } = _a, rest = __rest(_a, ["onWidthKnown", "children"]);
993
+ const ref = React__default.useRef(null);
994
+ React__default.useLayoutEffect(() => {
995
+ var _a;
996
+ onWidthKnown && onWidthKnown({ width: ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0 });
997
+ }, [ref, onWidthKnown]);
998
+ return (jsx(Tag, Object.assign({ ref: ref }, rest, { children: children })));
999
+ };
1000
+
1001
+ /**
1002
+ * TagsContainer component to display tags in limited space when children can't fit space it displays counter
1298
1003
  *
1299
- * _**Do not use** to confirm user actions, such as deleting. Use a checkbox for such flows._
1004
+ * @param {TagsContainerProps} props - The props for the TagContainer
1005
+ * @returns {JSX.Element} TagsContainer
1300
1006
  */
1301
- const PasswordField = forwardRef((_a, ref) => {
1302
- var { id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, dataTestId } = _a, rest = __rest(_a, ["id", "label", "tip", "helpText", "helpAddon", "errorMessage", "isInvalid", "maxLength", "onChange", "className", "value", "dataTestId"]);
1303
- const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
1304
- const htmlFor = id ? id : "passwordField-" + v4();
1305
- const [showPassword, setShowPassword] = useState(false);
1306
- const handleChange = useCallback((event) => {
1307
- onChange === null || onChange === void 0 ? void 0 : onChange(event);
1308
- }, [onChange]);
1309
- return (jsx(FormGroup, { htmlFor: htmlFor, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && errorMessage) || helpText, helpAddon: helpAddon, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsx(PasswordInput, Object.assign({}, rest, { type: showPassword ? "text" : "password", disabled: rest.readOnly, id: htmlFor, "aria-labelledby": htmlFor + "-label", ref: ref, maxLength: maxLength, value: value, isInvalid: renderAsInvalid, className: className, onChange: handleChange, dataTestId: dataTestId, actions: jsx(Icon, { className: "absolute top-0 bottom-0 right-2 h-full content-center", name: showPassword ? "EyeSlash" : "Eye", size: "small", color: "neutral", onClick: () => setShowPassword(prevState => !prevState) }) })) }));
1310
- });
1007
+ const TagsContainer = ({ items, width = "100%", itemsGap = 5, postFix, disabled }) => {
1008
+ const [isReady, setIsReady] = React__default.useState(false);
1009
+ const [counterWidth, setCounterWidth] = React__default.useState(0);
1010
+ const containerRef = React__default.useRef(null);
1011
+ const availableWidth = React__default.useRef();
1012
+ const childrenWidth = React__default.useRef([]);
1013
+ const itemsCount = items.length;
1014
+ React__default.useLayoutEffect(() => {
1015
+ var _a;
1016
+ availableWidth.current = ((_a = containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0;
1017
+ }, [containerRef]);
1018
+ const onWidthKnownHandler = ({ width: reportedWidth }) => {
1019
+ childrenWidth.current.push({ width: reportedWidth + itemsGap });
1020
+ if (childrenWidth.current.length === itemsCount) {
1021
+ setIsReady(true);
1022
+ }
1023
+ };
1024
+ const requiredSpace = childrenWidth.current.reduce((previous, current) => {
1025
+ return previous + current.width;
1026
+ }, 0);
1027
+ let counter = 0;
1028
+ const availableSpace = ((availableWidth === null || availableWidth === void 0 ? void 0 : availableWidth.current) || 0) - counterWidth;
1029
+ const renderedElements = items
1030
+ .concat({ text: "", onClick: () => null, disabled: false }) // reserved element for a potential counter
1031
+ .map((item, index) => {
1032
+ const spaceNeeded = childrenWidth.current.slice(0, index + 1).reduce((previous, current) => {
1033
+ return previous + current.width;
1034
+ }, 0);
1035
+ const isLast = index === items.length;
1036
+ const counterRequired = requiredSpace > availableSpace && counter !== 0;
1037
+ if (isLast && counterRequired) {
1038
+ return (jsx(TagWithWidth, { color: "white", disabled: disabled, onWidthKnown: ({ width: reportedWidth }) => setCounterWidth(reportedWidth), children: jsxs("div", { className: cvaSelectCounter(), "data-testid": "select-counter", children: ["+", counter] }) }, item.text + index));
1039
+ }
1040
+ if (isLast) {
1041
+ return null;
1042
+ }
1043
+ const itemCanFit = spaceNeeded <= availableSpace;
1044
+ if (itemCanFit) {
1045
+ return (jsx(TagWithWidth, { className: "inline-flex shrink-0", color: item.disabled ? "unknown" : "primary", dataTestId: `${item.text}-tag`, disabled: disabled, onClose: e => {
1046
+ e.stopPropagation();
1047
+ item.onClick();
1048
+ }, onWidthKnown: onWidthKnownHandler, children: item.text }, item.text + index));
1049
+ }
1050
+ const fromTheItems = item.text !== "";
1051
+ if (fromTheItems) {
1052
+ counter = counter + 1;
1053
+ }
1054
+ return null;
1055
+ })
1056
+ .filter(element => element !== null);
1057
+ return (jsxs("div", { className: cvaSelectDynamicTagContainer({ visible: isReady }), ref: containerRef, style: {
1058
+ width: `${width}`,
1059
+ }, children: [renderedElements, postFix] }));
1060
+ };
1311
1061
 
1312
1062
  /**
1313
- * @param phoneNumber - a phone number as a string
1314
- * @returns {boolean} true if the phone number starts with a plus sign
1315
- * @example checkIfPhoneNumberHasPlus("123456789") // false
1316
- * checkIfPhoneNumberHasPlus("+123456789") // true
1063
+ * A hook to retrieve components override object.
1064
+ * This complex object includes all the compositional components that are used in react-select. If you wish to overwrite a component, pass in an object with the appropriate namespace.
1065
+ *
1066
+ * @template IsMulti
1067
+ * @template Group
1068
+ * @param {Partial<SelectComponents<Option, IsMulti, Group>> | undefined} componentsProps a custom component prop that you can to override defaults
1069
+ * @param {boolean} disabled decide to override disabled variant
1070
+ * @param {boolean} menuIsOpen menu is open state
1071
+ * @param {React.MutableRefObject<boolean>} refMenuIsEnabled a flag to block menu from open
1072
+ * @param {string} dataTestId a test id
1073
+ * @param {number} maxSelectedDisplayCount a number of max display count
1074
+ * @param {JSX.Element} dropdownIcon an custom dropdown icon
1075
+ * @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
1317
1076
  */
1318
- const checkIfPhoneNumberHasPlus = (phoneNumber) => {
1319
- return phoneNumber.startsWith("+");
1077
+ const useCustomComponents = (componentsProps, disabled, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon) => {
1078
+ const [t] = useTranslation();
1079
+ // perhaps it should not be wrap in memo (causing some issues with opening and closing on mobiles)
1080
+ const customComponents = React.useMemo(() => {
1081
+ return Object.assign({ ValueContainer: props => {
1082
+ if (props.isMulti && Array.isArray(props.children) && props.children.length > 0) {
1083
+ const PLACEHOLDER_KEY = "placeholder";
1084
+ const key = props && props.children && props.children[0] ? props.children[0].key : "";
1085
+ const values = props && props.children ? props.children[0] : [];
1086
+ const tags = key === PLACEHOLDER_KEY ? [] : values;
1087
+ const searchInput = props && props.children && props.children[1];
1088
+ return (jsx(components.ValueContainer, Object.assign({}, props, { isDisabled: props.selectProps.isDisabled, children: maxSelectedDisplayCount === undefined ? (jsx(TagsContainer, { disabled: disabled, items: tags
1089
+ ? tags.map(({ props: tagProps }) => {
1090
+ return {
1091
+ text: tagProps.children,
1092
+ onClick: disabled
1093
+ ? undefined
1094
+ : (e) => {
1095
+ var _a, _b;
1096
+ refMenuIsEnabled.current = false;
1097
+ ((_a = tagProps === null || tagProps === void 0 ? void 0 : tagProps.removeProps) === null || _a === void 0 ? void 0 : _a.onClick) && ((_b = tagProps === null || tagProps === void 0 ? void 0 : tagProps.removeProps) === null || _b === void 0 ? void 0 : _b.onClick(e));
1098
+ },
1099
+ disabled: disabled,
1100
+ };
1101
+ })
1102
+ : [], postFix: searchInput, width: "100%" })) : (jsxs(Fragment, { children: [tags &&
1103
+ tags.slice(0, maxSelectedDisplayCount).map(({ props: tagProps }) => {
1104
+ var _a, _b;
1105
+ return (jsx(Tag, { className: "inline-flex shrink-0", color: disabled ? "unknown" : "primary", dataTestId: tagProps.children ? `${(_a = tagProps.children) === null || _a === void 0 ? void 0 : _a.toString()}-tag` : undefined, onClose: e => {
1106
+ var _a, _b;
1107
+ e.stopPropagation();
1108
+ refMenuIsEnabled.current = false;
1109
+ ((_a = tagProps === null || tagProps === void 0 ? void 0 : tagProps.removeProps) === null || _a === void 0 ? void 0 : _a.onClick) && ((_b = tagProps === null || tagProps === void 0 ? void 0 : tagProps.removeProps) === null || _b === void 0 ? void 0 : _b.onClick(e));
1110
+ }, children: tagProps.children }, (_b = tagProps.children) === null || _b === void 0 ? void 0 : _b.toString()));
1111
+ }), tags && tags.length > maxSelectedDisplayCount && (jsxs(Tag, { color: "neutral", dataTestId: "counter-tag", children: ["+", tags.length - maxSelectedDisplayCount] })), searchInput] })) })));
1112
+ }
1113
+ return (jsx(components.ValueContainer, Object.assign({}, props, { isDisabled: props.selectProps.isDisabled, children: props.children })));
1114
+ }, LoadingIndicator: props => {
1115
+ return jsx(Spinner, { className: "mt-1.5 mr-1", size: "small" });
1116
+ }, DropdownIndicator: props => {
1117
+ const icon = props.selectProps.menuIsOpen ? (jsx(Icon, { name: "ChevronUp", size: "medium" })) : (jsx(Icon, { name: "ChevronDown", size: "medium" }));
1118
+ return props.selectProps.isLoading ? null : (jsx(components.DropdownIndicator, Object.assign({}, props, { children: jsx("div", { className: cvaSelectIcon(), children: dropdownIcon ? dropdownIcon : icon }) })));
1119
+ }, IndicatorSeparator: () => null, ClearIndicator: props => {
1120
+ if (disabled) {
1121
+ return null;
1122
+ }
1123
+ return (jsx(components.ClearIndicator, Object.assign({}, props, { children: jsx("div", { className: cvaSelectXIcon(), "data-testid": dataTestId && `${dataTestId}-XMarkIcon`, onClick: props.clearValue, children: jsx(Icon, { name: "XCircle", size: "medium", title: t("clearIndicator.icon.tooltip.clearAll") }) }) })));
1124
+ }, Control: props => {
1125
+ return jsx(components.Control, Object.assign({}, props, { className: props.isDisabled ? "bg-slate-100" : "" }));
1126
+ }, SingleValue: props => {
1127
+ return (jsx(components.SingleValue, Object.assign({}, props, { className: props.isDisabled ? "text-slate-700" : "", children: jsx("div", { "data-testid": dataTestId + "-singleValue", children: props.children }) })));
1128
+ }, Menu: props => {
1129
+ return (jsx(components.Menu, Object.assign({}, props, { className: cvaSelectMenuList({ menuIsOpen: props.selectProps.menuIsOpen }) })));
1130
+ }, MenuList: props => {
1131
+ return (jsx(components.MenuList, Object.assign({}, props, { innerProps: Object.assign(Object.assign({}, props.innerProps), { onScroll: e => {
1132
+ const listEl = e.currentTarget;
1133
+ if (listEl.scrollTop + listEl.clientHeight >= listEl.scrollHeight) {
1134
+ props.selectProps.onMenuScrollToBottom && props.selectProps.onMenuScrollToBottom(new TouchEvent(""));
1135
+ }
1136
+ } }), children: props.children })));
1137
+ }, Option: props => {
1138
+ const componentProps = {
1139
+ label: props.label,
1140
+ focused: props.isFocused,
1141
+ selected: props.isSelected,
1142
+ onClick: props.innerProps.onClick,
1143
+ };
1144
+ return (jsx(components.Option, Object.assign({}, props, { innerProps: Object.assign(Object.assign({}, props.innerProps), { role: "option", onClick: () => { } }), children: props.isMulti ? (jsx(MultiSelectMenuItem, Object.assign({}, componentProps, { dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled }))) : (jsx(SingleSelectMenuItem, Object.assign({}, componentProps, { dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled || props.isDisabled }))) })));
1145
+ } }, componentsProps);
1146
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1147
+ }, [componentsProps, disabled, maxSelectedDisplayCount]); // do not add dropdownIcon (it will cause issue with opening/closing list for selects with custom icon)
1148
+ return customComponents;
1320
1149
  };
1150
+
1321
1151
  /**
1322
- * @param phoneNumber - a phone number as a string
1323
- * @returns {string|number} the phone number with a plus sign in front of it
1324
- * @example getPhoneNumberWithPlus("123456789") // "+123456789"
1152
+ * @template IsMulti
1153
+ * @template Group
1154
+ * @param {React.RefObject<HTMLDivElement>} refContainer react ref to container element
1155
+ * @param {React.RefObject<HTMLDivElement>} refPrefix react ref to prefix element
1156
+ * @param {number | undefined} maxSelectedDisplayCount a number of max display count
1157
+ * @param {StylesConfig<Option, IsMulti, Group> | undefined} styles a optional object to override styles of react-select
1158
+ * @returns {StylesConfig<Option, boolean>} styles to override in select
1325
1159
  */
1326
- const getPhoneNumberWithPlus = (phoneNumber) => {
1327
- const stringPhoneNumber = phoneNumber.toString();
1328
- return checkIfPhoneNumberHasPlus(stringPhoneNumber) ? stringPhoneNumber : `+${stringPhoneNumber}`;
1160
+ const useCustomStyles = (refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled) => {
1161
+ const customStyles = React.useMemo(() => {
1162
+ return Object.assign({ control: base => {
1163
+ return Object.assign(Object.assign({}, base), { border: "0", boxShadow: "0", "&:hover": {
1164
+ border: "0",
1165
+ }, marginRight: "2px", backgroundColor: "" });
1166
+ }, singleValue: base => (Object.assign({}, base)), multiValue: base => (Object.assign({}, base)), multiValueLabel: base => (Object.assign({}, base)), indicatorsContainer: base => (Object.assign(Object.assign({}, base), (disabled && { display: "none" }))), indicatorSeparator: () => ({
1167
+ width: "0px",
1168
+ }), menu: base => {
1169
+ return Object.assign(Object.assign({}, base), { width: "100%", marginTop: "4px", marginBottom: "18px", transition: "all 1s ease-in-out" });
1170
+ }, input: base => (Object.assign(Object.assign({}, base), { marginLeft: "0px" })), placeholder: base => (Object.assign({}, base)), option: () => ({}), menuPortal: base => (Object.assign(Object.assign({}, base), { width: (refContainer === null || refContainer === void 0 ? void 0 : refContainer.current) ? `${refContainer.current.clientWidth}px` : base.width, transform: (refPrefix === null || refPrefix === void 0 ? void 0 : refPrefix.current) ? `translate(-${refPrefix.current.clientWidth + 2}px)` : "translate(-2px)", backgroundColor: "#ffffff", borderRadius: "var(--border-radius-lg)", zIndex: 20, borderColor: "rgb(var(--color-slate-300))", boxShadow: "var(--tw-ring-inset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)" })), menuList: base => {
1171
+ return Object.assign(Object.assign({}, base), { position: "relative", padding: "var(--spacing-1)", display: "grid", gap: "var(--spacing-1)", width: "100%", borderRadius: "0px", boxShadow: "none", paddingTop: "0px" });
1172
+ }, valueContainer: base => {
1173
+ return Object.assign(Object.assign({}, base), { flexWrap: maxSelectedDisplayCount !== undefined ? "wrap" : "nowrap", gap: "0.25rem" });
1174
+ }, container: base => (Object.assign(Object.assign({}, base), { border: "none", width: "calc(100% - 2px)", paddingLeft: "2px" })), dropdownIndicator: base => (Object.assign(Object.assign({}, base), { padding: "0px" })), clearIndicator: base => {
1175
+ return Object.assign(Object.assign({}, base), { padding: "0px" });
1176
+ } }, styles);
1177
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1178
+ }, [refContainer, refPrefix]);
1179
+ return { customStyles };
1329
1180
  };
1181
+
1330
1182
  /**
1331
- * Generates a flag emoji based on the given country code.
1183
+ * A hook used by selects to share the common code
1332
1184
  *
1333
- * @param {string} countryCode - The two-letter country code (ISO 3166-1 alpha-2).
1334
- * @returns {string} - The corresponding flag emoji for the given country code.
1335
- * @example getPhoneNumberWithPlus("DK") // "🇩🇰"
1185
+ * @param {SelectProps} props - The props for the Select component
1186
+ * @returns {IUseSelect} Select component
1336
1187
  */
1337
- const countryCodeToFlagEmoji = (countryCode) => {
1338
- let code = countryCode;
1339
- if (countryCode.startsWith("+")) {
1340
- code = getCountryAbbreviation(countryCode.substring(1));
1341
- }
1342
- else if (!isNaN(Number(countryCode))) {
1343
- code = getCountryAbbreviation(countryCode);
1344
- }
1345
- return isSupportedCountry(code.toUpperCase())
1346
- ? code.toUpperCase().replace(/./g, char => String.fromCodePoint(127397 + char.charCodeAt(0)))
1347
- : "";
1188
+ const useSelect = (_a) => {
1189
+ var _b;
1190
+ var { id, className, dataTestId = "select", prefix, async, dropdownIcon, maxMenuHeight = 200, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix = "", onMenuOpen, onMenuClose, maxSelectedDisplayCount = undefined, isClearable = false, isSearchable = true, onMenuScrollToBottom, styles, filterOption, onInputChange } = _a, props = __rest(_a, ["id", "className", "dataTestId", "prefix", "async", "dropdownIcon", "maxMenuHeight", "label", "hasError", "disabled", "isMulti", "components", "value", "options", "onChange", "isLoading", "classNamePrefix", "onMenuOpen", "onMenuClose", "maxSelectedDisplayCount", "isClearable", "isSearchable", "onMenuScrollToBottom", "styles", "filterOption", "onInputChange"]);
1191
+ const refContainer = React__default.useRef(null);
1192
+ const refPrefix = React__default.useRef(null);
1193
+ const { customStyles } = useCustomStyles(refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled);
1194
+ const [menuIsOpen, setMenuIsOpen] = React__default.useState((_b = props.menuIsOpen) !== null && _b !== void 0 ? _b : false);
1195
+ const refMenuIsEnabled = React__default.useRef(true);
1196
+ const customComponents = useCustomComponents(components, disabled || false, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon);
1197
+ const menuPlacement = "auto";
1198
+ const openMenuHandler = () => __awaiter(void 0, void 0, void 0, function* () {
1199
+ onMenuOpen && onMenuOpen();
1200
+ if (refMenuIsEnabled.current) {
1201
+ setMenuIsOpen(true);
1202
+ }
1203
+ else {
1204
+ refMenuIsEnabled.current = true;
1205
+ }
1206
+ });
1207
+ const closeMenuHandler = () => {
1208
+ setMenuIsOpen(false);
1209
+ onMenuClose && onMenuClose();
1210
+ };
1211
+ const orderedOptions = React__default.useMemo(() => {
1212
+ return disabled
1213
+ ? getOrderedOptions(options, value).map(option => {
1214
+ return Object.assign(Object.assign({}, option), { disabled: true });
1215
+ })
1216
+ : getOrderedOptions(options, value);
1217
+ }, [options, value, disabled]);
1218
+ return {
1219
+ refContainer,
1220
+ refPrefix,
1221
+ customStyles,
1222
+ menuIsOpen,
1223
+ customComponents,
1224
+ menuPlacement,
1225
+ openMenuHandler,
1226
+ closeMenuHandler,
1227
+ orderedOptions,
1228
+ };
1348
1229
  };
1230
+
1349
1231
  /**
1350
- * Retrieves the ISO 3166-1 alpha-2 country code associated with a given international calling code.
1232
+ * CreatableSelects are input components used to choose a value from a set.
1351
1233
  *
1352
- * @param {string} callCode - The international calling code for a country.
1353
- * @returns {string} The abbreviation for a country or an empty string if no matching country is found.
1354
- * @example getCountryAbbreviation("45") // "DK"
1355
- * @example getCountryAbbreviation("+45") // "DK"
1234
+ * @param {CreatableSelectProps} props - The props for the CreatableSelect component
1235
+ * @returns {JSX.Element} CreatableSelect component
1356
1236
  */
1357
- const getCountryAbbreviation = (callCode) => {
1358
- let code = callCode;
1359
- if (callCode.startsWith("+")) {
1360
- code = callCode.substring(1);
1361
- }
1362
- return getCountries().find(c => getCountryCallingCode(c) === code) || "";
1237
+ const CreatableSelect = (props) => {
1238
+ const { className } = props, propsNoClassName = __rest(props, ["className"]);
1239
+ const { id, dataTestId = "creatableSelect", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, value, options, onChange, isLoading, classNamePrefix = dataTestId !== null && dataTestId !== void 0 ? dataTestId : "creatableSelect", onMenuScrollToBottom, filterOption, onInputChange, isSearchable, isClearable = false, readOnly, allowCreateWhileLoading, onCreateOption, } = propsNoClassName;
1240
+ const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
1241
+ const creatableSelectProps = {
1242
+ value,
1243
+ menuPlacement,
1244
+ maxMenuHeight,
1245
+ onChange,
1246
+ "aria-label": label,
1247
+ "data-testid": dataTestId,
1248
+ components: customComponents,
1249
+ styles: customStyles,
1250
+ tabSelectsValue: false,
1251
+ blurInputOnSelect: !isMulti,
1252
+ menuPortalTarget: props.menuPortalTarget || document.body,
1253
+ isSearchable: disabled || readOnly ? false : isSearchable,
1254
+ menuShouldBlockScroll: true,
1255
+ menuShouldScrollIntoView: true,
1256
+ openMenuOnFocus: true,
1257
+ menuIsOpen: !readOnly ? menuIsOpen : false,
1258
+ openMenuOnClick: true,
1259
+ closeMenuOnSelect: false,
1260
+ isMulti,
1261
+ classNamePrefix,
1262
+ isLoading,
1263
+ isClearable,
1264
+ id,
1265
+ onMenuScrollToBottom,
1266
+ onInputChange,
1267
+ allowCreateWhileLoading,
1268
+ onCreateOption,
1269
+ };
1270
+ return (jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: disabled || readOnly, className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined && (jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId && `${dataTestId}-prefix`, ref: refPrefix, children: prefix })), async ? (jsx(ReactAsyncCreatableSelect, Object.assign({}, propsNoClassName, creatableSelectProps, async, { onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler }))) : (jsx(ReactCreatableSelect, Object.assign({}, propsNoClassName, creatableSelectProps, { hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : options })))] }));
1363
1271
  };
1272
+ CreatableSelect.displayName = "CreatableSelect";
1364
1273
 
1365
1274
  /**
1366
- * A custom hook for managing phone number input state and validation.
1275
+ * Selects are input components used to choose a value from a set.
1367
1276
  *
1368
- * @property {Function} getPhoneNumber - A function for get formatted phone number with country code and plus sign
1277
+ * @param {SelectProps} props - The props for the Select component
1278
+ * @returns {JSX.Element} Select component
1369
1279
  */
1370
- const usePhoneInput = () => {
1371
- const getPhoneNumber = ({ country, phone }) => {
1372
- if (country) {
1373
- return getPhoneNumberWithPlus(`${country}${phone || ""}`);
1374
- }
1375
- return phone || "";
1376
- };
1377
- return {
1378
- getPhoneNumber,
1280
+ const Select = (props) => {
1281
+ const { className } = props, propsNoClassName = __rest(props, ["className"]);
1282
+ const { id, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, value, options, onChange, isLoading, classNamePrefix = dataTestId !== null && dataTestId !== void 0 ? dataTestId : "select", onMenuScrollToBottom, filterOption, onInputChange, isSearchable, isClearable = false, readOnly, openMenuOnClick = !disabled, openMenuOnFocus = !disabled, } = props;
1283
+ const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
1284
+ const selectProps = {
1285
+ value,
1286
+ menuPlacement,
1287
+ maxMenuHeight,
1288
+ onChange,
1289
+ "aria-label": label,
1290
+ "data-testid": dataTestId,
1291
+ components: customComponents,
1292
+ styles: customStyles,
1293
+ tabSelectsValue: false,
1294
+ blurInputOnSelect: !isMulti,
1295
+ menuPortalTarget: props.menuPortalTarget || document.body,
1296
+ isSearchable: disabled || readOnly ? false : isSearchable,
1297
+ menuShouldBlockScroll: true,
1298
+ menuShouldScrollIntoView: true,
1299
+ openMenuOnFocus,
1300
+ menuIsOpen: !readOnly ? menuIsOpen : false,
1301
+ openMenuOnClick,
1302
+ closeMenuOnSelect: false,
1303
+ isMulti,
1304
+ classNamePrefix,
1305
+ isLoading,
1306
+ isClearable,
1307
+ id,
1308
+ onMenuScrollToBottom,
1309
+ onInputChange,
1379
1310
  };
1311
+ return (jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: disabled || readOnly, className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined && (jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId && `${dataTestId}-prefix`, ref: refPrefix, children: prefix })), async ? (jsx(ReactAsyncSelect, Object.assign({}, propsNoClassName, selectProps, async, { onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler }))) : (jsx(ReactSelect, Object.assign({}, propsNoClassName, selectProps, { hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : options })))] }));
1380
1312
  };
1313
+ Select.displayName = "Select";
1381
1314
 
1382
1315
  const COUNTRY_CODES_NOT_SUPPORTED_BY_BACKEND = ["+53", "+98", "+211", "+247", "+249", "+383", "+850", "+963"];
1383
1316
  const ADDITIONAL_COUNTRY_CODES_SUPPORTED_BY_BACKEND = [
@@ -1491,7 +1424,7 @@ const CountryCodeSelect = ({ excludedCountries, countryCode, isInvalid, onChange
1491
1424
  const filteredCodes = countryCodes.filter(code => {
1492
1425
  return !(excludedCountries === null || excludedCountries === void 0 ? void 0 : excludedCountries.some(excludedCode => excludedCode.value === code.value));
1493
1426
  });
1494
- return (jsx(Select, { dataTestId: dataTestId, className: "w-36", "aria-invalid": isCountryCodeMissing, options: filteredCodes.map(code => code), value: filteredCodes.find(({ value }) => value === `+${countryCode}`), placeholder: placeholder, hasError: isCountryCodeMissing || isInvalid, maxMenuHeight: 200, onChange: onChange, disabled: disabled, readOnly: readOnly, onBlur: onBlur, closeMenuOnSelect: true, menuIsOpen: readOnly ? false : undefined, isClearable: isClearable }));
1427
+ return (jsx(Select, { "aria-invalid": isCountryCodeMissing, className: "w-36", closeMenuOnSelect: true, dataTestId: dataTestId, disabled: disabled, hasError: isCountryCodeMissing || isInvalid, isClearable: isClearable, maxMenuHeight: 200, menuIsOpen: readOnly ? false : undefined, onBlur: onBlur, onChange: onChange, options: filteredCodes.map(code => code), placeholder: placeholder, readOnly: readOnly, value: filteredCodes.find(({ value }) => value === `+${countryCode}`) }));
1495
1428
  };
1496
1429
 
1497
1430
  /**
@@ -1562,16 +1495,16 @@ const PhoneInput = forwardRef((_a, ref) => {
1562
1495
  // the event's type is inferred as Event, which doesn't have a target property, whereas ChangeEvent does.
1563
1496
  onChange && onChange(event);
1564
1497
  }, [phoneNumber, onChange]);
1565
- return (jsxs("div", { className: "grid-cols-min-fr grid gap-2", "data-testid": dataTestId && `${dataTestId}-container`, children: [jsx("input", { hidden: true, id: "phone-input", "data-testid": dataTestId, value: phoneNumber, ref: hiddenInputRef, onChange: onChange, "aria-invalid": isInvalid, readOnly: readOnly }), jsx(CountryCodeSelect, { dataTestId: dataTestId && `${dataTestId}-countryCodeSelect`, countryCode: code, onBlur: e => {
1498
+ return (jsxs("div", { className: "grid-cols-min-fr grid gap-2", "data-testid": dataTestId && `${dataTestId}-container`, children: [jsx("input", { "aria-invalid": isInvalid, "data-testid": dataTestId, hidden: true, id: "phone-input", onChange: onChange, readOnly: readOnly, ref: hiddenInputRef, value: phoneNumber }), jsx(CountryCodeSelect, { countryCode: code, dataTestId: dataTestId && `${dataTestId}-countryCodeSelect`, disabled: disabled, isClearable: isCountryCodeClearable, isInvalid: isInvalid, onBlur: e => {
1566
1499
  onBlurHandler();
1567
1500
  }, onChange: e => {
1568
1501
  var _a;
1569
1502
  onCodeChangeHandler((_a = e === null || e === void 0 ? void 0 : e.value) !== null && _a !== void 0 ? _a : "");
1570
- }, disabled: disabled, readOnly: readOnly, isInvalid: isInvalid, placeholder: placeholder, isClearable: isCountryCodeClearable }), jsx(BaseInput, Object.assign({ id: "phoneInput-number", dataTestId: dataTestId && `${dataTestId}-phoneNumberInput`, fieldSize: fieldSize, type: "tel", value: phone, disabled: disabled, readOnly: readOnly, isInvalid: isInvalid, onChange: e => {
1571
- onPhoneChangeHandler(e.target.value);
1572
- }, onBlur: () => {
1503
+ }, placeholder: placeholder, readOnly: readOnly }), jsx(BaseInput, Object.assign({ actions: !disableAction && (jsx(ActionButton, { dataTestId: dataTestId && `${dataTestId}-phoneIcon`, disabled: disabled || isInvalid, iconSize: fieldSize, type: "PHONE_NUMBER", value: phoneNumber })), dataTestId: dataTestId && `${dataTestId}-phoneNumberInput`, disabled: disabled, fieldSize: fieldSize, id: "phoneInput-number", isInvalid: isInvalid, onBlur: () => {
1573
1504
  onBlurHandler();
1574
- }, actions: !disableAction && (jsx(ActionButton, { disabled: disabled || isInvalid, value: phoneNumber, type: "PHONE_NUMBER", dataTestId: dataTestId && `${dataTestId}-phoneIcon`, iconSize: fieldSize })) }, rest))] }));
1505
+ }, onChange: e => {
1506
+ onPhoneChangeHandler(e.target.value);
1507
+ }, readOnly: readOnly, type: "tel", value: phone }, rest))] }));
1575
1508
  });
1576
1509
 
1577
1510
  /**
@@ -1649,7 +1582,7 @@ const PhoneField = forwardRef((_a, ref) => {
1649
1582
  validate(phoneNumberValue);
1650
1583
  onFieldsBlur && onFieldsBlur(Object.assign(Object.assign({}, phoneNumberValue), { isValid }));
1651
1584
  };
1652
- return (jsx(FormGroup, { htmlFor: htmlForId, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && (errorMessage || localError)) || helpText, helpAddon: helpAddon, disabled: rest.disabled, className: className, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsx(PhoneInput, Object.assign({ id: htmlForId, "aria-labelledby": htmlForId + "-label", value: value, defaultValue: defaultValue, ref: ref, isInvalid: renderAsInvalid, dataTestId: dataTestId, onChangeValue: onChangeValueHandler, onFieldsBlur: handleOnFieldBlur }, rest)) }));
1585
+ return (jsx(FormGroup, { className: className, dataTestId: dataTestId && `${dataTestId}-FormGroup`, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && (errorMessage || localError)) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(PhoneInput, Object.assign({ "aria-labelledby": htmlForId + "-label", dataTestId: dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, onChangeValue: onChangeValueHandler, onFieldsBlur: handleOnFieldBlur, ref: ref, value: value }, rest)) }));
1653
1586
  });
1654
1587
 
1655
1588
  const cvaRadioGroup = cvaMerge(["flex", "gap-2", "flex-col", "items-start"], {
@@ -1764,7 +1697,7 @@ const RadioGroupContext = React.createContext(null);
1764
1697
  * @returns {JSX.Element} RadioGroup component
1765
1698
  */
1766
1699
  const RadioGroup = ({ children, id, name, value, disabled, onChange, label, inline, className, dataTestId, isInvalid, }) => {
1767
- return (jsx(FormGroup, { label: label, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsx("div", { className: cvaRadioGroup({ layout: inline ? "inline" : null, className }), "data-testid": dataTestId, children: jsx(RadioGroupContext.Provider, { value: {
1700
+ return (jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, label: label, children: jsx("div", { className: cvaRadioGroup({ layout: inline ? "inline" : null, className }), "data-testid": dataTestId, children: jsx(RadioGroupContext.Provider, { value: {
1768
1701
  id,
1769
1702
  value,
1770
1703
  name: name || id,
@@ -1784,11 +1717,11 @@ RadioGroup.displayName = "RadioGroup";
1784
1717
  const RadioItem = ({ label, value, dataTestId, className, description, }) => {
1785
1718
  const groupCtx = React.useContext(RadioGroupContext);
1786
1719
  const isChecked = (groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.value) === value;
1787
- return (jsxs("label", { className: cvaRadioItemWrapper({ className }), htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id}-${value}`, "data-testid": dataTestId && `${dataTestId}-Wrapper`, children: [jsx("input", { id: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id}-${value}`, type: "radio", value: value, checked: isChecked, className: cvaRadioItem({
1720
+ return (jsxs("label", { className: cvaRadioItemWrapper({ className }), "data-testid": dataTestId && `${dataTestId}-Wrapper`, htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id}-${value}`, children: [jsx("input", { checked: isChecked, className: cvaRadioItem({
1788
1721
  checked: isChecked,
1789
1722
  disabled: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.disabled,
1790
1723
  invalid: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.isInvalid,
1791
- }), onChange: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.onChange, "data-testid": dataTestId }), jsxs("div", { className: cvaRadioItemLabelContainer(), children: [jsx(Label, { htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id}-${value}`, dataTestId: dataTestId && `${dataTestId}-Label`, disabled: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.disabled, isInvalid: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.isInvalid, children: label }), description && (jsx("label", { className: cvaRadioItemDescription({ disabled: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.disabled }), htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id}-${value}`, "data-testid": dataTestId && `${dataTestId}-Description`, children: description }))] })] }));
1724
+ }), "data-testid": dataTestId, id: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id}-${value}`, onChange: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.onChange, type: "radio", value: value }), jsxs("div", { className: cvaRadioItemLabelContainer(), children: [jsx(Label, { dataTestId: dataTestId && `${dataTestId}-Label`, disabled: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.disabled, htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id}-${value}`, isInvalid: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.isInvalid, children: label }), description && (jsx("label", { className: cvaRadioItemDescription({ disabled: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.disabled }), "data-testid": dataTestId && `${dataTestId}-Description`, htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id}-${value}`, children: description }))] })] }));
1792
1725
  };
1793
1726
 
1794
1727
  const cvaTimeRange = cvaMerge(["flex", "flex-1", "items-center", "gap-4", "border-transparent", "rounded-md"]);
@@ -1812,7 +1745,7 @@ const TimeRange = ({ id, className, dataTestId, children, range, onChange, disab
1812
1745
  setTimeRange(prev => (Object.assign(Object.assign({}, prev), { timeTo })));
1813
1746
  };
1814
1747
  const onRangeChange = () => onChange(timeRange);
1815
- return (jsxs("div", { id: id, className: cvaTimeRange({ className }), "data-testid": dataTestId, children: [jsx(BaseInput, { dataTestId: `${dataTestId}-from`, disabled: disabled, isInvalid: isInvalid, type: "time", onChange: (time) => onChangeFrom(time.currentTarget.value), onBlur: onRangeChange, value: (_a = timeRange === null || timeRange === void 0 ? void 0 : timeRange.timeFrom) !== null && _a !== void 0 ? _a : "" }), children !== null && children !== void 0 ? children : jsx("div", { "data-testid": `${dataTestId}-separator`, children: "-" }), jsx(BaseInput, { dataTestId: `${dataTestId}-to`, disabled: disabled, isInvalid: isInvalid, type: "time", onChange: (time) => onChangeTo(time.currentTarget.value), onBlur: onRangeChange, value: (_b = timeRange === null || timeRange === void 0 ? void 0 : timeRange.timeTo) !== null && _b !== void 0 ? _b : "" })] }));
1748
+ return (jsxs("div", { className: cvaTimeRange({ className }), "data-testid": dataTestId, id: id, children: [jsx(BaseInput, { dataTestId: `${dataTestId}-from`, disabled: disabled, isInvalid: isInvalid, onBlur: onRangeChange, onChange: (time) => onChangeFrom(time.currentTarget.value), type: "time", value: (_a = timeRange === null || timeRange === void 0 ? void 0 : timeRange.timeFrom) !== null && _a !== void 0 ? _a : "" }), children !== null && children !== void 0 ? children : jsx("div", { "data-testid": `${dataTestId}-separator`, children: "-" }), jsx(BaseInput, { dataTestId: `${dataTestId}-to`, disabled: disabled, isInvalid: isInvalid, onBlur: onRangeChange, onChange: (time) => onChangeTo(time.currentTarget.value), type: "time", value: (_b = timeRange === null || timeRange === void 0 ? void 0 : timeRange.timeTo) !== null && _b !== void 0 ? _b : "" })] }));
1816
1749
  };
1817
1750
 
1818
1751
  const cvaScheduleItem = cvaMerge(["grid", "pb-4", "gap-2", "grid-cols-[60px,200px,60px,2fr]"]);
@@ -1838,8 +1771,8 @@ const Schedule = ({ className, dataTestId, schedule, onChange, invalidKeys = []
1838
1771
  ? Object.assign(Object.assign({}, day), { range: { timeFrom: "", timeTo: "" }, isAllDayActive: isAllDayChecked }) : day);
1839
1772
  onChange(newSchedule);
1840
1773
  };
1841
- return (jsx("div", { "data-testid": dataTestId, className: className, children: schedule.map(({ label, range, isActive, key, checkboxLabel, isAllDayActive }, index) => {
1842
- return (jsxs("div", { className: cvaScheduleItem(), children: [jsx(Checkbox, { dataTestId: `${dataTestId}-${key}-checkbox`, checked: isActive, onChange: (event) => onActiveChange(Boolean(event.currentTarget.checked), index), label: checkboxLabel }), jsx(Text, { className: cvaScheduleItemText(), size: "medium", subtle: !isActive, children: label }), jsx(Checkbox, { dataTestId: `${dataTestId}-${key}-allday-checkbox`, disabled: !isActive, checked: isAllDayActive && isActive, onChange: (event) => onAllDayChange(Boolean(event.currentTarget.checked), index) }), jsx(TimeRange, { dataTestId: `${dataTestId}-${key}-range`, range: range, onChange: (newRange) => onRangeChange(newRange, index), disabled: !isActive || isAllDayActive, isInvalid: !!invalidKeys.find((invalidKey) => invalidKey === key) })] }, key));
1774
+ return (jsx("div", { className: className, "data-testid": dataTestId, children: schedule.map(({ label, range, isActive, key, checkboxLabel, isAllDayActive }, index) => {
1775
+ return (jsxs("div", { className: cvaScheduleItem(), children: [jsx(Checkbox, { checked: isActive, dataTestId: `${dataTestId}-${key}-checkbox`, label: checkboxLabel, onChange: (event) => onActiveChange(Boolean(event.currentTarget.checked), index) }), jsx(Text, { className: cvaScheduleItemText(), size: "medium", subtle: !isActive, children: label }), jsx(Checkbox, { checked: isAllDayActive && isActive, dataTestId: `${dataTestId}-${key}-allday-checkbox`, disabled: !isActive, onChange: (event) => onAllDayChange(Boolean(event.currentTarget.checked), index) }), jsx(TimeRange, { dataTestId: `${dataTestId}-${key}-range`, disabled: !isActive || isAllDayActive, isInvalid: !!invalidKeys.find((invalidKey) => invalidKey === key), onChange: (newRange) => onRangeChange(newRange, index), range: range })] }, key));
1843
1776
  }) }));
1844
1777
  };
1845
1778
 
@@ -1995,11 +1928,76 @@ const cvaSearch = cvaMerge([
1995
1928
  */
1996
1929
  const Search = forwardRef((_a, ref) => {
1997
1930
  var { className, placeholder = "Search", value, widenInputOnFocus, showBorderWhenNotInFocus = false, disabled, onKeyUp, onChange, onFocus, onBlur, name, onClear, dataTestId, autoComplete = "on" } = _a, rest = __rest(_a, ["className", "placeholder", "value", "widenInputOnFocus", "showBorderWhenNotInFocus", "disabled", "onKeyUp", "onChange", "onFocus", "onBlur", "name", "onClear", "dataTestId", "autoComplete"]);
1998
- return (jsx(TextInput, Object.assign({}, rest, { ref: ref, dataTestId: dataTestId, name: name, className: cvaSearch({ className, border: showBorderWhenNotInFocus, widenOnFocus: widenInputOnFocus }), placeholder: placeholder, prefix: jsx(Icon, { name: "MagnifyingGlass", size: "medium" }), suffix: onClear ? (jsx("button", { className: "flex", "data-testid": dataTestId && `${dataTestId}_suffix_component`, onClick: () => {
1931
+ return (jsx(TextInput, Object.assign({}, rest, { autoComplete: autoComplete, className: cvaSearch({ className, border: showBorderWhenNotInFocus, widenOnFocus: widenInputOnFocus }), dataTestId: dataTestId, disabled: disabled, name: name, onBlur: onBlur, onChange: onChange, onFocus: onFocus, onKeyUp: onKeyUp, placeholder: placeholder, prefix: jsx(Icon, { name: "MagnifyingGlass", size: "medium" }), ref: ref, suffix: onClear ? (jsx("button", { className: "flex", "data-testid": dataTestId && `${dataTestId}_suffix_component`, onClick: () => {
1999
1932
  onClear();
2000
- }, children: jsx(Icon, { name: "XMark", size: "small" }) })) : undefined, value: value, disabled: disabled, onChange: onChange, onKeyUp: onKeyUp, onFocus: onFocus, onBlur: onBlur, autoComplete: autoComplete })));
1933
+ }, children: jsx(Icon, { name: "XMark", size: "small" }) })) : undefined, value: value })));
1934
+ });
1935
+
1936
+ const FormFieldSelectAdapter = forwardRef((_a, ref) => {
1937
+ var { className, dataTestId, helpText, helpAddon, tip, label, disabled, isInvalid, errorMessage, name, onBlur, options, value, defaultValue, id, onChange, children } = _a, rest = __rest(_a, ["className", "dataTestId", "helpText", "helpAddon", "tip", "label", "disabled", "isInvalid", "errorMessage", "name", "onBlur", "options", "value", "defaultValue", "id", "onChange", "children"]);
1938
+ const [innerValue, setInnerValue] = useState(value || defaultValue);
1939
+ const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
1940
+ const htmlFor = useMemo(() => (id ? id : "selectField-" + v4()), [id]);
1941
+ const innerRef = useRef(null);
1942
+ useImperativeHandle(ref, () => innerRef.current, []);
1943
+ const handleChange = useCallback((newValue) => {
1944
+ setInnerValue(newValue === null || newValue === void 0 ? void 0 : newValue.value);
1945
+ }, []);
1946
+ useEffect(() => {
1947
+ var _a;
1948
+ if (!innerValue) {
1949
+ return;
1950
+ }
1951
+ const event = new Event("change");
1952
+ (_a = innerRef.current) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
1953
+ onChange === null || onChange === void 0 ? void 0 : onChange(event);
1954
+ }, [onChange, innerValue]);
1955
+ const selectedOption = options.find(option => { var _a; return option.value === ((_a = innerRef === null || innerRef === void 0 ? void 0 : innerRef.current) === null || _a === void 0 ? void 0 : _a.value); });
1956
+ const defaultSelectedOption = options.find(option => option.value === defaultValue);
1957
+ return (jsxs(FormGroup, { isInvalid: renderAsInvalid,
1958
+ htmlFor,
1959
+ className,
1960
+ dataTestId,
1961
+ helpText,
1962
+ helpAddon,
1963
+ tip,
1964
+ label,
1965
+ disabled, children: [jsx("select", { onChange, ref: innerRef, name, value: innerValue, hidden: true, children: options.map(option => {
1966
+ return (jsx("option", { value: option.value, children: option.label }, option.value));
1967
+ }) }), children(Object.assign({ id, isDisabled: disabled, onBlur,
1968
+ options, onChange: handleChange, value: selectedOption, defaultValue: defaultSelectedOption }, rest))] }));
2001
1969
  });
2002
1970
 
1971
+ /**
1972
+ * The CreatableSelectField component is a CreatableSelect component wrapped in the FromGroup component.
1973
+ *
1974
+ * This means that it can easily be added to any form alongside other Field components.
1975
+ *
1976
+ * This is done to make the field compatible with the React-hook-form library.
1977
+ *
1978
+ * @param {SelectFieldProps & CreatableSelectProps} props - The props for the CreatableSelectField component
1979
+ * @returns {JSX.Element} CreatableSelectField component
1980
+ */
1981
+ const CreatableSelectField = (_a) => {
1982
+ var { allowCreateWhileLoading, onCreateOption } = _a, props = __rest(_a, ["allowCreateWhileLoading", "onCreateOption"]);
1983
+ const creatableSelectOnlyProps = { allowCreateWhileLoading, onCreateOption };
1984
+ return (jsx(FormFieldSelectAdapter, Object.assign({}, props, { children: convertedProps => jsx(CreatableSelect, Object.assign({}, convertedProps, creatableSelectOnlyProps)) })));
1985
+ };
1986
+
1987
+ /**
1988
+ * The SelectField component is a Select component wrapped in the FromGroup component.
1989
+ *
1990
+ * This means that it can easily be added to any form alongside other Field components.
1991
+ *
1992
+ * This is done to make the field compatible with the React-hook-form library.
1993
+ *
1994
+ * @param {SelectFieldProps} props - The props for the SelectField component
1995
+ * @returns {JSX.Element} SelectField component
1996
+ */
1997
+ const SelectField = (props) => {
1998
+ return jsx(FormFieldSelectAdapter, Object.assign({}, props, { children: convertedProps => jsx(Select, Object.assign({}, convertedProps)) }));
1999
+ };
2000
+
2003
2001
  const cvaTextArea = cvaMerge([
2004
2002
  cvaInputBase(),
2005
2003
  "block",
@@ -2039,7 +2037,7 @@ const cvaTextArea = cvaMerge([
2039
2037
  */
2040
2038
  const TextArea = React.forwardRef((_a, ref) => {
2041
2039
  var { id, name, value, rows, disabled, placeholder, readOnly, tabIndex, onChange, onFocus, onBlur, maxLength, resize = "vertical", defaultValue, required, dataTestId, isInvalid, className } = _a, rest = __rest(_a, ["id", "name", "value", "rows", "disabled", "placeholder", "readOnly", "tabIndex", "onChange", "onFocus", "onBlur", "maxLength", "resize", "defaultValue", "required", "dataTestId", "isInvalid", "className"]);
2042
- return (jsx("textarea", Object.assign({ id: id, name: name, value: value, rows: rows, disabled: disabled, placeholder: placeholder, readOnly: readOnly, tabIndex: tabIndex, onFocus: onFocus, onBlur: onBlur, maxLength: maxLength, ref: ref, defaultValue: defaultValue, required: required, className: cvaTextArea({ className, resize, invalid: isInvalid, disabled }) }, rest, { onChange: onChange, "data-testid": dataTestId })));
2040
+ return (jsx("textarea", Object.assign({ className: cvaTextArea({ className, resize, invalid: isInvalid, disabled }), defaultValue: defaultValue, disabled: disabled, id: id, maxLength: maxLength, name: name, onBlur: onBlur, onFocus: onFocus, placeholder: placeholder, readOnly: readOnly, ref: ref, required: required, rows: rows, tabIndex: tabIndex, value: value }, rest, { "data-testid": dataTestId, onChange: onChange })));
2043
2041
  });
2044
2042
 
2045
2043
  /**
@@ -2064,8 +2062,8 @@ const TextAreaField = React.forwardRef((_a, ref) => {
2064
2062
  onChange(event);
2065
2063
  }
2066
2064
  }, [onChange]);
2067
- return (jsx(FormGroup, { htmlFor: htmlForId, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: errorMessage || helpText, helpAddon: helpAddon ||
2068
- (maxLength !== null && maxLength !== undefined && (jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength }))), className: `${className} grid grid-rows-[auto_1fr_auto]`, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsx(TextArea, Object.assign({ id: htmlForId, "aria-labelledby": htmlForId + "-label", ref: ref, maxLength: maxLength, value: value, isInvalid: renderAsInvalid }, rest, { className: "h-auto", onChange: handleChange, dataTestId: dataTestId })) }));
2065
+ return (jsx(FormGroup, { className: `${className} grid grid-rows-[auto_1fr_auto]`, dataTestId: dataTestId && `${dataTestId}-FormGroup`, helpAddon: helpAddon ||
2066
+ (maxLength !== null && maxLength !== undefined && (jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength }))), helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(TextArea, Object.assign({ "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, ref: ref, value: value }, rest, { className: "h-auto", dataTestId: dataTestId, onChange: handleChange })) }));
2069
2067
  });
2070
2068
 
2071
2069
  /**
@@ -2086,8 +2084,8 @@ const TextField = React.forwardRef((_a, ref) => {
2086
2084
  onChange(event);
2087
2085
  }
2088
2086
  }, [onChange]);
2089
- return (jsx(FormGroup, { htmlFor: htmlFor, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && errorMessage) || helpText, helpAddon: helpAddon ||
2090
- (maxLength !== null && maxLength !== undefined && (jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength }))), dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsx(TextInput, Object.assign({ disabled: rest.readOnly, id: htmlFor, "aria-labelledby": htmlFor + "-label", ref: ref, maxLength: maxLength, value: value, isInvalid: renderAsInvalid }, rest, { className: className, onChange: handleChange, dataTestId: dataTestId })) }));
2087
+ return (jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, helpAddon: helpAddon ||
2088
+ (maxLength !== null && maxLength !== undefined && (jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength }))), helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(TextInput, Object.assign({ "aria-labelledby": htmlFor + "-label", disabled: rest.readOnly, id: htmlFor, isInvalid: renderAsInvalid, maxLength: maxLength, ref: ref, value: value }, rest, { className: className, dataTestId: dataTestId, onChange: handleChange })) }));
2091
2089
  });
2092
2090
 
2093
2091
  /**
@@ -2100,7 +2098,7 @@ const TimeRangeField = (_a) => {
2100
2098
  var { className, dataTestId, onChange, isInvalid, errorMessage, label, tip, disabled, children, helpText, id } = _a, rest = __rest(_a, ["className", "dataTestId", "onChange", "isInvalid", "errorMessage", "label", "tip", "disabled", "children", "helpText", "id"]);
2101
2099
  const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
2102
2100
  const htmlFor = id ? id : "timeRangeField-" + v4();
2103
- return (jsx(FormGroup, { htmlFor: htmlFor, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && errorMessage) || helpText, dataTestId: dataTestId && `${dataTestId}-FormGroup`, disabled: disabled, children: jsx(TimeRange, Object.assign({ className: className, onChange: onChange, disabled: disabled, dataTestId: dataTestId, isInvalid: renderAsInvalid }, rest, { children: children })) }));
2101
+ return (jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, disabled: disabled, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(TimeRange, Object.assign({ className: className, dataTestId: dataTestId, disabled: disabled, isInvalid: renderAsInvalid, onChange: onChange }, rest, { children: children })) }));
2104
2102
  };
2105
2103
 
2106
2104
  const cvaToggleWrapper = cvaMerge(["flex", "gap-2", "items-center"]);
@@ -2175,10 +2173,10 @@ const Toggle = React.forwardRef(({ toggled = false, onChange, onClick, disabled,
2175
2173
  const showLabelContainer = Boolean(name || description);
2176
2174
  const showDescription = Boolean(description);
2177
2175
  const getTestId = (suffix) => `${dataTestId}-${suffix}`;
2178
- return (jsx("span", { className: className, onClick: onClick, "data-testid": getTestId("outer-wrapper"), children: jsxs("label", { className: cvaToggleWrapper(), htmlFor: id, "data-testid": getTestId("wrapper"), children: [jsx("span", { className: cvaToggleTrack({ disabled, size, toggled }), "data-testid": getTestId("track"), children: jsx("span", { className: cvaToggleThumb({ toggled }), "data-testid": getTestId("thumb") }) }), showLabelContainer && (jsxs("span", { className: cvaToggleLabelContainer(), "data-testid": getTestId("label-container"), children: [jsx(Label, { className: cvaToggleLabel(), "data-testid": getTestId("label"), disabled: disabled, children: name }), showDescription && (jsx("span", { className: cvaToggleDescription({ disabled }), "data-testid": getTestId("description"), children: description }))] })), jsx("input", { name: name, className: cvaToggleInput(), type: "checkbox", checked: toggled, disabled: disabled, onChange: e => {
2176
+ return (jsx("span", { className: className, "data-testid": getTestId("outer-wrapper"), onClick: onClick, children: jsxs("label", { className: cvaToggleWrapper(), "data-testid": getTestId("wrapper"), htmlFor: id, children: [jsx("span", { className: cvaToggleTrack({ disabled, size, toggled }), "data-testid": getTestId("track"), children: jsx("span", { className: cvaToggleThumb({ toggled }), "data-testid": getTestId("thumb") }) }), showLabelContainer && (jsxs("span", { className: cvaToggleLabelContainer(), "data-testid": getTestId("label-container"), children: [jsx(Label, { className: cvaToggleLabel(), "data-testid": getTestId("label"), disabled: disabled, children: name }), showDescription && (jsx("span", { className: cvaToggleDescription({ disabled }), "data-testid": getTestId("description"), children: description }))] })), jsx("input", { "aria-checked": toggled, checked: toggled, className: cvaToggleInput(), "data-testid": getTestId("input"), disabled: disabled, id: id, name: name, onBlur: onBlur, onChange: e => {
2179
2177
  e.stopPropagation();
2180
2178
  onChange(!toggled, e);
2181
- }, id: id, "aria-checked": toggled, tabIndex: tabIndex, required: required, ref: ref, "data-testid": getTestId("input"), onBlur: onBlur })] }) }));
2179
+ }, ref: ref, required: required, tabIndex: tabIndex, type: "checkbox" })] }) }));
2182
2180
  });
2183
2181
 
2184
2182
  const cvaUploadInputField = cvaMerge([
@@ -2200,14 +2198,13 @@ const cvaUploadInputAddonBefore = cvaMerge(["block", "truncate", "w-28", "pt-2"]
2200
2198
  */
2201
2199
  const UploadInput = forwardRef((_a, ref) => {
2202
2200
  var { disabled, acceptedTypes, nonInteractive, uploadLabel, multipleFiles } = _a, rest = __rest(_a, ["disabled", "acceptedTypes", "nonInteractive", "uploadLabel", "multipleFiles"]);
2203
- return (jsx("label", { className: "tu-upload-input", children: jsx(BaseInput, Object.assign({ inputClassName: cvaUploadInputField(), addonBefore: uploadLabel, addonBeforeClassName: cvaUploadInputAddonBefore(), ref: ref, disabled: disabled, accept: acceptedTypes, multiple: multipleFiles, type: "file", nonInteractive: nonInteractive,
2204
- // onClick used to work with nonInteractive option
2205
- onClick: event => {
2201
+ return (jsx("label", { className: "tu-upload-input", children: jsx(BaseInput, Object.assign({ accept: acceptedTypes, addonBefore: uploadLabel, addonBeforeClassName: cvaUploadInputAddonBefore(), disabled: disabled, inputClassName: cvaUploadInputField(), multiple: multipleFiles, nonInteractive: nonInteractive, onClick: event => {
2202
+ // onClick used to work with nonInteractive option
2206
2203
  if (nonInteractive) {
2207
2204
  event.preventDefault();
2208
2205
  event.stopPropagation();
2209
2206
  }
2210
- } }, rest)) }));
2207
+ }, ref: ref, type: "file" }, rest)) }));
2211
2208
  });
2212
2209
 
2213
2210
  /**
@@ -2217,7 +2214,7 @@ const UploadField = forwardRef((_a, ref) => {
2217
2214
  var { label, id, tip, helpText, errorMessage, isInvalid, className, value, dataTestId } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "errorMessage", "isInvalid", "className", "value", "dataTestId"]);
2218
2215
  const renderAsInvalid = isInvalid || Boolean(errorMessage);
2219
2216
  const htmlForId = id ? id : "uploadField-" + v4();
2220
- return (jsx(FormGroup, { htmlFor: htmlForId, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: errorMessage || helpText, dataTestId: `${dataTestId}-FormGroup`, children: jsx(UploadInput, Object.assign({ ref: ref, id: htmlForId, "aria-labelledby": htmlForId + "-label", isInvalid: renderAsInvalid }, rest, { className: className, dataTestId: dataTestId })) }));
2217
+ return (jsx(FormGroup, { dataTestId: `${dataTestId}-FormGroup`, helpText: errorMessage || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(UploadInput, Object.assign({ "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, ref: ref }, rest, { className: className, dataTestId: dataTestId })) }));
2221
2218
  });
2222
2219
 
2223
2220
  /**
@@ -2244,7 +2241,7 @@ const UrlInput = forwardRef((_a, ref) => {
2244
2241
  var { dataTestId, isInvalid, disabled = false, fieldSize = "medium", disableAction = false, value, defaultValue } = _a, rest = __rest(_a, ["dataTestId", "isInvalid", "disabled", "fieldSize", "disableAction", "value", "defaultValue"]);
2245
2242
  const [url, setUrl] = useState((value === null || value === void 0 ? void 0 : value.toString()) || (defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue.toString()));
2246
2243
  const renderAsInvalid = (url && typeof url === "string" && !validateUrlAddress(url)) || isInvalid;
2247
- return (jsx(BaseInput, Object.assign({ id: "url-input", dataTestId: dataTestId && `${dataTestId}-url-input`, ref: ref, type: "url", placeholder: rest.placeholder || "https://www.example.com", onChange: e => setUrl(e.target.value), isInvalid: renderAsInvalid, value: url, disabled: disabled }, rest, { actions: !disableAction && (jsx(ActionButton, { disabled: renderAsInvalid || disabled, value: url, type: "WEB_ADDRESS", dataTestId: (dataTestId && `${dataTestId}-url-input-Icon`) || "url-input-action-icon", iconSize: fieldSize })) })));
2244
+ return (jsx(BaseInput, Object.assign({ dataTestId: dataTestId && `${dataTestId}-url-input`, disabled: disabled, id: "url-input", isInvalid: renderAsInvalid, onChange: e => setUrl(e.target.value), placeholder: rest.placeholder || "https://www.example.com", ref: ref, type: "url", value: url }, rest, { actions: !disableAction && (jsx(ActionButton, { dataTestId: (dataTestId && `${dataTestId}-url-input-Icon`) || "url-input-action-icon", disabled: renderAsInvalid || disabled, iconSize: fieldSize, type: "WEB_ADDRESS", value: url })) })));
2248
2245
  });
2249
2246
 
2250
2247
  /**
@@ -2260,7 +2257,7 @@ const UrlField = forwardRef((_a, ref) => {
2260
2257
  return typeof inputValue === "string";
2261
2258
  }
2262
2259
  const renderAsInvalid = !!errorMessage || (value && isString(value) && !validateUrlAddress(value)) || isInvalid;
2263
- return (jsx(FormGroup, { htmlFor: htmlForId, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: renderAsInvalid ? errorMessage : helpText, helpAddon: helpAddon, disabled: rest.disabled, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsx(UrlInput, Object.assign({ id: htmlForId, "aria-labelledby": htmlForId + "-label", ref: ref, value: value || defaultValue, isInvalid: renderAsInvalid, disabled: rest.disabled }, rest, { className: className, dataTestId: dataTestId })) }));
2260
+ return (jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, disabled: rest.disabled, helpAddon: helpAddon, helpText: renderAsInvalid ? errorMessage : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(UrlInput, Object.assign({ "aria-labelledby": htmlForId + "-label", disabled: rest.disabled, id: htmlForId, isInvalid: renderAsInvalid, ref: ref, value: value || defaultValue }, rest, { className: className, dataTestId: dataTestId })) }));
2264
2261
  });
2265
2262
 
2266
2263
  /*
@@ -2272,4 +2269,4 @@ const UrlField = forwardRef((_a, ref) => {
2272
2269
  */
2273
2270
  setupLibraryTranslations();
2274
2271
 
2275
- export { ActionButton, BaseInput, Checkbox, CreatableSelect, DateField, DateInput, DropZone, EMAIL_REGEX, EmailField, EmailInput, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PasswordField, PasswordInput, PhoneField, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SelectField, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField, Toggle, UploadField, UploadInput, UrlField, UrlInput, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaInput, cvaInputAddon, cvaInputAddonAfter, cvaInputAddonBefore, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputField, cvaInputPrefix, cvaInputSuffix, cvaSelect, cvaSelectCounter, cvaSelectDynamicTagContainer, cvaSelectIcon, cvaSelectMenu, cvaSelectMenuList, cvaSelectPrefix, cvaSelectXIcon, getCountryAbbreviation, getOrderedOptions, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isMultiValue, parseSchedule, serializeSchedule, useCustomComponents, usePhoneInput, validateEmailAddress, validatePhoneNumber, weekDay };
2272
+ export { ActionButton, BaseInput, Checkbox, CreatableSelect, CreatableSelectField, DateField, DateInput, DropZone, EMAIL_REGEX, EmailField, EmailInput, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PasswordField, PasswordInput, PhoneField, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SelectField, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField, Toggle, UploadField, UploadInput, UrlField, UrlInput, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaInput, cvaInputAddon, cvaInputAddonAfter, cvaInputAddonBefore, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputField, cvaInputPrefix, cvaInputSuffix, cvaSelect, cvaSelectCounter, cvaSelectDynamicTagContainer, cvaSelectIcon, cvaSelectMenu, cvaSelectMenuList, cvaSelectPrefix, cvaSelectXIcon, getCountryAbbreviation, getOrderedOptions, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isMultiValue, parseSchedule, serializeSchedule, useCustomComponents, usePhoneInput, validateEmailAddress, validatePhoneNumber, weekDay };