@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.cjs.js +937 -939
- package/index.esm.js +937 -940
- package/package.json +1 -1
- package/src/components/Select/CreatableSelect.d.ts +32 -31
- package/src/components/Select/Select.d.ts +2 -2
- package/src/components/Select/useSelect.d.ts +2 -2
- package/src/components/SelectField/CreatableSelectField.d.ts +14 -0
- package/src/components/SelectField/FormFieldSelectAdapter.d.ts +44 -0
- package/src/components/SelectField/SelectField.d.ts +13 -0
- package/src/index.d.ts +2 -1
- package/src/SelectField/SelectField.d.ts +0 -50
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, {
|
|
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
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
"
|
|
115
|
-
"
|
|
116
|
-
"
|
|
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:
|
|
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-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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: "
|
|
243
|
+
true: ["text-slate-500"],
|
|
149
244
|
false: "",
|
|
150
245
|
},
|
|
151
246
|
},
|
|
152
247
|
});
|
|
153
|
-
const
|
|
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
|
-
|
|
157
|
-
true: "text-
|
|
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
|
-
*
|
|
166
|
-
*
|
|
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
|
-
*
|
|
169
|
-
*
|
|
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
|
|
172
|
-
|
|
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
|
|
176
|
-
"
|
|
177
|
-
"
|
|
178
|
-
"
|
|
179
|
-
"
|
|
180
|
-
"
|
|
181
|
-
"
|
|
182
|
-
"
|
|
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: "
|
|
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: "
|
|
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
|
|
309
|
+
* The CheckIcon component is used by the checkbox to display the checked state.
|
|
230
310
|
*
|
|
231
|
-
* @param {
|
|
232
|
-
* @returns {JSX.Element}
|
|
311
|
+
* @param {CheckIconProps} props - The props for the CheckIcon component
|
|
312
|
+
* @returns {JSX.Element} CheckIcon component
|
|
233
313
|
*/
|
|
234
|
-
const
|
|
235
|
-
return (
|
|
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", {
|
|
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,
|
|
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", {
|
|
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
|
|
496
|
+
* A wrapper around BaseInput with a pop-up day picker.
|
|
475
497
|
*
|
|
476
|
-
*
|
|
477
|
-
* @returns {JSX.Element} SingleSelectMenuItem
|
|
498
|
+
* NOTE: If shown with a label, please use the `DateField` component instead.
|
|
478
499
|
*/
|
|
479
|
-
const
|
|
480
|
-
|
|
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
|
-
*
|
|
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 {
|
|
486
|
-
* @returns {JSX.Element}
|
|
512
|
+
* @param {LabelProps} props - The props for the Label component
|
|
513
|
+
* @returns {JSX.Element} Label component
|
|
487
514
|
*/
|
|
488
|
-
const
|
|
489
|
-
return (jsx(
|
|
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
|
-
*
|
|
499
|
-
*
|
|
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 {
|
|
502
|
-
* @returns {JSX.Element}
|
|
542
|
+
* @param {FormGroupProps} props - The props for the FormGroup component
|
|
543
|
+
* @returns {JSX.Element} FormGroup component
|
|
503
544
|
*/
|
|
504
|
-
const
|
|
505
|
-
|
|
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
|
-
*
|
|
550
|
+
* The date field component is used for entering date values.
|
|
516
551
|
*
|
|
517
|
-
*
|
|
518
|
-
*
|
|
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
|
|
521
|
-
|
|
522
|
-
const
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
},
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
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 (
|
|
554
|
-
|
|
619
|
+
else if (e.type === "dragleave") {
|
|
620
|
+
setDragActive(false);
|
|
555
621
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
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
|
-
|
|
564
|
-
|
|
565
|
-
|
|
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
|
-
|
|
568
|
-
})
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
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
|
-
|
|
577
|
-
|
|
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,
|
|
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, {
|
|
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, {
|
|
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
|
|
1276
|
-
const
|
|
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
|
-
*
|
|
913
|
+
* @param {MultiValue<Option> | SingleValue<Option>} arg option to check type
|
|
914
|
+
* @returns {arg is MultiValue<Option> } is Multivalue
|
|
1280
915
|
*/
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
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
|
|
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
|
-
*
|
|
963
|
+
* @param {SelectMenuItemProps} props - The props for the SingleSelectMenuItem
|
|
964
|
+
* @returns {JSX.Element} SingleSelectMenuItem
|
|
1291
965
|
*/
|
|
1292
|
-
const
|
|
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
|
-
*
|
|
985
|
+
* Extended Tag component with information about its own width.
|
|
986
|
+
* Used in the select component.
|
|
1296
987
|
*
|
|
1297
|
-
*
|
|
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
|
-
*
|
|
1004
|
+
* @param {TagsContainerProps} props - The props for the TagContainer
|
|
1005
|
+
* @returns {JSX.Element} TagsContainer
|
|
1300
1006
|
*/
|
|
1301
|
-
const
|
|
1302
|
-
|
|
1303
|
-
const
|
|
1304
|
-
const
|
|
1305
|
-
const
|
|
1306
|
-
const
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
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
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
*
|
|
1316
|
-
*
|
|
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
|
|
1319
|
-
|
|
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
|
-
* @
|
|
1323
|
-
* @
|
|
1324
|
-
* @
|
|
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
|
|
1327
|
-
const
|
|
1328
|
-
|
|
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
|
-
*
|
|
1183
|
+
* A hook used by selects to share the common code
|
|
1332
1184
|
*
|
|
1333
|
-
* @param {
|
|
1334
|
-
* @returns {
|
|
1335
|
-
* @example getPhoneNumberWithPlus("DK") // "🇩🇰"
|
|
1185
|
+
* @param {SelectProps} props - The props for the Select component
|
|
1186
|
+
* @returns {IUseSelect} Select component
|
|
1336
1187
|
*/
|
|
1337
|
-
const
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
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
|
-
*
|
|
1232
|
+
* CreatableSelects are input components used to choose a value from a set.
|
|
1351
1233
|
*
|
|
1352
|
-
* @param {
|
|
1353
|
-
* @returns {
|
|
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
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
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
|
-
*
|
|
1275
|
+
* Selects are input components used to choose a value from a set.
|
|
1367
1276
|
*
|
|
1368
|
-
*
|
|
1277
|
+
* @param {SelectProps} props - The props for the Select component
|
|
1278
|
+
* @returns {JSX.Element} Select component
|
|
1369
1279
|
*/
|
|
1370
|
-
const
|
|
1371
|
-
const
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
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, {
|
|
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", {
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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, {
|
|
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, {
|
|
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 }),
|
|
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, "
|
|
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", {
|
|
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,
|
|
1842
|
-
return (jsxs("div", { className: cvaScheduleItem(), children: [jsx(Checkbox, { dataTestId: `${dataTestId}-${key}-checkbox`,
|
|
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, {
|
|
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
|
|
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({
|
|
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, {
|
|
2068
|
-
(maxLength !== null && maxLength !== undefined && (jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength }))),
|
|
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, {
|
|
2090
|
-
(maxLength !== null && maxLength !== undefined && (jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength }))),
|
|
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, {
|
|
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,
|
|
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
|
-
},
|
|
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({
|
|
2204
|
-
|
|
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, {
|
|
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({
|
|
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, {
|
|
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 };
|