@trackunit/react-form-components 0.0.305 → 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 +918 -919
- package/index.esm.js +918 -920
- 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.cjs.js
CHANGED
|
@@ -4,17 +4,17 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var i18nLibraryTranslation = require('@trackunit/i18n-library-translation');
|
|
7
|
+
var reactComponents = require('@trackunit/react-components');
|
|
7
8
|
var React = require('react');
|
|
9
|
+
var reactUse = require('react-use');
|
|
8
10
|
var uuid = require('uuid');
|
|
9
|
-
var reactComponents = require('@trackunit/react-components');
|
|
10
11
|
var cssClassVarianceUtilities = require('@trackunit/css-class-variance-utilities');
|
|
12
|
+
var dateFns = require('date-fns');
|
|
13
|
+
var parsePhoneNumberFromString = require('libphonenumber-js');
|
|
11
14
|
var ReactSelect = require('react-select');
|
|
12
15
|
var ReactAsyncCreatableSelect = require('react-select/async-creatable');
|
|
13
16
|
var ReactCreatableSelect = require('react-select/creatable');
|
|
14
17
|
var ReactAsyncSelect = require('react-select/async');
|
|
15
|
-
var reactUse = require('react-use');
|
|
16
|
-
var dateFns = require('date-fns');
|
|
17
|
-
var parsePhoneNumberFromString = require('libphonenumber-js');
|
|
18
18
|
|
|
19
19
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
20
20
|
|
|
@@ -38,11 +38,11 @@ function _interopNamespace(e) {
|
|
|
38
38
|
|
|
39
39
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
40
40
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
41
|
+
var parsePhoneNumberFromString__default = /*#__PURE__*/_interopDefaultLegacy(parsePhoneNumberFromString);
|
|
41
42
|
var ReactSelect__default = /*#__PURE__*/_interopDefaultLegacy(ReactSelect);
|
|
42
43
|
var ReactAsyncCreatableSelect__default = /*#__PURE__*/_interopDefaultLegacy(ReactAsyncCreatableSelect);
|
|
43
44
|
var ReactCreatableSelect__default = /*#__PURE__*/_interopDefaultLegacy(ReactCreatableSelect);
|
|
44
45
|
var ReactAsyncSelect__default = /*#__PURE__*/_interopDefaultLegacy(ReactAsyncSelect);
|
|
45
|
-
var parsePhoneNumberFromString__default = /*#__PURE__*/_interopDefaultLegacy(parsePhoneNumberFromString);
|
|
46
46
|
|
|
47
47
|
var defaultTranslations = {
|
|
48
48
|
"clearIndicator.icon.tooltip.clearAll": "Clear all",
|
|
@@ -99,6 +99,65 @@ const setupLibraryTranslations = () => {
|
|
|
99
99
|
i18nLibraryTranslation.registerTranslations(translations);
|
|
100
100
|
};
|
|
101
101
|
|
|
102
|
+
const cvaActionButton = cssClassVarianceUtilities.cvaMerge(["drop-shadow-none", "rounded-md"], {
|
|
103
|
+
variants: {
|
|
104
|
+
size: {
|
|
105
|
+
small: ["w-6", "h-6"],
|
|
106
|
+
medium: ["w-8", "h-8"],
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
defaultVariants: {
|
|
110
|
+
size: "medium",
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
const cvaActionContainer = cssClassVarianceUtilities.cvaMerge(["flex", "items-center", "m-1"]);
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* The ActionButton component is a wrapper over IconButton to perform an action when the onClick event is triggered.
|
|
117
|
+
*
|
|
118
|
+
* @param {ActionButtonProps} props - The props for the ActionButton component
|
|
119
|
+
* @returns {JSX.Element} ActionButton component
|
|
120
|
+
*/
|
|
121
|
+
const ActionButton = ({ type, value, dataTestId, iconSize, disabled, key, className }) => {
|
|
122
|
+
const [, copyToClipboard] = reactUse.useCopyToClipboard();
|
|
123
|
+
const elementKey = React.useMemo(() => key !== null && key !== void 0 ? key : `ActionButton-${uuid.v4()}`, [key]);
|
|
124
|
+
const getIconName = () => {
|
|
125
|
+
switch (type) {
|
|
126
|
+
case "PHONE_NUMBER":
|
|
127
|
+
return "PhoneArrowUpRight";
|
|
128
|
+
case "WEB_ADDRESS":
|
|
129
|
+
return "ArrowTopRightOnSquare";
|
|
130
|
+
case "EMAIL":
|
|
131
|
+
return "Envelope";
|
|
132
|
+
case "COPY":
|
|
133
|
+
default:
|
|
134
|
+
return "ClipboardDocument";
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const ButtonAction = () => {
|
|
138
|
+
var _a, _b;
|
|
139
|
+
switch (type) {
|
|
140
|
+
case "EMAIL":
|
|
141
|
+
return window.open(`mailto:${value}`);
|
|
142
|
+
case "WEB_ADDRESS":
|
|
143
|
+
if (value) {
|
|
144
|
+
return window.open(value, "_blank", "noopener,noreferrer");
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
case "PHONE_NUMBER":
|
|
148
|
+
return window.open(`tel:${value}`);
|
|
149
|
+
case "COPY":
|
|
150
|
+
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 : "");
|
|
151
|
+
default:
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
if (ButtonAction === null) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
return (jsxRuntime.jsx("div", { className: cvaActionContainer({ className }), children: jsxRuntime.jsx(reactComponents.IconButton, { className: cvaActionButton({ size: iconSize }), dataTestId: dataTestId || "testIconButtonId", disabled: disabled, icon: jsxRuntime.jsx(reactComponents.Icon, { name: getIconName(), size: "small" }), onClick: ButtonAction, size: "small", variant: "secondary" }) }, elementKey));
|
|
159
|
+
};
|
|
160
|
+
|
|
102
161
|
/******************************************************************************
|
|
103
162
|
Copyright (c) Microsoft Corporation.
|
|
104
163
|
|
|
@@ -136,95 +195,137 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
136
195
|
});
|
|
137
196
|
}
|
|
138
197
|
|
|
139
|
-
const
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
"
|
|
145
|
-
"
|
|
146
|
-
"
|
|
147
|
-
|
|
198
|
+
const cvaInputBase = cssClassVarianceUtilities.cvaMerge([
|
|
199
|
+
"component-baseInput-shadow",
|
|
200
|
+
"component-baseInput-border",
|
|
201
|
+
"component-baseInput-background",
|
|
202
|
+
"border-slate-300",
|
|
203
|
+
"focus-within:ring-2",
|
|
204
|
+
"focus-within:ring-inset",
|
|
205
|
+
"focus-within:ring-primary-500",
|
|
206
|
+
"focus-within:border-slate-400",
|
|
207
|
+
"hover:border-slate-400",
|
|
208
|
+
"hover:bg-slate-50",
|
|
209
|
+
"transition",
|
|
210
|
+
]);
|
|
211
|
+
const cvaInputBaseDisabled = cssClassVarianceUtilities.cvaMerge(["bg-slate-100", "hover:bg-slate-100", "hover:border-slate-300"]);
|
|
212
|
+
const cvaInputBaseInvalid = cssClassVarianceUtilities.cvaMerge(["border-danger-600", "focus-within:ring-danger-600"]);
|
|
213
|
+
const cvaInput = cssClassVarianceUtilities.cvaMerge(["relative", "flex", "h-10", cvaInputBase()], {
|
|
148
214
|
variants: {
|
|
215
|
+
size: {
|
|
216
|
+
small: ["h-8"],
|
|
217
|
+
medium: ["h-10"],
|
|
218
|
+
},
|
|
219
|
+
disabled: {
|
|
220
|
+
true: cvaInputBaseDisabled(),
|
|
221
|
+
false: "",
|
|
222
|
+
},
|
|
149
223
|
invalid: {
|
|
150
|
-
true:
|
|
224
|
+
true: cvaInputBaseInvalid(),
|
|
151
225
|
false: "",
|
|
152
226
|
},
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
const cvaInputField = cssClassVarianceUtilities.cvaMerge([
|
|
230
|
+
"w-full",
|
|
231
|
+
"px-3",
|
|
232
|
+
"border-0",
|
|
233
|
+
"bg-transparent",
|
|
234
|
+
"text-base",
|
|
235
|
+
"text-slate-900",
|
|
236
|
+
"placeholder-slate-400",
|
|
237
|
+
"focus-visible:outline-none",
|
|
238
|
+
], {
|
|
239
|
+
variants: {
|
|
240
|
+
size: {
|
|
241
|
+
small: ["py-1"],
|
|
242
|
+
medium: ["py-2"],
|
|
243
|
+
},
|
|
153
244
|
disabled: {
|
|
154
|
-
true: "text-slate-
|
|
245
|
+
true: ["text-slate-700"],
|
|
155
246
|
false: "",
|
|
156
247
|
},
|
|
157
248
|
},
|
|
158
|
-
defaultVariants: {
|
|
159
|
-
invalid: false,
|
|
160
|
-
disabled: false,
|
|
161
|
-
},
|
|
162
249
|
});
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
250
|
+
const cvaInputAddon = cssClassVarianceUtilities.cvaMerge([
|
|
251
|
+
"flex",
|
|
252
|
+
"justify-center",
|
|
253
|
+
"items-center",
|
|
254
|
+
"px-3",
|
|
255
|
+
"border-slate-300",
|
|
256
|
+
"text-slate-500",
|
|
257
|
+
"bg-slate-50",
|
|
258
|
+
]);
|
|
259
|
+
const cvaInputAddonBefore = cssClassVarianceUtilities.cvaMerge([cvaInputAddon(), "border-r", "rounded-l-lg"]);
|
|
260
|
+
const cvaInputAddonAfter = cssClassVarianceUtilities.cvaMerge([cvaInputAddon(), "border-l", "rounded-r-lg"]);
|
|
261
|
+
const cvaInputPrefix = cssClassVarianceUtilities.cvaMerge([
|
|
262
|
+
"flex",
|
|
263
|
+
"justify-center",
|
|
264
|
+
"items-center",
|
|
265
|
+
"text-slate-400",
|
|
266
|
+
"hover:component-search-prefix",
|
|
267
|
+
"component-baseInput-prefix",
|
|
268
|
+
"component-search-borderless",
|
|
269
|
+
"px-3",
|
|
270
|
+
], {
|
|
176
271
|
variants: {
|
|
177
272
|
disabled: {
|
|
178
|
-
true: "
|
|
273
|
+
true: ["text-slate-500"],
|
|
179
274
|
false: "",
|
|
180
275
|
},
|
|
181
276
|
},
|
|
182
277
|
});
|
|
183
|
-
const
|
|
184
|
-
const cvaFormGroupContainerAfter = cssClassVarianceUtilities.cvaMerge(["flex", "justify-between", "mt-1", "text-xs", "text-slate-500"], {
|
|
278
|
+
const cvaInputSuffix = cssClassVarianceUtilities.cvaMerge(["flex", "justify-center", "items-center", "text-slate-400", "px-3"], {
|
|
185
279
|
variants: {
|
|
186
|
-
|
|
187
|
-
true: "text-
|
|
280
|
+
disabled: {
|
|
281
|
+
true: ["text-slate-500"],
|
|
188
282
|
false: "",
|
|
189
283
|
},
|
|
190
284
|
},
|
|
191
285
|
});
|
|
192
|
-
const cvaHelpAddon = cssClassVarianceUtilities.cvaMerge(["ml-auto"]);
|
|
193
286
|
|
|
194
287
|
/**
|
|
195
|
-
*
|
|
196
|
-
*
|
|
288
|
+
* A base input component that can be used for text inputs, password inputs, etc.
|
|
289
|
+
* A reference to the input element is provided as the `ref` prop.
|
|
290
|
+
* Extends props from [React.InputHTMLAttributes](https://reactjs.org/docs/dom-elements.html#input)
|
|
197
291
|
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
292
|
+
* For specific input types make sure to use the corresponding input component.
|
|
293
|
+
* This is a base used by our other input components such as TextInput, NumberInput, PasswordInput, etc.
|
|
200
294
|
*/
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
295
|
+
const BaseInput = React__namespace.forwardRef((_a, ref) => {
|
|
296
|
+
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"]);
|
|
297
|
+
const isReadOnlyWithPlaceholder = React.useMemo(() => !!rest.readOnly && !!rest.placeholder && !rest.value, [rest.readOnly, rest.placeholder, rest.value]);
|
|
298
|
+
const renderAsDisabled = rest.disabled || rest.readOnly;
|
|
299
|
+
const innerRef = React__namespace.useRef(null);
|
|
300
|
+
React__namespace.useImperativeHandle(ref, () => innerRef.current, []);
|
|
301
|
+
return (jsxRuntime.jsxs("div", { className: cvaInput({
|
|
302
|
+
disabled: renderAsDisabled,
|
|
303
|
+
invalid: isInvalid,
|
|
304
|
+
size: fieldSize,
|
|
305
|
+
className,
|
|
306
|
+
}), "data-testid": dataTestId && `${dataTestId}-container`, children: [addonBefore && addonBefore !== undefined ? (jsxRuntime.jsx("div", { className: cvaInputAddonBefore({ className: addonBeforeClassName }), "data-testid": dataTestId && `${dataTestId}-addonBefore`, children: addonBefore })) : null, prefix && addonBefore !== prefix ? (jsxRuntime.jsx("div", { className: cvaInputPrefix({
|
|
307
|
+
disabled: renderAsDisabled,
|
|
308
|
+
}), "data-testid": dataTestId && `${dataTestId}-prefix`, children: prefix })) : null, jsxRuntime.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 ? (jsxRuntime.jsx("div", { className: cvaInputSuffix({
|
|
309
|
+
disabled: renderAsDisabled,
|
|
310
|
+
}), "data-testid": dataTestId && `${dataTestId}-suffix`, children: suffix })) : null, rest.readOnly === true && showDefaultActions ? (jsxRuntime.jsx(ActionButton, { type: "COPY", value: innerRef }, "default-copy-action")) : null, actions && addonBefore !== actions ? actions : null, addonAfter && addonAfter !== undefined && addonBefore !== addonAfter ? (jsxRuntime.jsx("div", { className: cvaInputAddonAfter(), "data-testid": dataTestId && `${dataTestId}-addonAfter`, children: addonAfter })) : null] }));
|
|
311
|
+
});
|
|
204
312
|
|
|
205
|
-
const
|
|
206
|
-
"
|
|
207
|
-
"
|
|
208
|
-
"
|
|
209
|
-
"
|
|
210
|
-
"
|
|
211
|
-
"
|
|
212
|
-
"
|
|
213
|
-
"focus-within:ring-inset",
|
|
214
|
-
"focus-within:ring-primary-600",
|
|
215
|
-
"focus-within:border-slate-400",
|
|
216
|
-
"hover:border-slate-400",
|
|
217
|
-
"hover:bg-slate-50",
|
|
218
|
-
"bg-white",
|
|
219
|
-
"transition",
|
|
313
|
+
const cvaLabel = cssClassVarianceUtilities.cvaMerge([
|
|
314
|
+
"text-base",
|
|
315
|
+
"text-slate-700",
|
|
316
|
+
"truncate",
|
|
317
|
+
"hover:text-slate-800",
|
|
318
|
+
"group-hover:text-slate-800",
|
|
319
|
+
"active:text-slate-800",
|
|
320
|
+
"group-active:text-slate-800",
|
|
220
321
|
], {
|
|
221
322
|
variants: {
|
|
222
323
|
invalid: {
|
|
223
|
-
true: "
|
|
324
|
+
true: "text-red-600 hover:text-red-700 active:text-red-700 group-hover:text-red-700 group-active:text-red-700",
|
|
224
325
|
false: "",
|
|
225
326
|
},
|
|
226
327
|
disabled: {
|
|
227
|
-
true: "
|
|
328
|
+
true: "text-slate-400 hover:text-slate-400 group-hover:text-slate-400",
|
|
228
329
|
false: "",
|
|
229
330
|
},
|
|
230
331
|
},
|
|
@@ -233,94 +334,15 @@ const cvaSelect = cssClassVarianceUtilities.cvaMerge([
|
|
|
233
334
|
disabled: false,
|
|
234
335
|
},
|
|
235
336
|
});
|
|
236
|
-
const cvaSelectIcon = cssClassVarianceUtilities.cvaMerge("mr-2 flex cursor-pointer items-center justify-center text-slate-400 hover:text-slate-500");
|
|
237
|
-
const cvaSelectPrefix = cssClassVarianceUtilities.cvaMerge(["flex", "justify-center", "items-center", "text-slate-400", "pl-2"]);
|
|
238
|
-
const cvaSelectXIcon = cssClassVarianceUtilities.cvaMerge([
|
|
239
|
-
"mr-2 flex cursor-pointer items-center justify-center text-slate-400 hover:text-slate-500",
|
|
240
|
-
"ml-1",
|
|
241
|
-
]);
|
|
242
|
-
const cvaSelectMenuList = cssClassVarianceUtilities.cvaMerge(["min-w-min", "shadow-md", "rounded-lg", "z-20", "bg-white", "p-1", "border", "border-slate-300", "gap-1", "grid"], {
|
|
243
|
-
variants: {
|
|
244
|
-
menuIsOpen: {
|
|
245
|
-
true: "animate-fade-in-fast",
|
|
246
|
-
false: "animate-fade-out-fast",
|
|
247
|
-
},
|
|
248
|
-
},
|
|
249
|
-
});
|
|
250
|
-
const cvaSelectDynamicTagContainer = cssClassVarianceUtilities.cvaMerge(["h-full", "flex", "gap-1", "items-center"], {
|
|
251
|
-
variants: {
|
|
252
|
-
visible: { true: "visible", false: "invisible" },
|
|
253
|
-
},
|
|
254
|
-
});
|
|
255
|
-
const cvaSelectCounter = cssClassVarianceUtilities.cvaMerge(["overflow-hidden", "whitespace-nowrap"]);
|
|
256
|
-
const cvaSelectMenu = cssClassVarianceUtilities.cvaMerge(["relative", "p-1", "grid", "gap-1"]);
|
|
257
337
|
|
|
258
338
|
/**
|
|
259
|
-
* The
|
|
339
|
+
* The CheckIcon component is used by the checkbox to display the checked state.
|
|
260
340
|
*
|
|
261
|
-
* @param {
|
|
262
|
-
* @returns {JSX.Element}
|
|
341
|
+
* @param {CheckIconProps} props - The props for the CheckIcon component
|
|
342
|
+
* @returns {JSX.Element} CheckIcon component
|
|
263
343
|
*/
|
|
264
|
-
const
|
|
265
|
-
return (jsxRuntime.
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* @param {MultiValue<Option> | SingleValue<Option>} arg option to check type
|
|
270
|
-
* @returns {arg is MultiValue<Option> } is Multivalue
|
|
271
|
-
*/
|
|
272
|
-
function isMultiValue(arg) {
|
|
273
|
-
return Array.isArray(arg);
|
|
274
|
-
}
|
|
275
|
-
function isGroupBase(arg) {
|
|
276
|
-
return arg.options !== undefined;
|
|
277
|
-
}
|
|
278
|
-
const isSelectedOption = (option, selected) => {
|
|
279
|
-
if (isGroupBase(option)) {
|
|
280
|
-
return false;
|
|
281
|
-
}
|
|
282
|
-
return isMultiValue(selected)
|
|
283
|
-
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
284
|
-
selected.some(v => v.value === option.value)
|
|
285
|
-
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
286
|
-
option.value === (selected === null || selected === void 0 ? void 0 : selected.value);
|
|
287
|
-
};
|
|
288
|
-
const removeSelectedFromGroups = (group, selected) => {
|
|
289
|
-
if (isGroupBase(group)) {
|
|
290
|
-
return Object.assign(Object.assign({}, group), { options: group.options.filter(option => !isSelectedOption(option, selected)) });
|
|
291
|
-
}
|
|
292
|
-
return group;
|
|
293
|
-
};
|
|
294
|
-
/**
|
|
295
|
-
* @template IsMulti
|
|
296
|
-
* @template Group
|
|
297
|
-
* @param {OptionsOrGroups<Option, Group> | undefined} options An array of options to select from
|
|
298
|
-
* @param {PropsValue<Option> | undefined} value Selected values
|
|
299
|
-
* @returns {OptionsOrGroups<Option, Group>} An array of ordered options with selected on top
|
|
300
|
-
*/
|
|
301
|
-
const getOrderedOptions = (options, value) => {
|
|
302
|
-
if (value && options) {
|
|
303
|
-
const orderedValues = isMultiValue(value)
|
|
304
|
-
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
305
|
-
[...value].sort((a, b) => a.label.localeCompare(b.label))
|
|
306
|
-
: [value];
|
|
307
|
-
const selectableOptions = options
|
|
308
|
-
.filter(option => !isSelectedOption(option, value))
|
|
309
|
-
.map(option => removeSelectedFromGroups(option, value));
|
|
310
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
311
|
-
return orderedValues.concat(selectableOptions) || [];
|
|
312
|
-
}
|
|
313
|
-
return options || [];
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* The CheckIcon component is used by the checkbox to display the checked state.
|
|
318
|
-
*
|
|
319
|
-
* @param {CheckIconProps} props - The props for the CheckIcon component
|
|
320
|
-
* @returns {JSX.Element} CheckIcon component
|
|
321
|
-
*/
|
|
322
|
-
const CheckIcon = ({ className, dataTestId }) => {
|
|
323
|
-
return (jsxRuntime.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: jsxRuntime.jsx("path", { d: "m2 5.5 2 2L8.5 3", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
344
|
+
const CheckIcon = ({ className, dataTestId }) => {
|
|
345
|
+
return (jsxRuntime.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: jsxRuntime.jsx("path", { d: "m2 5.5 2 2L8.5 3", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
324
346
|
};
|
|
325
347
|
|
|
326
348
|
const cvaCheckbox = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -501,662 +523,117 @@ const Checkbox = React__namespace.forwardRef((_a, ref) => {
|
|
|
501
523
|
});
|
|
502
524
|
|
|
503
525
|
/**
|
|
504
|
-
* A
|
|
526
|
+
* A wrapper around BaseInput with a pop-up day picker.
|
|
505
527
|
*
|
|
506
|
-
*
|
|
507
|
-
* @returns {JSX.Element} SingleSelectMenuItem
|
|
528
|
+
* NOTE: If shown with a label, please use the `DateField` component instead.
|
|
508
529
|
*/
|
|
509
|
-
const
|
|
510
|
-
|
|
511
|
-
|
|
530
|
+
const DateInput = React.forwardRef((_a, ref) => {
|
|
531
|
+
var { min, max, defaultValue, value } = _a, rest = __rest(_a, ["min", "max", "defaultValue", "value"]);
|
|
532
|
+
const formatDateToInputString = (date) => date instanceof Date ? dateFns.format(date, "yyyy-MM-dd") : date;
|
|
533
|
+
// Chrome and Firefox need their default icon to have datepicker functionality.
|
|
534
|
+
const showIcon = !/Chrome/.test(navigator.userAgent) && !/Firefox/.test(navigator.userAgent);
|
|
535
|
+
return (jsxRuntime.jsx(BaseInput, Object.assign({ defaultValue: formatDateToInputString(defaultValue), max: formatDateToInputString(max), min: formatDateToInputString(min), ref: ref, suffix: showIcon && jsxRuntime.jsx(reactComponents.Icon, { dataTestId: "calendar", name: "Calendar", size: "medium", type: "solid" }), type: "date", value: formatDateToInputString(value) }, rest)));
|
|
536
|
+
});
|
|
537
|
+
|
|
512
538
|
/**
|
|
513
|
-
*
|
|
539
|
+
* The Label component is used for labels for input fields.
|
|
540
|
+
* This component is **not used directly**, but is part of the FormGroup and Field components.
|
|
514
541
|
*
|
|
515
|
-
* @param {
|
|
516
|
-
* @returns {JSX.Element}
|
|
542
|
+
* @param {LabelProps} props - The props for the Label component
|
|
543
|
+
* @returns {JSX.Element} Label component
|
|
517
544
|
*/
|
|
518
|
-
const
|
|
519
|
-
return (jsxRuntime.jsx(
|
|
520
|
-
e.stopPropagation();
|
|
521
|
-
onClick && onClick(e);
|
|
522
|
-
}, prefix: jsxRuntime.jsx(Checkbox, { checked: selected, disabled: disabled, onChange: () => null, onClick: e => {
|
|
523
|
-
e.stopPropagation();
|
|
524
|
-
}, readOnly: false }), selected: selected }));
|
|
545
|
+
const Label = ({ id, htmlFor, children, className, dataTestId, disabled, isInvalid, }) => {
|
|
546
|
+
return (jsxRuntime.jsx("label", { className: cvaLabel({ invalid: isInvalid, disabled, className }), "data-testid": dataTestId, htmlFor: htmlFor || "", id: id || "", children: children }));
|
|
525
547
|
};
|
|
526
548
|
|
|
549
|
+
const cvaFormGroup = cssClassVarianceUtilities.cvaMerge(["component-formGroup-gap"], {
|
|
550
|
+
variants: {
|
|
551
|
+
disabled: {
|
|
552
|
+
true: "pointer-events-none",
|
|
553
|
+
false: "",
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
});
|
|
557
|
+
const cvaFormGroupContainerBefore = cssClassVarianceUtilities.cvaMerge(["flex", "gap-1", "mb-1"]);
|
|
558
|
+
const cvaFormGroupContainerAfter = cssClassVarianceUtilities.cvaMerge(["flex", "justify-between", "mt-1", "text-xs", "text-slate-500"], {
|
|
559
|
+
variants: {
|
|
560
|
+
invalid: {
|
|
561
|
+
true: "text-danger-500",
|
|
562
|
+
false: "",
|
|
563
|
+
},
|
|
564
|
+
},
|
|
565
|
+
});
|
|
566
|
+
const cvaHelpAddon = cssClassVarianceUtilities.cvaMerge(["ml-auto"]);
|
|
567
|
+
|
|
527
568
|
/**
|
|
528
|
-
*
|
|
529
|
-
*
|
|
569
|
+
* The FormGroup component should be used to wrap any Input element that needs a label.
|
|
570
|
+
* Besides a label the component supplies an optional Tooltip, HelpText and HelpAddon support.
|
|
530
571
|
*
|
|
531
|
-
* @param {
|
|
532
|
-
* @returns {JSX.Element}
|
|
572
|
+
* @param {FormGroupProps} props - The props for the FormGroup component
|
|
573
|
+
* @returns {JSX.Element} FormGroup component
|
|
533
574
|
*/
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
const ref = React__default["default"].useRef(null);
|
|
537
|
-
React__default["default"].useLayoutEffect(() => {
|
|
538
|
-
var _a;
|
|
539
|
-
onWidthKnown && onWidthKnown({ width: ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0 });
|
|
540
|
-
}, [ref, onWidthKnown]);
|
|
541
|
-
return (jsxRuntime.jsx(reactComponents.Tag, Object.assign({ ref: ref }, rest, { children: children })));
|
|
575
|
+
const FormGroup = ({ isInvalid, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, tipIconProps, disabled = false, }) => {
|
|
576
|
+
return (jsxRuntime.jsxs("div", { className: cvaFormGroup({ disabled, className }), "data-testid": dataTestId, children: [jsxRuntime.jsxs("div", { className: cvaFormGroupContainerBefore(), children: [jsxRuntime.jsx(Label, { className: "component-formGroup-font", dataTestId: dataTestId && `${dataTestId}-label`, htmlFor: htmlFor, id: htmlFor + "-label", children: label }), tip && (jsxRuntime.jsx(reactComponents.Tooltip, { dataTestId: dataTestId && `${dataTestId}-tooltip`, iconProps: tipIconProps, label: tip, placement: "bottom" }))] }), children, jsxRuntime.jsxs("div", { className: cvaFormGroupContainerAfter({ invalid: isInvalid }), children: [helpText && jsxRuntime.jsx("span", { "data-testid": dataTestId && `${dataTestId}-helpText`, children: helpText }), helpAddon && (jsxRuntime.jsx("span", { className: cvaHelpAddon(), "data-testid": dataTestId && `${dataTestId}-helpAddon`, children: helpAddon }))] })] }));
|
|
542
577
|
};
|
|
543
578
|
|
|
544
579
|
/**
|
|
545
|
-
*
|
|
580
|
+
* The date field component is used for entering date values.
|
|
546
581
|
*
|
|
547
|
-
*
|
|
548
|
-
*
|
|
582
|
+
* _**Do use**_ the DateField for date input.
|
|
583
|
+
*
|
|
584
|
+
* _**Do not use**_ this fields for non-serialized dates. Use TextField instead.
|
|
549
585
|
*/
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
const
|
|
553
|
-
const
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
},
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
counter = counter + 1;
|
|
596
|
-
}
|
|
597
|
-
return null;
|
|
598
|
-
})
|
|
599
|
-
.filter(element => element !== null);
|
|
600
|
-
return (jsxRuntime.jsxs("div", { className: cvaSelectDynamicTagContainer({ visible: isReady }), ref: containerRef, style: {
|
|
601
|
-
width: `${width}`,
|
|
602
|
-
}, children: [renderedElements, postFix] }));
|
|
603
|
-
};
|
|
586
|
+
const DateField = React.forwardRef((_a, ref) => {
|
|
587
|
+
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"]);
|
|
588
|
+
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
589
|
+
const htmlForId = id ? id : "dateField-" + uuid.v4();
|
|
590
|
+
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsxRuntime.jsx(DateInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref }, rest, { className: className, dataTestId: dataTestId })) }));
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
const cvaDropZone = cssClassVarianceUtilities.cvaMerge([
|
|
594
|
+
"flex",
|
|
595
|
+
"component-baseInput-background",
|
|
596
|
+
"justify-center",
|
|
597
|
+
"text-slate-500",
|
|
598
|
+
"rounded-sm",
|
|
599
|
+
"border-2",
|
|
600
|
+
"border-gray-200",
|
|
601
|
+
"border-dashed",
|
|
602
|
+
"hover:bg-slate-100",
|
|
603
|
+
"hover:border-solid",
|
|
604
|
+
"hover:border-primary-500",
|
|
605
|
+
], {
|
|
606
|
+
variants: {
|
|
607
|
+
size: {
|
|
608
|
+
small: ["p-2"],
|
|
609
|
+
medium: ["p-4"],
|
|
610
|
+
large: ["p-8"],
|
|
611
|
+
},
|
|
612
|
+
disabled: { true: ["bg-slate-100", "hover:bg-slate-100"], false: "" },
|
|
613
|
+
dragActive: { true: ["border-gray-200", "bg-slate-100"], false: "" },
|
|
614
|
+
dropComplete: {
|
|
615
|
+
true: ["border-solid", "border-primary-500", "bg-slate-100", "hover:border-solid", "hover:border-gray-200"],
|
|
616
|
+
false: "",
|
|
617
|
+
},
|
|
618
|
+
invalid: { true: ["border-danger-600", "text-danger-500"], false: "" },
|
|
619
|
+
},
|
|
620
|
+
});
|
|
621
|
+
const cvaDropZoneLabel = cssClassVarianceUtilities.cvaMerge([
|
|
622
|
+
"h-full",
|
|
623
|
+
"pt-1",
|
|
624
|
+
"pb-1",
|
|
625
|
+
"gap-2",
|
|
626
|
+
"items-center",
|
|
627
|
+
"flex-col",
|
|
628
|
+
"flex",
|
|
629
|
+
"justify-center",
|
|
630
|
+
]);
|
|
604
631
|
|
|
605
632
|
/**
|
|
606
|
-
*
|
|
607
|
-
* 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.
|
|
633
|
+
* The Drop Zone can be used to drag and drop files
|
|
608
634
|
*
|
|
609
|
-
* @
|
|
610
|
-
* @
|
|
611
|
-
* @param {Partial<SelectComponents<Option, IsMulti, Group>> | undefined} componentsProps a custom component prop that you can to override defaults
|
|
612
|
-
* @param {boolean} disabled decide to override disabled variant
|
|
613
|
-
* @param {boolean} menuIsOpen menu is open state
|
|
614
|
-
* @param {React.MutableRefObject<boolean>} refMenuIsEnabled a flag to block menu from open
|
|
615
|
-
* @param {string} dataTestId a test id
|
|
616
|
-
* @param {number} maxSelectedDisplayCount a number of max display count
|
|
617
|
-
* @param {JSX.Element} dropdownIcon an custom dropdown icon
|
|
618
|
-
* @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
|
|
619
|
-
*/
|
|
620
|
-
const useCustomComponents = (componentsProps, disabled, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon) => {
|
|
621
|
-
const [t] = useTranslation();
|
|
622
|
-
// perhaps it should not be wrap in memo (causing some issues with opening and closing on mobiles)
|
|
623
|
-
const customComponents = React__namespace.useMemo(() => {
|
|
624
|
-
return Object.assign({ ValueContainer: props => {
|
|
625
|
-
if (props.isMulti && Array.isArray(props.children) && props.children.length > 0) {
|
|
626
|
-
const PLACEHOLDER_KEY = "placeholder";
|
|
627
|
-
const key = props && props.children && props.children[0] ? props.children[0].key : "";
|
|
628
|
-
const values = props && props.children ? props.children[0] : [];
|
|
629
|
-
const tags = key === PLACEHOLDER_KEY ? [] : values;
|
|
630
|
-
const searchInput = props && props.children && props.children[1];
|
|
631
|
-
return (jsxRuntime.jsx(ReactSelect.components.ValueContainer, Object.assign({}, props, { isDisabled: props.selectProps.isDisabled, children: maxSelectedDisplayCount === undefined ? (jsxRuntime.jsx(TagsContainer, { disabled: disabled, items: tags
|
|
632
|
-
? tags.map(({ props: tagProps }) => {
|
|
633
|
-
return {
|
|
634
|
-
text: tagProps.children,
|
|
635
|
-
onClick: disabled
|
|
636
|
-
? undefined
|
|
637
|
-
: (e) => {
|
|
638
|
-
var _a, _b;
|
|
639
|
-
refMenuIsEnabled.current = false;
|
|
640
|
-
((_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));
|
|
641
|
-
},
|
|
642
|
-
disabled: disabled,
|
|
643
|
-
};
|
|
644
|
-
})
|
|
645
|
-
: [], postFix: searchInput, width: "100%" })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [tags &&
|
|
646
|
-
tags.slice(0, maxSelectedDisplayCount).map(({ props: tagProps }) => {
|
|
647
|
-
var _a, _b;
|
|
648
|
-
return (jsxRuntime.jsx(reactComponents.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 => {
|
|
649
|
-
var _a, _b;
|
|
650
|
-
e.stopPropagation();
|
|
651
|
-
refMenuIsEnabled.current = false;
|
|
652
|
-
((_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));
|
|
653
|
-
}, children: tagProps.children }, (_b = tagProps.children) === null || _b === void 0 ? void 0 : _b.toString()));
|
|
654
|
-
}), tags && tags.length > maxSelectedDisplayCount && (jsxRuntime.jsxs(reactComponents.Tag, { color: "neutral", dataTestId: "counter-tag", children: ["+", tags.length - maxSelectedDisplayCount] })), searchInput] })) })));
|
|
655
|
-
}
|
|
656
|
-
return (jsxRuntime.jsx(ReactSelect.components.ValueContainer, Object.assign({}, props, { isDisabled: props.selectProps.isDisabled, children: props.children })));
|
|
657
|
-
}, LoadingIndicator: props => {
|
|
658
|
-
return jsxRuntime.jsx(reactComponents.Spinner, { className: "mt-1.5 mr-1", size: "small" });
|
|
659
|
-
}, DropdownIndicator: props => {
|
|
660
|
-
const icon = props.selectProps.menuIsOpen ? (jsxRuntime.jsx(reactComponents.Icon, { name: "ChevronUp", size: "medium" })) : (jsxRuntime.jsx(reactComponents.Icon, { name: "ChevronDown", size: "medium" }));
|
|
661
|
-
return props.selectProps.isLoading ? null : (jsxRuntime.jsx(ReactSelect.components.DropdownIndicator, Object.assign({}, props, { children: jsxRuntime.jsx("div", { className: cvaSelectIcon(), children: dropdownIcon ? dropdownIcon : icon }) })));
|
|
662
|
-
}, IndicatorSeparator: () => null, ClearIndicator: props => {
|
|
663
|
-
if (disabled) {
|
|
664
|
-
return null;
|
|
665
|
-
}
|
|
666
|
-
return (jsxRuntime.jsx(ReactSelect.components.ClearIndicator, Object.assign({}, props, { children: jsxRuntime.jsx("div", { className: cvaSelectXIcon(), "data-testid": dataTestId && `${dataTestId}-XMarkIcon`, onClick: props.clearValue, children: jsxRuntime.jsx(reactComponents.Icon, { name: "XCircle", size: "medium", title: t("clearIndicator.icon.tooltip.clearAll") }) }) })));
|
|
667
|
-
}, Control: props => {
|
|
668
|
-
return jsxRuntime.jsx(ReactSelect.components.Control, Object.assign({}, props, { className: props.isDisabled ? "bg-slate-100" : "" }));
|
|
669
|
-
}, SingleValue: props => {
|
|
670
|
-
return (jsxRuntime.jsx(ReactSelect.components.SingleValue, Object.assign({}, props, { className: props.isDisabled ? "text-slate-700" : "", children: jsxRuntime.jsx("div", { "data-testid": dataTestId + "-singleValue", children: props.children }) })));
|
|
671
|
-
}, Menu: props => {
|
|
672
|
-
return (jsxRuntime.jsx(ReactSelect.components.Menu, Object.assign({}, props, { className: cvaSelectMenuList({ menuIsOpen: props.selectProps.menuIsOpen }) })));
|
|
673
|
-
}, MenuList: props => {
|
|
674
|
-
return (jsxRuntime.jsx(ReactSelect.components.MenuList, Object.assign({}, props, { innerProps: Object.assign(Object.assign({}, props.innerProps), { onScroll: e => {
|
|
675
|
-
const listEl = e.currentTarget;
|
|
676
|
-
if (listEl.scrollTop + listEl.clientHeight >= listEl.scrollHeight) {
|
|
677
|
-
props.selectProps.onMenuScrollToBottom && props.selectProps.onMenuScrollToBottom(new TouchEvent(""));
|
|
678
|
-
}
|
|
679
|
-
} }), children: props.children })));
|
|
680
|
-
}, Option: props => {
|
|
681
|
-
const componentProps = {
|
|
682
|
-
label: props.label,
|
|
683
|
-
focused: props.isFocused,
|
|
684
|
-
selected: props.isSelected,
|
|
685
|
-
onClick: props.innerProps.onClick,
|
|
686
|
-
};
|
|
687
|
-
return (jsxRuntime.jsx(ReactSelect.components.Option, Object.assign({}, props, { innerProps: Object.assign(Object.assign({}, props.innerProps), { role: "option", onClick: () => { } }), children: props.isMulti ? (jsxRuntime.jsx(MultiSelectMenuItem, Object.assign({}, componentProps, { dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled }))) : (jsxRuntime.jsx(SingleSelectMenuItem, Object.assign({}, componentProps, { dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled || props.isDisabled }))) })));
|
|
688
|
-
} }, componentsProps);
|
|
689
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
690
|
-
}, [componentsProps, disabled, maxSelectedDisplayCount]); // do not add dropdownIcon (it will cause issue with opening/closing list for selects with custom icon)
|
|
691
|
-
return customComponents;
|
|
692
|
-
};
|
|
693
|
-
|
|
694
|
-
/**
|
|
695
|
-
* @template IsMulti
|
|
696
|
-
* @template Group
|
|
697
|
-
* @param {React.RefObject<HTMLDivElement>} refContainer react ref to container element
|
|
698
|
-
* @param {React.RefObject<HTMLDivElement>} refPrefix react ref to prefix element
|
|
699
|
-
* @param {number | undefined} maxSelectedDisplayCount a number of max display count
|
|
700
|
-
* @param {StylesConfig<Option, IsMulti, Group> | undefined} styles a optional object to override styles of react-select
|
|
701
|
-
* @returns {StylesConfig<Option, boolean>} styles to override in select
|
|
702
|
-
*/
|
|
703
|
-
const useCustomStyles = (refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled) => {
|
|
704
|
-
const customStyles = React__namespace.useMemo(() => {
|
|
705
|
-
return Object.assign({ control: base => {
|
|
706
|
-
return Object.assign(Object.assign({}, base), { border: "0", boxShadow: "0", "&:hover": {
|
|
707
|
-
border: "0",
|
|
708
|
-
}, marginRight: "2px", backgroundColor: "" });
|
|
709
|
-
}, 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: () => ({
|
|
710
|
-
width: "0px",
|
|
711
|
-
}), menu: base => {
|
|
712
|
-
return Object.assign(Object.assign({}, base), { width: "100%", marginTop: "4px", marginBottom: "18px", transition: "all 1s ease-in-out" });
|
|
713
|
-
}, 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 => {
|
|
714
|
-
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" });
|
|
715
|
-
}, valueContainer: base => {
|
|
716
|
-
return Object.assign(Object.assign({}, base), { flexWrap: maxSelectedDisplayCount !== undefined ? "wrap" : "nowrap", gap: "0.25rem" });
|
|
717
|
-
}, 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 => {
|
|
718
|
-
return Object.assign(Object.assign({}, base), { padding: "0px" });
|
|
719
|
-
} }, styles);
|
|
720
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
721
|
-
}, [refContainer, refPrefix]);
|
|
722
|
-
return { customStyles };
|
|
723
|
-
};
|
|
724
|
-
|
|
725
|
-
/**
|
|
726
|
-
* A hook used by selects to share the common code
|
|
727
|
-
*
|
|
728
|
-
* @param {SelectProps} props - The props for the Select component
|
|
729
|
-
* @returns {IUseSelect} Select component
|
|
730
|
-
*/
|
|
731
|
-
const useSelect = (_a) => {
|
|
732
|
-
var _b;
|
|
733
|
-
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"]);
|
|
734
|
-
const refContainer = React__default["default"].useRef(null);
|
|
735
|
-
const refPrefix = React__default["default"].useRef(null);
|
|
736
|
-
const { customStyles } = useCustomStyles(refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled);
|
|
737
|
-
const [menuIsOpen, setMenuIsOpen] = React__default["default"].useState((_b = props.menuIsOpen) !== null && _b !== void 0 ? _b : false);
|
|
738
|
-
const refMenuIsEnabled = React__default["default"].useRef(true);
|
|
739
|
-
const customComponents = useCustomComponents(components, disabled || false, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon);
|
|
740
|
-
const menuPlacement = "auto";
|
|
741
|
-
const openMenuHandler = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
742
|
-
onMenuOpen && onMenuOpen();
|
|
743
|
-
if (refMenuIsEnabled.current) {
|
|
744
|
-
setMenuIsOpen(true);
|
|
745
|
-
}
|
|
746
|
-
else {
|
|
747
|
-
refMenuIsEnabled.current = true;
|
|
748
|
-
}
|
|
749
|
-
});
|
|
750
|
-
const closeMenuHandler = () => {
|
|
751
|
-
setMenuIsOpen(false);
|
|
752
|
-
onMenuClose && onMenuClose();
|
|
753
|
-
};
|
|
754
|
-
const orderedOptions = React__default["default"].useMemo(() => {
|
|
755
|
-
return disabled
|
|
756
|
-
? getOrderedOptions(options, value).map(option => {
|
|
757
|
-
return Object.assign(Object.assign({}, option), { disabled: true });
|
|
758
|
-
})
|
|
759
|
-
: getOrderedOptions(options, value);
|
|
760
|
-
}, [options, value, disabled]);
|
|
761
|
-
return {
|
|
762
|
-
refContainer,
|
|
763
|
-
refPrefix,
|
|
764
|
-
customStyles,
|
|
765
|
-
menuIsOpen,
|
|
766
|
-
customComponents,
|
|
767
|
-
menuPlacement,
|
|
768
|
-
openMenuHandler,
|
|
769
|
-
closeMenuHandler,
|
|
770
|
-
orderedOptions,
|
|
771
|
-
};
|
|
772
|
-
};
|
|
773
|
-
|
|
774
|
-
/**
|
|
775
|
-
* The CreatableSelect component.
|
|
776
|
-
*
|
|
777
|
-
* @param {CreateableSelectProps} props - The props for the CreatableSelect component
|
|
778
|
-
* @returns {JSX.Element} CreatableSelect component
|
|
779
|
-
*/
|
|
780
|
-
const CreatableSelect = (props) => {
|
|
781
|
-
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;
|
|
782
|
-
const hasError = !!error;
|
|
783
|
-
const { refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
|
|
784
|
-
const selectProps = {
|
|
785
|
-
value,
|
|
786
|
-
menuPlacement,
|
|
787
|
-
maxMenuHeight,
|
|
788
|
-
onChange,
|
|
789
|
-
"aria-label": label,
|
|
790
|
-
"data-testid": dataTestId,
|
|
791
|
-
components: customComponents,
|
|
792
|
-
styles: customStyles,
|
|
793
|
-
tabSelectsValue: false,
|
|
794
|
-
blurInputOnSelect: !isMulti,
|
|
795
|
-
menuPortalTarget: document.body,
|
|
796
|
-
isSearchable: disabled ? false : true,
|
|
797
|
-
menuShouldBlockScroll: true,
|
|
798
|
-
menuShouldScrollIntoView: true,
|
|
799
|
-
openMenuOnFocus: disabled ? false : true,
|
|
800
|
-
menuIsOpen: disabled ? false : menuIsOpen,
|
|
801
|
-
openMenuOnClick: true,
|
|
802
|
-
closeMenuOnSelect: false,
|
|
803
|
-
isMulti: isMulti,
|
|
804
|
-
classNamePrefix,
|
|
805
|
-
isLoading,
|
|
806
|
-
onInputChange,
|
|
807
|
-
placeholder,
|
|
808
|
-
isClearable,
|
|
809
|
-
id,
|
|
810
|
-
};
|
|
811
|
-
return (jsxRuntime.jsx(SelectContainer, { dataTestId: dataTestId, description: description, error: error, hasError: hasError, hideLabel: hideLabel, id: id, info: info, isDisabled: disabled, label: label, children: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [prefix !== undefined && (jsxRuntime.jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId && `${dataTestId}-prefix`, ref: refPrefix, children: prefix })), async ? (jsxRuntime.jsx(ReactAsyncCreatableSelect__default["default"], Object.assign({ "aria-label": label, components: customComponents, "data-testid": dataTestId, maxMenuHeight: maxMenuHeight }, props, { onMenuClose: () => {
|
|
812
|
-
closeMenuHandler();
|
|
813
|
-
}, onMenuOpen: () => {
|
|
814
|
-
!disabled && openMenuHandler();
|
|
815
|
-
} }))) : (jsxRuntime.jsx(ReactCreatableSelect__default["default"], Object.assign({}, selectProps, { isMulti: isMulti, onMenuClose: () => {
|
|
816
|
-
closeMenuHandler();
|
|
817
|
-
}, onMenuOpen: () => {
|
|
818
|
-
!disabled && openMenuHandler();
|
|
819
|
-
}, options: filterOption ? orderedOptions : options })))] }) }));
|
|
820
|
-
};
|
|
821
|
-
|
|
822
|
-
/**
|
|
823
|
-
* Selects are input components used to choose a value from a set.
|
|
824
|
-
*
|
|
825
|
-
* @param {SelectProps} props - The props for the Select component
|
|
826
|
-
* @returns {JSX.Element} Select component
|
|
827
|
-
*/
|
|
828
|
-
const Select = (props) => {
|
|
829
|
-
const { className } = props, propsNoClassName = __rest(props, ["className"]);
|
|
830
|
-
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;
|
|
831
|
-
const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
|
|
832
|
-
const selectProps = {
|
|
833
|
-
value,
|
|
834
|
-
menuPlacement,
|
|
835
|
-
maxMenuHeight,
|
|
836
|
-
onChange,
|
|
837
|
-
"aria-label": label,
|
|
838
|
-
"data-testid": dataTestId,
|
|
839
|
-
components: customComponents,
|
|
840
|
-
styles: customStyles,
|
|
841
|
-
tabSelectsValue: false,
|
|
842
|
-
blurInputOnSelect: !isMulti,
|
|
843
|
-
menuPortalTarget: props.menuPortalTarget || document.body,
|
|
844
|
-
isSearchable: disabled || readOnly ? false : isSearchable,
|
|
845
|
-
menuShouldBlockScroll: true,
|
|
846
|
-
menuShouldScrollIntoView: true,
|
|
847
|
-
openMenuOnFocus,
|
|
848
|
-
menuIsOpen: !readOnly ? menuIsOpen : false,
|
|
849
|
-
openMenuOnClick,
|
|
850
|
-
closeMenuOnSelect: false,
|
|
851
|
-
isMulti,
|
|
852
|
-
classNamePrefix,
|
|
853
|
-
isLoading,
|
|
854
|
-
isClearable,
|
|
855
|
-
id,
|
|
856
|
-
onMenuScrollToBottom,
|
|
857
|
-
onInputChange,
|
|
858
|
-
};
|
|
859
|
-
return (jsxRuntime.jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: disabled || readOnly, className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined && (jsxRuntime.jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId && `${dataTestId}-prefix`, ref: refPrefix, children: prefix })), async ? (jsxRuntime.jsx(ReactAsyncSelect__default["default"], Object.assign({}, propsNoClassName, selectProps, async, { onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler }))) : (jsxRuntime.jsx(ReactSelect__default["default"], Object.assign({}, propsNoClassName, selectProps, { hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : options })))] }));
|
|
860
|
-
};
|
|
861
|
-
Select.displayName = "Select";
|
|
862
|
-
|
|
863
|
-
/**
|
|
864
|
-
* The SelectField component is a Select component wrapped in the FromGroup component.
|
|
865
|
-
*
|
|
866
|
-
* This means that it can easily be added to any form alongside other Field components.
|
|
867
|
-
*
|
|
868
|
-
* This is done to make the field compatible with the React-hook-form library.
|
|
869
|
-
*
|
|
870
|
-
* @param {SelectFieldProps} props - The props for the SelectField component
|
|
871
|
-
* @returns {JSX.Element} SelectField component
|
|
872
|
-
*/
|
|
873
|
-
const SelectField = React.forwardRef((_a, ref) => {
|
|
874
|
-
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"]);
|
|
875
|
-
const [innerValue, setInnerValue] = React.useState(value || defaultValue);
|
|
876
|
-
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
877
|
-
const htmlFor = React.useMemo(() => (id ? id : "selectField-" + uuid.v4()), [id]);
|
|
878
|
-
const innerRef = React.useRef(null);
|
|
879
|
-
React.useImperativeHandle(ref, () => innerRef.current, []);
|
|
880
|
-
const handleChange = React.useCallback((newValue) => {
|
|
881
|
-
setInnerValue(newValue === null || newValue === void 0 ? void 0 : newValue.value);
|
|
882
|
-
}, []);
|
|
883
|
-
React.useEffect(() => {
|
|
884
|
-
var _a;
|
|
885
|
-
if (!innerValue) {
|
|
886
|
-
return;
|
|
887
|
-
}
|
|
888
|
-
const event = new Event("change");
|
|
889
|
-
(_a = innerRef.current) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
|
|
890
|
-
// The event as unknown as ChangeEvent<HTMLInputElement> assertion is needed because
|
|
891
|
-
// the event's type is inferred as Event, which doesn't have a target property, whereas ChangeEvent does.
|
|
892
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(event);
|
|
893
|
-
}, [onChange, innerValue]);
|
|
894
|
-
const selectedOption = React.useMemo(() => options.find(option => option.value === value), [options, value]);
|
|
895
|
-
const defaultSelectedOption = options.find(option => option.value === defaultValue);
|
|
896
|
-
return (jsxRuntime.jsxs(FormGroup, { isInvalid: renderAsInvalid,
|
|
897
|
-
htmlFor,
|
|
898
|
-
className,
|
|
899
|
-
dataTestId,
|
|
900
|
-
helpText,
|
|
901
|
-
helpAddon,
|
|
902
|
-
tip,
|
|
903
|
-
label,
|
|
904
|
-
disabled, children: [jsxRuntime.jsx("select", { onChange, ref: innerRef, name, value: innerValue, hidden: true, children: options.map(option => {
|
|
905
|
-
return (jsxRuntime.jsx("option", { value: option.value, children: option.label }, option.value));
|
|
906
|
-
}) }), jsxRuntime.jsx(Select, { id,
|
|
907
|
-
isDisabled: disabled,
|
|
908
|
-
onBlur,
|
|
909
|
-
options,
|
|
910
|
-
onChange: handleChange,
|
|
911
|
-
value: selectedOption,
|
|
912
|
-
defaultValue: defaultSelectedOption })] }));
|
|
913
|
-
});
|
|
914
|
-
|
|
915
|
-
const cvaActionButton = cssClassVarianceUtilities.cvaMerge(["drop-shadow-none", "rounded-md"], {
|
|
916
|
-
variants: {
|
|
917
|
-
size: {
|
|
918
|
-
small: ["w-6", "h-6"],
|
|
919
|
-
medium: ["w-8", "h-8"],
|
|
920
|
-
},
|
|
921
|
-
},
|
|
922
|
-
defaultVariants: {
|
|
923
|
-
size: "medium",
|
|
924
|
-
},
|
|
925
|
-
});
|
|
926
|
-
const cvaActionContainer = cssClassVarianceUtilities.cvaMerge(["flex", "items-center", "m-1"]);
|
|
927
|
-
|
|
928
|
-
/**
|
|
929
|
-
* The ActionButton component is a wrapper over IconButton to perform an action when the onClick event is triggered.
|
|
930
|
-
*
|
|
931
|
-
* @param {ActionButtonProps} props - The props for the ActionButton component
|
|
932
|
-
* @returns {JSX.Element} ActionButton component
|
|
933
|
-
*/
|
|
934
|
-
const ActionButton = ({ type, value, dataTestId, iconSize, disabled, key, className }) => {
|
|
935
|
-
const [, copyToClipboard] = reactUse.useCopyToClipboard();
|
|
936
|
-
const elementKey = React.useMemo(() => key !== null && key !== void 0 ? key : `ActionButton-${uuid.v4()}`, [key]);
|
|
937
|
-
const getIconName = () => {
|
|
938
|
-
switch (type) {
|
|
939
|
-
case "PHONE_NUMBER":
|
|
940
|
-
return "PhoneArrowUpRight";
|
|
941
|
-
case "WEB_ADDRESS":
|
|
942
|
-
return "ArrowTopRightOnSquare";
|
|
943
|
-
case "EMAIL":
|
|
944
|
-
return "Envelope";
|
|
945
|
-
case "COPY":
|
|
946
|
-
default:
|
|
947
|
-
return "ClipboardDocument";
|
|
948
|
-
}
|
|
949
|
-
};
|
|
950
|
-
const ButtonAction = () => {
|
|
951
|
-
var _a, _b;
|
|
952
|
-
switch (type) {
|
|
953
|
-
case "EMAIL":
|
|
954
|
-
return window.open(`mailto:${value}`);
|
|
955
|
-
case "WEB_ADDRESS":
|
|
956
|
-
if (value) {
|
|
957
|
-
return window.open(value, "_blank", "noopener,noreferrer");
|
|
958
|
-
}
|
|
959
|
-
return null;
|
|
960
|
-
case "PHONE_NUMBER":
|
|
961
|
-
return window.open(`tel:${value}`);
|
|
962
|
-
case "COPY":
|
|
963
|
-
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 : "");
|
|
964
|
-
default:
|
|
965
|
-
return null;
|
|
966
|
-
}
|
|
967
|
-
};
|
|
968
|
-
if (ButtonAction === null) {
|
|
969
|
-
return null;
|
|
970
|
-
}
|
|
971
|
-
return (jsxRuntime.jsx("div", { className: cvaActionContainer({ className }), children: jsxRuntime.jsx(reactComponents.IconButton, { className: cvaActionButton({ size: iconSize }), dataTestId: dataTestId || "testIconButtonId", disabled: disabled, icon: jsxRuntime.jsx(reactComponents.Icon, { name: getIconName(), size: "small" }), onClick: ButtonAction, size: "small", variant: "secondary" }) }, elementKey));
|
|
972
|
-
};
|
|
973
|
-
|
|
974
|
-
const cvaInputBase = cssClassVarianceUtilities.cvaMerge([
|
|
975
|
-
"component-baseInput-shadow",
|
|
976
|
-
"component-baseInput-border",
|
|
977
|
-
"component-baseInput-background",
|
|
978
|
-
"border-slate-300",
|
|
979
|
-
"focus-within:ring-2",
|
|
980
|
-
"focus-within:ring-inset",
|
|
981
|
-
"focus-within:ring-primary-500",
|
|
982
|
-
"focus-within:border-slate-400",
|
|
983
|
-
"hover:border-slate-400",
|
|
984
|
-
"hover:bg-slate-50",
|
|
985
|
-
"transition",
|
|
986
|
-
]);
|
|
987
|
-
const cvaInputBaseDisabled = cssClassVarianceUtilities.cvaMerge(["bg-slate-100", "hover:bg-slate-100", "hover:border-slate-300"]);
|
|
988
|
-
const cvaInputBaseInvalid = cssClassVarianceUtilities.cvaMerge(["border-danger-600", "focus-within:ring-danger-600"]);
|
|
989
|
-
const cvaInput = cssClassVarianceUtilities.cvaMerge(["relative", "flex", "h-10", cvaInputBase()], {
|
|
990
|
-
variants: {
|
|
991
|
-
size: {
|
|
992
|
-
small: ["h-8"],
|
|
993
|
-
medium: ["h-10"],
|
|
994
|
-
},
|
|
995
|
-
disabled: {
|
|
996
|
-
true: cvaInputBaseDisabled(),
|
|
997
|
-
false: "",
|
|
998
|
-
},
|
|
999
|
-
invalid: {
|
|
1000
|
-
true: cvaInputBaseInvalid(),
|
|
1001
|
-
false: "",
|
|
1002
|
-
},
|
|
1003
|
-
},
|
|
1004
|
-
});
|
|
1005
|
-
const cvaInputField = cssClassVarianceUtilities.cvaMerge([
|
|
1006
|
-
"w-full",
|
|
1007
|
-
"px-3",
|
|
1008
|
-
"border-0",
|
|
1009
|
-
"bg-transparent",
|
|
1010
|
-
"text-base",
|
|
1011
|
-
"text-slate-900",
|
|
1012
|
-
"placeholder-slate-400",
|
|
1013
|
-
"focus-visible:outline-none",
|
|
1014
|
-
], {
|
|
1015
|
-
variants: {
|
|
1016
|
-
size: {
|
|
1017
|
-
small: ["py-1"],
|
|
1018
|
-
medium: ["py-2"],
|
|
1019
|
-
},
|
|
1020
|
-
disabled: {
|
|
1021
|
-
true: ["text-slate-700"],
|
|
1022
|
-
false: "",
|
|
1023
|
-
},
|
|
1024
|
-
},
|
|
1025
|
-
});
|
|
1026
|
-
const cvaInputAddon = cssClassVarianceUtilities.cvaMerge([
|
|
1027
|
-
"flex",
|
|
1028
|
-
"justify-center",
|
|
1029
|
-
"items-center",
|
|
1030
|
-
"px-3",
|
|
1031
|
-
"border-slate-300",
|
|
1032
|
-
"text-slate-500",
|
|
1033
|
-
"bg-slate-50",
|
|
1034
|
-
]);
|
|
1035
|
-
const cvaInputAddonBefore = cssClassVarianceUtilities.cvaMerge([cvaInputAddon(), "border-r", "rounded-l-lg"]);
|
|
1036
|
-
const cvaInputAddonAfter = cssClassVarianceUtilities.cvaMerge([cvaInputAddon(), "border-l", "rounded-r-lg"]);
|
|
1037
|
-
const cvaInputPrefix = cssClassVarianceUtilities.cvaMerge([
|
|
1038
|
-
"flex",
|
|
1039
|
-
"justify-center",
|
|
1040
|
-
"items-center",
|
|
1041
|
-
"text-slate-400",
|
|
1042
|
-
"hover:component-search-prefix",
|
|
1043
|
-
"component-baseInput-prefix",
|
|
1044
|
-
"component-search-borderless",
|
|
1045
|
-
"px-3",
|
|
1046
|
-
], {
|
|
1047
|
-
variants: {
|
|
1048
|
-
disabled: {
|
|
1049
|
-
true: ["text-slate-500"],
|
|
1050
|
-
false: "",
|
|
1051
|
-
},
|
|
1052
|
-
},
|
|
1053
|
-
});
|
|
1054
|
-
const cvaInputSuffix = cssClassVarianceUtilities.cvaMerge(["flex", "justify-center", "items-center", "text-slate-400", "px-3"], {
|
|
1055
|
-
variants: {
|
|
1056
|
-
disabled: {
|
|
1057
|
-
true: ["text-slate-500"],
|
|
1058
|
-
false: "",
|
|
1059
|
-
},
|
|
1060
|
-
},
|
|
1061
|
-
});
|
|
1062
|
-
|
|
1063
|
-
/**
|
|
1064
|
-
* A base input component that can be used for text inputs, password inputs, etc.
|
|
1065
|
-
* A reference to the input element is provided as the `ref` prop.
|
|
1066
|
-
* Extends props from [React.InputHTMLAttributes](https://reactjs.org/docs/dom-elements.html#input)
|
|
1067
|
-
*
|
|
1068
|
-
* For specific input types make sure to use the corresponding input component.
|
|
1069
|
-
* This is a base used by our other input components such as TextInput, NumberInput, PasswordInput, etc.
|
|
1070
|
-
*/
|
|
1071
|
-
const BaseInput = React__namespace.forwardRef((_a, ref) => {
|
|
1072
|
-
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"]);
|
|
1073
|
-
const isReadOnlyWithPlaceholder = React.useMemo(() => !!rest.readOnly && !!rest.placeholder && !rest.value, [rest.readOnly, rest.placeholder, rest.value]);
|
|
1074
|
-
const renderAsDisabled = rest.disabled || rest.readOnly;
|
|
1075
|
-
const innerRef = React__namespace.useRef(null);
|
|
1076
|
-
React__namespace.useImperativeHandle(ref, () => innerRef.current, []);
|
|
1077
|
-
return (jsxRuntime.jsxs("div", { className: cvaInput({
|
|
1078
|
-
disabled: renderAsDisabled,
|
|
1079
|
-
invalid: isInvalid,
|
|
1080
|
-
size: fieldSize,
|
|
1081
|
-
className,
|
|
1082
|
-
}), "data-testid": dataTestId && `${dataTestId}-container`, children: [addonBefore && addonBefore !== undefined ? (jsxRuntime.jsx("div", { className: cvaInputAddonBefore({ className: addonBeforeClassName }), "data-testid": dataTestId && `${dataTestId}-addonBefore`, children: addonBefore })) : null, prefix && addonBefore !== prefix ? (jsxRuntime.jsx("div", { className: cvaInputPrefix({
|
|
1083
|
-
disabled: renderAsDisabled,
|
|
1084
|
-
}), "data-testid": dataTestId && `${dataTestId}-prefix`, children: prefix })) : null, jsxRuntime.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 ? (jsxRuntime.jsx("div", { className: cvaInputSuffix({
|
|
1085
|
-
disabled: renderAsDisabled,
|
|
1086
|
-
}), "data-testid": dataTestId && `${dataTestId}-suffix`, children: suffix })) : null, rest.readOnly === true && showDefaultActions ? (jsxRuntime.jsx(ActionButton, { type: "COPY", value: innerRef }, "default-copy-action")) : null, actions && addonBefore !== actions ? actions : null, addonAfter && addonAfter !== undefined && addonBefore !== addonAfter ? (jsxRuntime.jsx("div", { className: cvaInputAddonAfter(), "data-testid": dataTestId && `${dataTestId}-addonAfter`, children: addonAfter })) : null] }));
|
|
1087
|
-
});
|
|
1088
|
-
|
|
1089
|
-
/**
|
|
1090
|
-
* A wrapper around BaseInput with a pop-up day picker.
|
|
1091
|
-
*
|
|
1092
|
-
* NOTE: If shown with a label, please use the `DateField` component instead.
|
|
1093
|
-
*/
|
|
1094
|
-
const DateInput = React.forwardRef((_a, ref) => {
|
|
1095
|
-
var { min, max, defaultValue, value } = _a, rest = __rest(_a, ["min", "max", "defaultValue", "value"]);
|
|
1096
|
-
const formatDateToInputString = (date) => date instanceof Date ? dateFns.format(date, "yyyy-MM-dd") : date;
|
|
1097
|
-
// Chrome and Firefox need their default icon to have datepicker functionality.
|
|
1098
|
-
const showIcon = !/Chrome/.test(navigator.userAgent) && !/Firefox/.test(navigator.userAgent);
|
|
1099
|
-
return (jsxRuntime.jsx(BaseInput, Object.assign({ defaultValue: formatDateToInputString(defaultValue), max: formatDateToInputString(max), min: formatDateToInputString(min), ref: ref, suffix: showIcon && jsxRuntime.jsx(reactComponents.Icon, { dataTestId: "calendar", name: "Calendar", size: "medium", type: "solid" }), type: "date", value: formatDateToInputString(value) }, rest)));
|
|
1100
|
-
});
|
|
1101
|
-
|
|
1102
|
-
/**
|
|
1103
|
-
* The date field component is used for entering date values.
|
|
1104
|
-
*
|
|
1105
|
-
* _**Do use**_ the DateField for date input.
|
|
1106
|
-
*
|
|
1107
|
-
* _**Do not use**_ this fields for non-serialized dates. Use TextField instead.
|
|
1108
|
-
*/
|
|
1109
|
-
const DateField = React.forwardRef((_a, ref) => {
|
|
1110
|
-
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"]);
|
|
1111
|
-
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
1112
|
-
const htmlForId = id ? id : "dateField-" + uuid.v4();
|
|
1113
|
-
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsxRuntime.jsx(DateInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref }, rest, { className: className, dataTestId: dataTestId })) }));
|
|
1114
|
-
});
|
|
1115
|
-
|
|
1116
|
-
const cvaDropZone = cssClassVarianceUtilities.cvaMerge([
|
|
1117
|
-
"flex",
|
|
1118
|
-
"component-baseInput-background",
|
|
1119
|
-
"justify-center",
|
|
1120
|
-
"text-slate-500",
|
|
1121
|
-
"rounded-sm",
|
|
1122
|
-
"border-2",
|
|
1123
|
-
"border-gray-200",
|
|
1124
|
-
"border-dashed",
|
|
1125
|
-
"hover:bg-slate-100",
|
|
1126
|
-
"hover:border-solid",
|
|
1127
|
-
"hover:border-primary-500",
|
|
1128
|
-
], {
|
|
1129
|
-
variants: {
|
|
1130
|
-
size: {
|
|
1131
|
-
small: ["p-2"],
|
|
1132
|
-
medium: ["p-4"],
|
|
1133
|
-
large: ["p-8"],
|
|
1134
|
-
},
|
|
1135
|
-
disabled: { true: ["bg-slate-100", "hover:bg-slate-100"], false: "" },
|
|
1136
|
-
dragActive: { true: ["border-gray-200", "bg-slate-100"], false: "" },
|
|
1137
|
-
dropComplete: {
|
|
1138
|
-
true: ["border-solid", "border-primary-500", "bg-slate-100", "hover:border-solid", "hover:border-gray-200"],
|
|
1139
|
-
false: "",
|
|
1140
|
-
},
|
|
1141
|
-
invalid: { true: ["border-danger-600", "text-danger-500"], false: "" },
|
|
1142
|
-
},
|
|
1143
|
-
});
|
|
1144
|
-
const cvaDropZoneLabel = cssClassVarianceUtilities.cvaMerge([
|
|
1145
|
-
"h-full",
|
|
1146
|
-
"pt-1",
|
|
1147
|
-
"pb-1",
|
|
1148
|
-
"gap-2",
|
|
1149
|
-
"items-center",
|
|
1150
|
-
"flex-col",
|
|
1151
|
-
"flex",
|
|
1152
|
-
"justify-center",
|
|
1153
|
-
]);
|
|
1154
|
-
|
|
1155
|
-
/**
|
|
1156
|
-
* The Drop Zone can be used to drag and drop files
|
|
1157
|
-
*
|
|
1158
|
-
* @param {DropZoneProps} props - The props for the DropZone component
|
|
1159
|
-
* @returns {JSX.Element} DropZone component
|
|
635
|
+
* @param {DropZoneProps} props - The props for the DropZone component
|
|
636
|
+
* @returns {JSX.Element} DropZone component
|
|
1160
637
|
*/
|
|
1161
638
|
const DropZone = (_a) => {
|
|
1162
639
|
var { className, dataTestId, filesSelected, label, size = "large", isInvalid = false, disabled = false } = _a, rest = __rest(_a, ["className", "dataTestId", "filesSelected", "label", "size", "isInvalid", "disabled"]);
|
|
@@ -1236,178 +713,634 @@ const EmailInput = React__namespace.forwardRef((_a, ref) => {
|
|
|
1236
713
|
});
|
|
1237
714
|
|
|
1238
715
|
/**
|
|
1239
|
-
* The EmailField component is used to enter email.
|
|
1240
|
-
* EmailField validates that user enters a valid email address.
|
|
1241
|
-
*
|
|
716
|
+
* The EmailField component is used to enter email.
|
|
717
|
+
* EmailField validates that user enters a valid email address.
|
|
718
|
+
*
|
|
719
|
+
*/
|
|
720
|
+
const EmailField = React.forwardRef((_a, ref) => {
|
|
721
|
+
var { label, id, tip, helpText, errorMessage, helpAddon, className, defaultValue, dataTestId, value, onChange, isInvalid = false } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "errorMessage", "helpAddon", "className", "defaultValue", "dataTestId", "value", "onChange", "isInvalid"]);
|
|
722
|
+
const htmlForId = id ? id : "emailField-" + uuid.v4();
|
|
723
|
+
// Type guard to check if value is a string
|
|
724
|
+
function isString(inputValue) {
|
|
725
|
+
return typeof inputValue === "string";
|
|
726
|
+
}
|
|
727
|
+
const renderAsInvalid = !!errorMessage || (value && isString(value) && !validateEmailAddress(value)) || isInvalid;
|
|
728
|
+
const handleChange = React.useCallback((event) => {
|
|
729
|
+
if (onChange) {
|
|
730
|
+
onChange(event);
|
|
731
|
+
}
|
|
732
|
+
}, [onChange]);
|
|
733
|
+
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsxRuntime.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 })) }));
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* A thin wrapper around the `BaseInput` component for number input fields.
|
|
738
|
+
*
|
|
739
|
+
* NOTE: If shown with a label, please use the `NumberField` component instead.
|
|
740
|
+
*/
|
|
741
|
+
const NumberInput = React.forwardRef((props, ref) => {
|
|
742
|
+
return jsxRuntime.jsx(BaseInput, Object.assign({ ref: ref, type: "number" }, props, { value: props.value }));
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* The number field component is used for entering numeric values and includes controls for incrementally increasing or decreasing the value.
|
|
747
|
+
*
|
|
748
|
+
* _**Do use**_ the NumberField when the controls to incrementally increase or decrease makes the task easier for the user.
|
|
749
|
+
*
|
|
750
|
+
* _**Do not use**_ this fields for non-serialized numbers. Use TextField instead.
|
|
751
|
+
*/
|
|
752
|
+
const NumberField = React.forwardRef((_a, ref) => {
|
|
753
|
+
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"]);
|
|
754
|
+
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
755
|
+
const htmlForId = id ? id : "numberField-" + uuid.v4();
|
|
756
|
+
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsxRuntime.jsx(NumberInput, Object.assign({ "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, ref: ref, value: value }, rest, { className: className, dataTestId: dataTestId })) }));
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
const cvaOptionCardLabel = cssClassVarianceUtilities.cvaMerge([
|
|
760
|
+
cvaInputBase(),
|
|
761
|
+
"text-center",
|
|
762
|
+
"component-baseInput-background",
|
|
763
|
+
"aspect-square",
|
|
764
|
+
"flex",
|
|
765
|
+
"flex-col",
|
|
766
|
+
"gap-2",
|
|
767
|
+
"justify-center",
|
|
768
|
+
"items-center",
|
|
769
|
+
"p-responsive-space",
|
|
770
|
+
"w-full",
|
|
771
|
+
"peer-checked:bg-primary-50",
|
|
772
|
+
"peer-checked:border-primary-600",
|
|
773
|
+
"peer-checked:border-2",
|
|
774
|
+
], {
|
|
775
|
+
variants: {
|
|
776
|
+
disabled: {
|
|
777
|
+
true: [cvaInputBaseDisabled(), "cursor-not-allowed"],
|
|
778
|
+
false: ["cursor-pointer"],
|
|
779
|
+
},
|
|
780
|
+
},
|
|
781
|
+
});
|
|
782
|
+
const cvaOptionCardContent = cssClassVarianceUtilities.cvaMerge(["flex", "flex-col", "items-center"]);
|
|
783
|
+
const cvaOptionCardContainer = cssClassVarianceUtilities.cvaMerge(["contents"]);
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* A card version of a radio button that includes an icon, headings and a description.
|
|
787
|
+
*/
|
|
788
|
+
const OptionCard = React.forwardRef((_a, ref) => {
|
|
789
|
+
var { icon, heading, subheading, description, disabled, id, value, className, dataTestId } = _a, rest = __rest(_a, ["icon", "heading", "subheading", "description", "disabled", "id", "value", "className", "dataTestId"]);
|
|
790
|
+
const htmlForId = id !== null && id !== void 0 ? id : "option-card-" + uuid.v4();
|
|
791
|
+
return (jsxRuntime.jsxs("div", { className: cvaOptionCardContainer(), "data-testid": dataTestId, children: [jsxRuntime.jsx("input", Object.assign({ className: "peer hidden", id: htmlForId, ref: ref, type: "radio", value: value }, rest)), jsxRuntime.jsxs("label", { className: cvaOptionCardLabel({ className, disabled }), htmlFor: htmlForId, children: [disabled && icon && React.cloneElement(icon, { className: `${icon.props.className} text-secondary-400` }), !disabled && icon, heading && (jsxRuntime.jsx(reactComponents.Heading, { subtle: disabled, variant: "secondary", children: heading })), (subheading || description) && (jsxRuntime.jsxs("div", { className: cvaOptionCardContent(), children: [subheading && (jsxRuntime.jsx(reactComponents.Text, { align: "center", subtle: disabled, type: "span", weight: "thick", children: subheading })), description && (jsxRuntime.jsx(reactComponents.Text, { align: "center", subtle: true, type: "span", children: description }))] }))] })] }));
|
|
792
|
+
});
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* A thin wrapper around the `BaseInput` component for password input fields.
|
|
796
|
+
*
|
|
797
|
+
* NOTE: If shown with a label, please use the `PasswordField` component instead.
|
|
798
|
+
*/
|
|
799
|
+
const PasswordInput = React.forwardRef((props, ref) => (jsxRuntime.jsx(BaseInput, Object.assign({ ref: ref }, props))));
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Password fields enter a password or other confidential information. Characters are masked as they are typed.
|
|
803
|
+
*
|
|
804
|
+
* _**Do use** when the user has to input a password or something that needs to be obfuscated_
|
|
805
|
+
*
|
|
806
|
+
* _**Do not use** to confirm user actions, such as deleting. Use a checkbox for such flows._
|
|
807
|
+
*/
|
|
808
|
+
const PasswordField = React.forwardRef((_a, ref) => {
|
|
809
|
+
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"]);
|
|
810
|
+
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
811
|
+
const htmlFor = id ? id : "passwordField-" + uuid.v4();
|
|
812
|
+
const [showPassword, setShowPassword] = React.useState(false);
|
|
813
|
+
const handleChange = React.useCallback((event) => {
|
|
814
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(event);
|
|
815
|
+
}, [onChange]);
|
|
816
|
+
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsxRuntime.jsx(PasswordInput, Object.assign({}, rest, { actions: jsxRuntime.jsx(reactComponents.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 })) }));
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
/**
|
|
820
|
+
* @param phoneNumber - a phone number as a string
|
|
821
|
+
* @returns {boolean} true if the phone number starts with a plus sign
|
|
822
|
+
* @example checkIfPhoneNumberHasPlus("123456789") // false
|
|
823
|
+
* checkIfPhoneNumberHasPlus("+123456789") // true
|
|
824
|
+
*/
|
|
825
|
+
const checkIfPhoneNumberHasPlus = (phoneNumber) => {
|
|
826
|
+
return phoneNumber.startsWith("+");
|
|
827
|
+
};
|
|
828
|
+
/**
|
|
829
|
+
* @param phoneNumber - a phone number as a string
|
|
830
|
+
* @returns {string|number} the phone number with a plus sign in front of it
|
|
831
|
+
* @example getPhoneNumberWithPlus("123456789") // "+123456789"
|
|
832
|
+
*/
|
|
833
|
+
const getPhoneNumberWithPlus = (phoneNumber) => {
|
|
834
|
+
const stringPhoneNumber = phoneNumber.toString();
|
|
835
|
+
return checkIfPhoneNumberHasPlus(stringPhoneNumber) ? stringPhoneNumber : `+${stringPhoneNumber}`;
|
|
836
|
+
};
|
|
837
|
+
/**
|
|
838
|
+
* Generates a flag emoji based on the given country code.
|
|
839
|
+
*
|
|
840
|
+
* @param {string} countryCode - The two-letter country code (ISO 3166-1 alpha-2).
|
|
841
|
+
* @returns {string} - The corresponding flag emoji for the given country code.
|
|
842
|
+
* @example getPhoneNumberWithPlus("DK") // "🇩🇰"
|
|
843
|
+
*/
|
|
844
|
+
const countryCodeToFlagEmoji = (countryCode) => {
|
|
845
|
+
let code = countryCode;
|
|
846
|
+
if (countryCode.startsWith("+")) {
|
|
847
|
+
code = getCountryAbbreviation(countryCode.substring(1));
|
|
848
|
+
}
|
|
849
|
+
else if (!isNaN(Number(countryCode))) {
|
|
850
|
+
code = getCountryAbbreviation(countryCode);
|
|
851
|
+
}
|
|
852
|
+
return parsePhoneNumberFromString.isSupportedCountry(code.toUpperCase())
|
|
853
|
+
? code.toUpperCase().replace(/./g, char => String.fromCodePoint(127397 + char.charCodeAt(0)))
|
|
854
|
+
: "";
|
|
855
|
+
};
|
|
856
|
+
/**
|
|
857
|
+
* Retrieves the ISO 3166-1 alpha-2 country code associated with a given international calling code.
|
|
858
|
+
*
|
|
859
|
+
* @param {string} callCode - The international calling code for a country.
|
|
860
|
+
* @returns {string} The abbreviation for a country or an empty string if no matching country is found.
|
|
861
|
+
* @example getCountryAbbreviation("45") // "DK"
|
|
862
|
+
* @example getCountryAbbreviation("+45") // "DK"
|
|
863
|
+
*/
|
|
864
|
+
const getCountryAbbreviation = (callCode) => {
|
|
865
|
+
let code = callCode;
|
|
866
|
+
if (callCode.startsWith("+")) {
|
|
867
|
+
code = callCode.substring(1);
|
|
868
|
+
}
|
|
869
|
+
return parsePhoneNumberFromString.getCountries().find(c => parsePhoneNumberFromString.getCountryCallingCode(c) === code) || "";
|
|
870
|
+
};
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* A custom hook for managing phone number input state and validation.
|
|
874
|
+
*
|
|
875
|
+
* @property {Function} getPhoneNumber - A function for get formatted phone number with country code and plus sign
|
|
876
|
+
*/
|
|
877
|
+
const usePhoneInput = () => {
|
|
878
|
+
const getPhoneNumber = ({ country, phone }) => {
|
|
879
|
+
if (country) {
|
|
880
|
+
return getPhoneNumberWithPlus(`${country}${phone || ""}`);
|
|
881
|
+
}
|
|
882
|
+
return phone || "";
|
|
883
|
+
};
|
|
884
|
+
return {
|
|
885
|
+
getPhoneNumber,
|
|
886
|
+
};
|
|
887
|
+
};
|
|
888
|
+
|
|
889
|
+
const cvaSelect = cssClassVarianceUtilities.cvaMerge([
|
|
890
|
+
"relative",
|
|
891
|
+
"flex",
|
|
892
|
+
"shadow-sm",
|
|
893
|
+
"rounded-lg",
|
|
894
|
+
"border",
|
|
895
|
+
"border-slate-300",
|
|
896
|
+
"focus-within:ring-2",
|
|
897
|
+
"focus-within:ring-inset",
|
|
898
|
+
"focus-within:ring-primary-600",
|
|
899
|
+
"focus-within:border-slate-400",
|
|
900
|
+
"hover:border-slate-400",
|
|
901
|
+
"hover:bg-slate-50",
|
|
902
|
+
"bg-white",
|
|
903
|
+
"transition",
|
|
904
|
+
], {
|
|
905
|
+
variants: {
|
|
906
|
+
invalid: {
|
|
907
|
+
true: "border-red-600 text-red-600 focus-within:ring-red-600 hover:border-red-600",
|
|
908
|
+
false: "",
|
|
909
|
+
},
|
|
910
|
+
disabled: {
|
|
911
|
+
true: "!bg-slate-100",
|
|
912
|
+
false: "",
|
|
913
|
+
},
|
|
914
|
+
},
|
|
915
|
+
defaultVariants: {
|
|
916
|
+
invalid: false,
|
|
917
|
+
disabled: false,
|
|
918
|
+
},
|
|
919
|
+
});
|
|
920
|
+
const cvaSelectIcon = cssClassVarianceUtilities.cvaMerge("mr-2 flex cursor-pointer items-center justify-center text-slate-400 hover:text-slate-500");
|
|
921
|
+
const cvaSelectPrefix = cssClassVarianceUtilities.cvaMerge(["flex", "justify-center", "items-center", "text-slate-400", "pl-2"]);
|
|
922
|
+
const cvaSelectXIcon = cssClassVarianceUtilities.cvaMerge([
|
|
923
|
+
"mr-2 flex cursor-pointer items-center justify-center text-slate-400 hover:text-slate-500",
|
|
924
|
+
"ml-1",
|
|
925
|
+
]);
|
|
926
|
+
const cvaSelectMenuList = cssClassVarianceUtilities.cvaMerge(["min-w-min", "shadow-md", "rounded-lg", "z-20", "bg-white", "p-1", "border", "border-slate-300", "gap-1", "grid"], {
|
|
927
|
+
variants: {
|
|
928
|
+
menuIsOpen: {
|
|
929
|
+
true: "animate-fade-in-fast",
|
|
930
|
+
false: "animate-fade-out-fast",
|
|
931
|
+
},
|
|
932
|
+
},
|
|
933
|
+
});
|
|
934
|
+
const cvaSelectDynamicTagContainer = cssClassVarianceUtilities.cvaMerge(["h-full", "flex", "gap-1", "items-center"], {
|
|
935
|
+
variants: {
|
|
936
|
+
visible: { true: "visible", false: "invisible" },
|
|
937
|
+
},
|
|
938
|
+
});
|
|
939
|
+
const cvaSelectCounter = cssClassVarianceUtilities.cvaMerge(["overflow-hidden", "whitespace-nowrap"]);
|
|
940
|
+
const cvaSelectMenu = cssClassVarianceUtilities.cvaMerge(["relative", "p-1", "grid", "gap-1"]);
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* @param {MultiValue<Option> | SingleValue<Option>} arg option to check type
|
|
944
|
+
* @returns {arg is MultiValue<Option> } is Multivalue
|
|
945
|
+
*/
|
|
946
|
+
function isMultiValue(arg) {
|
|
947
|
+
return Array.isArray(arg);
|
|
948
|
+
}
|
|
949
|
+
function isGroupBase(arg) {
|
|
950
|
+
return arg.options !== undefined;
|
|
951
|
+
}
|
|
952
|
+
const isSelectedOption = (option, selected) => {
|
|
953
|
+
if (isGroupBase(option)) {
|
|
954
|
+
return false;
|
|
955
|
+
}
|
|
956
|
+
return isMultiValue(selected)
|
|
957
|
+
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
958
|
+
selected.some(v => v.value === option.value)
|
|
959
|
+
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
960
|
+
option.value === (selected === null || selected === void 0 ? void 0 : selected.value);
|
|
961
|
+
};
|
|
962
|
+
const removeSelectedFromGroups = (group, selected) => {
|
|
963
|
+
if (isGroupBase(group)) {
|
|
964
|
+
return Object.assign(Object.assign({}, group), { options: group.options.filter(option => !isSelectedOption(option, selected)) });
|
|
965
|
+
}
|
|
966
|
+
return group;
|
|
967
|
+
};
|
|
968
|
+
/**
|
|
969
|
+
* @template IsMulti
|
|
970
|
+
* @template Group
|
|
971
|
+
* @param {OptionsOrGroups<Option, Group> | undefined} options An array of options to select from
|
|
972
|
+
* @param {PropsValue<Option> | undefined} value Selected values
|
|
973
|
+
* @returns {OptionsOrGroups<Option, Group>} An array of ordered options with selected on top
|
|
1242
974
|
*/
|
|
1243
|
-
const
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
975
|
+
const getOrderedOptions = (options, value) => {
|
|
976
|
+
if (value && options) {
|
|
977
|
+
const orderedValues = isMultiValue(value)
|
|
978
|
+
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
979
|
+
[...value].sort((a, b) => a.label.localeCompare(b.label))
|
|
980
|
+
: [value];
|
|
981
|
+
const selectableOptions = options
|
|
982
|
+
.filter(option => !isSelectedOption(option, value))
|
|
983
|
+
.map(option => removeSelectedFromGroups(option, value));
|
|
984
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
985
|
+
return orderedValues.concat(selectableOptions) || [];
|
|
1249
986
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
if (onChange) {
|
|
1253
|
-
onChange(event);
|
|
1254
|
-
}
|
|
1255
|
-
}, [onChange]);
|
|
1256
|
-
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsxRuntime.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 })) }));
|
|
1257
|
-
});
|
|
987
|
+
return options || [];
|
|
988
|
+
};
|
|
1258
989
|
|
|
1259
990
|
/**
|
|
1260
|
-
* A
|
|
991
|
+
* A single select menu item is a basic wrapper around Menu item designed to be used as a single value render in Select list
|
|
1261
992
|
*
|
|
1262
|
-
*
|
|
993
|
+
* @param {SelectMenuItemProps} props - The props for the SingleSelectMenuItem
|
|
994
|
+
* @returns {JSX.Element} SingleSelectMenuItem
|
|
1263
995
|
*/
|
|
1264
|
-
const
|
|
1265
|
-
return jsxRuntime.jsx(
|
|
1266
|
-
}
|
|
1267
|
-
|
|
996
|
+
const SingleSelectMenuItem = ({ label, icon, onClick, selected, dataTestId, focused, disabled, }) => {
|
|
997
|
+
return (jsxRuntime.jsx(reactComponents.MenuItem, { dataTestId: dataTestId, disabled: disabled, focused: focused, label: label, onClick: onClick, prefix: icon, selected: selected, suffix: selected ? jsxRuntime.jsx(reactComponents.Icon, { name: "Check", size: "small" }) : undefined }));
|
|
998
|
+
};
|
|
1268
999
|
/**
|
|
1269
|
-
*
|
|
1270
|
-
*
|
|
1271
|
-
* _**Do use**_ the NumberField when the controls to incrementally increase or decrease makes the task easier for the user.
|
|
1000
|
+
* A multi select menu item is a basic wrapper around Menu item designed to be used as a multi value render in Select list
|
|
1272
1001
|
*
|
|
1273
|
-
*
|
|
1274
|
-
|
|
1275
|
-
const NumberField = React.forwardRef((_a, ref) => {
|
|
1276
|
-
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"]);
|
|
1277
|
-
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
1278
|
-
const htmlForId = id ? id : "numberField-" + uuid.v4();
|
|
1279
|
-
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId && `${dataTestId}-FormGroup`, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsxRuntime.jsx(NumberInput, Object.assign({ "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, maxLength: maxLength, ref: ref, value: value }, rest, { className: className, dataTestId: dataTestId })) }));
|
|
1280
|
-
});
|
|
1281
|
-
|
|
1282
|
-
const cvaOptionCardLabel = cssClassVarianceUtilities.cvaMerge([
|
|
1283
|
-
cvaInputBase(),
|
|
1284
|
-
"text-center",
|
|
1285
|
-
"component-baseInput-background",
|
|
1286
|
-
"aspect-square",
|
|
1287
|
-
"flex",
|
|
1288
|
-
"flex-col",
|
|
1289
|
-
"gap-2",
|
|
1290
|
-
"justify-center",
|
|
1291
|
-
"items-center",
|
|
1292
|
-
"p-responsive-space",
|
|
1293
|
-
"w-full",
|
|
1294
|
-
"peer-checked:bg-primary-50",
|
|
1295
|
-
"peer-checked:border-primary-600",
|
|
1296
|
-
"peer-checked:border-2",
|
|
1297
|
-
], {
|
|
1298
|
-
variants: {
|
|
1299
|
-
disabled: {
|
|
1300
|
-
true: [cvaInputBaseDisabled(), "cursor-not-allowed"],
|
|
1301
|
-
false: ["cursor-pointer"],
|
|
1302
|
-
},
|
|
1303
|
-
},
|
|
1304
|
-
});
|
|
1305
|
-
const cvaOptionCardContent = cssClassVarianceUtilities.cvaMerge(["flex", "flex-col", "items-center"]);
|
|
1306
|
-
const cvaOptionCardContainer = cssClassVarianceUtilities.cvaMerge(["contents"]);
|
|
1307
|
-
|
|
1308
|
-
/**
|
|
1309
|
-
* A card version of a radio button that includes an icon, headings and a description.
|
|
1002
|
+
* @param {SelectMenuItemProps} props - The props for the MultiSelectMenuItem
|
|
1003
|
+
* @returns {JSX.Element} multi select menu item
|
|
1310
1004
|
*/
|
|
1311
|
-
const
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
})
|
|
1005
|
+
const MultiSelectMenuItem = ({ label, onClick, selected, dataTestId, focused, disabled, }) => {
|
|
1006
|
+
return (jsxRuntime.jsx(reactComponents.MenuItem, { dataTestId: dataTestId, disabled: disabled, focused: focused, label: label, onClick: e => {
|
|
1007
|
+
e.stopPropagation();
|
|
1008
|
+
onClick && onClick(e);
|
|
1009
|
+
}, prefix: jsxRuntime.jsx(Checkbox, { checked: selected, disabled: disabled, onChange: () => null, onClick: e => {
|
|
1010
|
+
e.stopPropagation();
|
|
1011
|
+
}, readOnly: false }), selected: selected }));
|
|
1012
|
+
};
|
|
1316
1013
|
|
|
1317
1014
|
/**
|
|
1318
|
-
*
|
|
1015
|
+
* Extended Tag component with information about its own width.
|
|
1016
|
+
* Used in the select component.
|
|
1319
1017
|
*
|
|
1320
|
-
*
|
|
1018
|
+
* @param {TagProps} props - The props for the tag component
|
|
1019
|
+
* @returns {JSX.Element} TagWithWidth component
|
|
1321
1020
|
*/
|
|
1322
|
-
const
|
|
1021
|
+
const TagWithWidth = (_a) => {
|
|
1022
|
+
var { onWidthKnown, children } = _a, rest = __rest(_a, ["onWidthKnown", "children"]);
|
|
1023
|
+
const ref = React__default["default"].useRef(null);
|
|
1024
|
+
React__default["default"].useLayoutEffect(() => {
|
|
1025
|
+
var _a;
|
|
1026
|
+
onWidthKnown && onWidthKnown({ width: ((_a = ref.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0 });
|
|
1027
|
+
}, [ref, onWidthKnown]);
|
|
1028
|
+
return (jsxRuntime.jsx(reactComponents.Tag, Object.assign({ ref: ref }, rest, { children: children })));
|
|
1029
|
+
};
|
|
1323
1030
|
|
|
1324
1031
|
/**
|
|
1325
|
-
*
|
|
1326
|
-
*
|
|
1327
|
-
* _**Do use** when the user has to input a password or something that needs to be obfuscated_
|
|
1032
|
+
* TagsContainer component to display tags in limited space when children can't fit space it displays counter
|
|
1328
1033
|
*
|
|
1329
|
-
*
|
|
1034
|
+
* @param {TagsContainerProps} props - The props for the TagContainer
|
|
1035
|
+
* @returns {JSX.Element} TagsContainer
|
|
1330
1036
|
*/
|
|
1331
|
-
const
|
|
1332
|
-
|
|
1333
|
-
const
|
|
1334
|
-
const
|
|
1335
|
-
const
|
|
1336
|
-
const
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1037
|
+
const TagsContainer = ({ items, width = "100%", itemsGap = 5, postFix, disabled }) => {
|
|
1038
|
+
const [isReady, setIsReady] = React__default["default"].useState(false);
|
|
1039
|
+
const [counterWidth, setCounterWidth] = React__default["default"].useState(0);
|
|
1040
|
+
const containerRef = React__default["default"].useRef(null);
|
|
1041
|
+
const availableWidth = React__default["default"].useRef();
|
|
1042
|
+
const childrenWidth = React__default["default"].useRef([]);
|
|
1043
|
+
const itemsCount = items.length;
|
|
1044
|
+
React__default["default"].useLayoutEffect(() => {
|
|
1045
|
+
var _a;
|
|
1046
|
+
availableWidth.current = ((_a = containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0;
|
|
1047
|
+
}, [containerRef]);
|
|
1048
|
+
const onWidthKnownHandler = ({ width: reportedWidth }) => {
|
|
1049
|
+
childrenWidth.current.push({ width: reportedWidth + itemsGap });
|
|
1050
|
+
if (childrenWidth.current.length === itemsCount) {
|
|
1051
|
+
setIsReady(true);
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
const requiredSpace = childrenWidth.current.reduce((previous, current) => {
|
|
1055
|
+
return previous + current.width;
|
|
1056
|
+
}, 0);
|
|
1057
|
+
let counter = 0;
|
|
1058
|
+
const availableSpace = ((availableWidth === null || availableWidth === void 0 ? void 0 : availableWidth.current) || 0) - counterWidth;
|
|
1059
|
+
const renderedElements = items
|
|
1060
|
+
.concat({ text: "", onClick: () => null, disabled: false }) // reserved element for a potential counter
|
|
1061
|
+
.map((item, index) => {
|
|
1062
|
+
const spaceNeeded = childrenWidth.current.slice(0, index + 1).reduce((previous, current) => {
|
|
1063
|
+
return previous + current.width;
|
|
1064
|
+
}, 0);
|
|
1065
|
+
const isLast = index === items.length;
|
|
1066
|
+
const counterRequired = requiredSpace > availableSpace && counter !== 0;
|
|
1067
|
+
if (isLast && counterRequired) {
|
|
1068
|
+
return (jsxRuntime.jsx(TagWithWidth, { color: "white", disabled: disabled, onWidthKnown: ({ width: reportedWidth }) => setCounterWidth(reportedWidth), children: jsxRuntime.jsxs("div", { className: cvaSelectCounter(), "data-testid": "select-counter", children: ["+", counter] }) }, item.text + index));
|
|
1069
|
+
}
|
|
1070
|
+
if (isLast) {
|
|
1071
|
+
return null;
|
|
1072
|
+
}
|
|
1073
|
+
const itemCanFit = spaceNeeded <= availableSpace;
|
|
1074
|
+
if (itemCanFit) {
|
|
1075
|
+
return (jsxRuntime.jsx(TagWithWidth, { className: "inline-flex shrink-0", color: item.disabled ? "unknown" : "primary", dataTestId: `${item.text}-tag`, disabled: disabled, onClose: e => {
|
|
1076
|
+
e.stopPropagation();
|
|
1077
|
+
item.onClick();
|
|
1078
|
+
}, onWidthKnown: onWidthKnownHandler, children: item.text }, item.text + index));
|
|
1079
|
+
}
|
|
1080
|
+
const fromTheItems = item.text !== "";
|
|
1081
|
+
if (fromTheItems) {
|
|
1082
|
+
counter = counter + 1;
|
|
1083
|
+
}
|
|
1084
|
+
return null;
|
|
1085
|
+
})
|
|
1086
|
+
.filter(element => element !== null);
|
|
1087
|
+
return (jsxRuntime.jsxs("div", { className: cvaSelectDynamicTagContainer({ visible: isReady }), ref: containerRef, style: {
|
|
1088
|
+
width: `${width}`,
|
|
1089
|
+
}, children: [renderedElements, postFix] }));
|
|
1090
|
+
};
|
|
1341
1091
|
|
|
1342
1092
|
/**
|
|
1343
|
-
*
|
|
1344
|
-
*
|
|
1345
|
-
*
|
|
1346
|
-
*
|
|
1093
|
+
* A hook to retrieve components override object.
|
|
1094
|
+
* 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.
|
|
1095
|
+
*
|
|
1096
|
+
* @template IsMulti
|
|
1097
|
+
* @template Group
|
|
1098
|
+
* @param {Partial<SelectComponents<Option, IsMulti, Group>> | undefined} componentsProps a custom component prop that you can to override defaults
|
|
1099
|
+
* @param {boolean} disabled decide to override disabled variant
|
|
1100
|
+
* @param {boolean} menuIsOpen menu is open state
|
|
1101
|
+
* @param {React.MutableRefObject<boolean>} refMenuIsEnabled a flag to block menu from open
|
|
1102
|
+
* @param {string} dataTestId a test id
|
|
1103
|
+
* @param {number} maxSelectedDisplayCount a number of max display count
|
|
1104
|
+
* @param {JSX.Element} dropdownIcon an custom dropdown icon
|
|
1105
|
+
* @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
|
|
1347
1106
|
*/
|
|
1348
|
-
const
|
|
1349
|
-
|
|
1107
|
+
const useCustomComponents = (componentsProps, disabled, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon) => {
|
|
1108
|
+
const [t] = useTranslation();
|
|
1109
|
+
// perhaps it should not be wrap in memo (causing some issues with opening and closing on mobiles)
|
|
1110
|
+
const customComponents = React__namespace.useMemo(() => {
|
|
1111
|
+
return Object.assign({ ValueContainer: props => {
|
|
1112
|
+
if (props.isMulti && Array.isArray(props.children) && props.children.length > 0) {
|
|
1113
|
+
const PLACEHOLDER_KEY = "placeholder";
|
|
1114
|
+
const key = props && props.children && props.children[0] ? props.children[0].key : "";
|
|
1115
|
+
const values = props && props.children ? props.children[0] : [];
|
|
1116
|
+
const tags = key === PLACEHOLDER_KEY ? [] : values;
|
|
1117
|
+
const searchInput = props && props.children && props.children[1];
|
|
1118
|
+
return (jsxRuntime.jsx(ReactSelect.components.ValueContainer, Object.assign({}, props, { isDisabled: props.selectProps.isDisabled, children: maxSelectedDisplayCount === undefined ? (jsxRuntime.jsx(TagsContainer, { disabled: disabled, items: tags
|
|
1119
|
+
? tags.map(({ props: tagProps }) => {
|
|
1120
|
+
return {
|
|
1121
|
+
text: tagProps.children,
|
|
1122
|
+
onClick: disabled
|
|
1123
|
+
? undefined
|
|
1124
|
+
: (e) => {
|
|
1125
|
+
var _a, _b;
|
|
1126
|
+
refMenuIsEnabled.current = false;
|
|
1127
|
+
((_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));
|
|
1128
|
+
},
|
|
1129
|
+
disabled: disabled,
|
|
1130
|
+
};
|
|
1131
|
+
})
|
|
1132
|
+
: [], postFix: searchInput, width: "100%" })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [tags &&
|
|
1133
|
+
tags.slice(0, maxSelectedDisplayCount).map(({ props: tagProps }) => {
|
|
1134
|
+
var _a, _b;
|
|
1135
|
+
return (jsxRuntime.jsx(reactComponents.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 => {
|
|
1136
|
+
var _a, _b;
|
|
1137
|
+
e.stopPropagation();
|
|
1138
|
+
refMenuIsEnabled.current = false;
|
|
1139
|
+
((_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));
|
|
1140
|
+
}, children: tagProps.children }, (_b = tagProps.children) === null || _b === void 0 ? void 0 : _b.toString()));
|
|
1141
|
+
}), tags && tags.length > maxSelectedDisplayCount && (jsxRuntime.jsxs(reactComponents.Tag, { color: "neutral", dataTestId: "counter-tag", children: ["+", tags.length - maxSelectedDisplayCount] })), searchInput] })) })));
|
|
1142
|
+
}
|
|
1143
|
+
return (jsxRuntime.jsx(ReactSelect.components.ValueContainer, Object.assign({}, props, { isDisabled: props.selectProps.isDisabled, children: props.children })));
|
|
1144
|
+
}, LoadingIndicator: props => {
|
|
1145
|
+
return jsxRuntime.jsx(reactComponents.Spinner, { className: "mt-1.5 mr-1", size: "small" });
|
|
1146
|
+
}, DropdownIndicator: props => {
|
|
1147
|
+
const icon = props.selectProps.menuIsOpen ? (jsxRuntime.jsx(reactComponents.Icon, { name: "ChevronUp", size: "medium" })) : (jsxRuntime.jsx(reactComponents.Icon, { name: "ChevronDown", size: "medium" }));
|
|
1148
|
+
return props.selectProps.isLoading ? null : (jsxRuntime.jsx(ReactSelect.components.DropdownIndicator, Object.assign({}, props, { children: jsxRuntime.jsx("div", { className: cvaSelectIcon(), children: dropdownIcon ? dropdownIcon : icon }) })));
|
|
1149
|
+
}, IndicatorSeparator: () => null, ClearIndicator: props => {
|
|
1150
|
+
if (disabled) {
|
|
1151
|
+
return null;
|
|
1152
|
+
}
|
|
1153
|
+
return (jsxRuntime.jsx(ReactSelect.components.ClearIndicator, Object.assign({}, props, { children: jsxRuntime.jsx("div", { className: cvaSelectXIcon(), "data-testid": dataTestId && `${dataTestId}-XMarkIcon`, onClick: props.clearValue, children: jsxRuntime.jsx(reactComponents.Icon, { name: "XCircle", size: "medium", title: t("clearIndicator.icon.tooltip.clearAll") }) }) })));
|
|
1154
|
+
}, Control: props => {
|
|
1155
|
+
return jsxRuntime.jsx(ReactSelect.components.Control, Object.assign({}, props, { className: props.isDisabled ? "bg-slate-100" : "" }));
|
|
1156
|
+
}, SingleValue: props => {
|
|
1157
|
+
return (jsxRuntime.jsx(ReactSelect.components.SingleValue, Object.assign({}, props, { className: props.isDisabled ? "text-slate-700" : "", children: jsxRuntime.jsx("div", { "data-testid": dataTestId + "-singleValue", children: props.children }) })));
|
|
1158
|
+
}, Menu: props => {
|
|
1159
|
+
return (jsxRuntime.jsx(ReactSelect.components.Menu, Object.assign({}, props, { className: cvaSelectMenuList({ menuIsOpen: props.selectProps.menuIsOpen }) })));
|
|
1160
|
+
}, MenuList: props => {
|
|
1161
|
+
return (jsxRuntime.jsx(ReactSelect.components.MenuList, Object.assign({}, props, { innerProps: Object.assign(Object.assign({}, props.innerProps), { onScroll: e => {
|
|
1162
|
+
const listEl = e.currentTarget;
|
|
1163
|
+
if (listEl.scrollTop + listEl.clientHeight >= listEl.scrollHeight) {
|
|
1164
|
+
props.selectProps.onMenuScrollToBottom && props.selectProps.onMenuScrollToBottom(new TouchEvent(""));
|
|
1165
|
+
}
|
|
1166
|
+
} }), children: props.children })));
|
|
1167
|
+
}, Option: props => {
|
|
1168
|
+
const componentProps = {
|
|
1169
|
+
label: props.label,
|
|
1170
|
+
focused: props.isFocused,
|
|
1171
|
+
selected: props.isSelected,
|
|
1172
|
+
onClick: props.innerProps.onClick,
|
|
1173
|
+
};
|
|
1174
|
+
return (jsxRuntime.jsx(ReactSelect.components.Option, Object.assign({}, props, { innerProps: Object.assign(Object.assign({}, props.innerProps), { role: "option", onClick: () => { } }), children: props.isMulti ? (jsxRuntime.jsx(MultiSelectMenuItem, Object.assign({}, componentProps, { dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled }))) : (jsxRuntime.jsx(SingleSelectMenuItem, Object.assign({}, componentProps, { dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled || props.isDisabled }))) })));
|
|
1175
|
+
} }, componentsProps);
|
|
1176
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1177
|
+
}, [componentsProps, disabled, maxSelectedDisplayCount]); // do not add dropdownIcon (it will cause issue with opening/closing list for selects with custom icon)
|
|
1178
|
+
return customComponents;
|
|
1350
1179
|
};
|
|
1180
|
+
|
|
1351
1181
|
/**
|
|
1352
|
-
* @
|
|
1353
|
-
* @
|
|
1354
|
-
* @
|
|
1182
|
+
* @template IsMulti
|
|
1183
|
+
* @template Group
|
|
1184
|
+
* @param {React.RefObject<HTMLDivElement>} refContainer react ref to container element
|
|
1185
|
+
* @param {React.RefObject<HTMLDivElement>} refPrefix react ref to prefix element
|
|
1186
|
+
* @param {number | undefined} maxSelectedDisplayCount a number of max display count
|
|
1187
|
+
* @param {StylesConfig<Option, IsMulti, Group> | undefined} styles a optional object to override styles of react-select
|
|
1188
|
+
* @returns {StylesConfig<Option, boolean>} styles to override in select
|
|
1355
1189
|
*/
|
|
1356
|
-
const
|
|
1357
|
-
const
|
|
1358
|
-
|
|
1190
|
+
const useCustomStyles = (refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled) => {
|
|
1191
|
+
const customStyles = React__namespace.useMemo(() => {
|
|
1192
|
+
return Object.assign({ control: base => {
|
|
1193
|
+
return Object.assign(Object.assign({}, base), { border: "0", boxShadow: "0", "&:hover": {
|
|
1194
|
+
border: "0",
|
|
1195
|
+
}, marginRight: "2px", backgroundColor: "" });
|
|
1196
|
+
}, 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: () => ({
|
|
1197
|
+
width: "0px",
|
|
1198
|
+
}), menu: base => {
|
|
1199
|
+
return Object.assign(Object.assign({}, base), { width: "100%", marginTop: "4px", marginBottom: "18px", transition: "all 1s ease-in-out" });
|
|
1200
|
+
}, 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 => {
|
|
1201
|
+
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" });
|
|
1202
|
+
}, valueContainer: base => {
|
|
1203
|
+
return Object.assign(Object.assign({}, base), { flexWrap: maxSelectedDisplayCount !== undefined ? "wrap" : "nowrap", gap: "0.25rem" });
|
|
1204
|
+
}, 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 => {
|
|
1205
|
+
return Object.assign(Object.assign({}, base), { padding: "0px" });
|
|
1206
|
+
} }, styles);
|
|
1207
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1208
|
+
}, [refContainer, refPrefix]);
|
|
1209
|
+
return { customStyles };
|
|
1359
1210
|
};
|
|
1211
|
+
|
|
1360
1212
|
/**
|
|
1361
|
-
*
|
|
1213
|
+
* A hook used by selects to share the common code
|
|
1362
1214
|
*
|
|
1363
|
-
* @param {
|
|
1364
|
-
* @returns {
|
|
1365
|
-
* @example getPhoneNumberWithPlus("DK") // "🇩🇰"
|
|
1215
|
+
* @param {SelectProps} props - The props for the Select component
|
|
1216
|
+
* @returns {IUseSelect} Select component
|
|
1366
1217
|
*/
|
|
1367
|
-
const
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1218
|
+
const useSelect = (_a) => {
|
|
1219
|
+
var _b;
|
|
1220
|
+
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"]);
|
|
1221
|
+
const refContainer = React__default["default"].useRef(null);
|
|
1222
|
+
const refPrefix = React__default["default"].useRef(null);
|
|
1223
|
+
const { customStyles } = useCustomStyles(refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled);
|
|
1224
|
+
const [menuIsOpen, setMenuIsOpen] = React__default["default"].useState((_b = props.menuIsOpen) !== null && _b !== void 0 ? _b : false);
|
|
1225
|
+
const refMenuIsEnabled = React__default["default"].useRef(true);
|
|
1226
|
+
const customComponents = useCustomComponents(components, disabled || false, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon);
|
|
1227
|
+
const menuPlacement = "auto";
|
|
1228
|
+
const openMenuHandler = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1229
|
+
onMenuOpen && onMenuOpen();
|
|
1230
|
+
if (refMenuIsEnabled.current) {
|
|
1231
|
+
setMenuIsOpen(true);
|
|
1232
|
+
}
|
|
1233
|
+
else {
|
|
1234
|
+
refMenuIsEnabled.current = true;
|
|
1235
|
+
}
|
|
1236
|
+
});
|
|
1237
|
+
const closeMenuHandler = () => {
|
|
1238
|
+
setMenuIsOpen(false);
|
|
1239
|
+
onMenuClose && onMenuClose();
|
|
1240
|
+
};
|
|
1241
|
+
const orderedOptions = React__default["default"].useMemo(() => {
|
|
1242
|
+
return disabled
|
|
1243
|
+
? getOrderedOptions(options, value).map(option => {
|
|
1244
|
+
return Object.assign(Object.assign({}, option), { disabled: true });
|
|
1245
|
+
})
|
|
1246
|
+
: getOrderedOptions(options, value);
|
|
1247
|
+
}, [options, value, disabled]);
|
|
1248
|
+
return {
|
|
1249
|
+
refContainer,
|
|
1250
|
+
refPrefix,
|
|
1251
|
+
customStyles,
|
|
1252
|
+
menuIsOpen,
|
|
1253
|
+
customComponents,
|
|
1254
|
+
menuPlacement,
|
|
1255
|
+
openMenuHandler,
|
|
1256
|
+
closeMenuHandler,
|
|
1257
|
+
orderedOptions,
|
|
1258
|
+
};
|
|
1378
1259
|
};
|
|
1260
|
+
|
|
1379
1261
|
/**
|
|
1380
|
-
*
|
|
1262
|
+
* CreatableSelects are input components used to choose a value from a set.
|
|
1381
1263
|
*
|
|
1382
|
-
* @param {
|
|
1383
|
-
* @returns {
|
|
1384
|
-
* @example getCountryAbbreviation("45") // "DK"
|
|
1385
|
-
* @example getCountryAbbreviation("+45") // "DK"
|
|
1264
|
+
* @param {CreatableSelectProps} props - The props for the CreatableSelect component
|
|
1265
|
+
* @returns {JSX.Element} CreatableSelect component
|
|
1386
1266
|
*/
|
|
1387
|
-
const
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1267
|
+
const CreatableSelect = (props) => {
|
|
1268
|
+
const { className } = props, propsNoClassName = __rest(props, ["className"]);
|
|
1269
|
+
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;
|
|
1270
|
+
const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
|
|
1271
|
+
const creatableSelectProps = {
|
|
1272
|
+
value,
|
|
1273
|
+
menuPlacement,
|
|
1274
|
+
maxMenuHeight,
|
|
1275
|
+
onChange,
|
|
1276
|
+
"aria-label": label,
|
|
1277
|
+
"data-testid": dataTestId,
|
|
1278
|
+
components: customComponents,
|
|
1279
|
+
styles: customStyles,
|
|
1280
|
+
tabSelectsValue: false,
|
|
1281
|
+
blurInputOnSelect: !isMulti,
|
|
1282
|
+
menuPortalTarget: props.menuPortalTarget || document.body,
|
|
1283
|
+
isSearchable: disabled || readOnly ? false : isSearchable,
|
|
1284
|
+
menuShouldBlockScroll: true,
|
|
1285
|
+
menuShouldScrollIntoView: true,
|
|
1286
|
+
openMenuOnFocus: true,
|
|
1287
|
+
menuIsOpen: !readOnly ? menuIsOpen : false,
|
|
1288
|
+
openMenuOnClick: true,
|
|
1289
|
+
closeMenuOnSelect: false,
|
|
1290
|
+
isMulti,
|
|
1291
|
+
classNamePrefix,
|
|
1292
|
+
isLoading,
|
|
1293
|
+
isClearable,
|
|
1294
|
+
id,
|
|
1295
|
+
onMenuScrollToBottom,
|
|
1296
|
+
onInputChange,
|
|
1297
|
+
allowCreateWhileLoading,
|
|
1298
|
+
onCreateOption,
|
|
1299
|
+
};
|
|
1300
|
+
return (jsxRuntime.jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: disabled || readOnly, className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined && (jsxRuntime.jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId && `${dataTestId}-prefix`, ref: refPrefix, children: prefix })), async ? (jsxRuntime.jsx(ReactAsyncCreatableSelect__default["default"], Object.assign({}, propsNoClassName, creatableSelectProps, async, { onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler }))) : (jsxRuntime.jsx(ReactCreatableSelect__default["default"], Object.assign({}, propsNoClassName, creatableSelectProps, { hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : options })))] }));
|
|
1393
1301
|
};
|
|
1302
|
+
CreatableSelect.displayName = "CreatableSelect";
|
|
1394
1303
|
|
|
1395
1304
|
/**
|
|
1396
|
-
*
|
|
1305
|
+
* Selects are input components used to choose a value from a set.
|
|
1397
1306
|
*
|
|
1398
|
-
*
|
|
1307
|
+
* @param {SelectProps} props - The props for the Select component
|
|
1308
|
+
* @returns {JSX.Element} Select component
|
|
1399
1309
|
*/
|
|
1400
|
-
const
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1310
|
+
const Select = (props) => {
|
|
1311
|
+
const { className } = props, propsNoClassName = __rest(props, ["className"]);
|
|
1312
|
+
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;
|
|
1313
|
+
const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
|
|
1314
|
+
const selectProps = {
|
|
1315
|
+
value,
|
|
1316
|
+
menuPlacement,
|
|
1317
|
+
maxMenuHeight,
|
|
1318
|
+
onChange,
|
|
1319
|
+
"aria-label": label,
|
|
1320
|
+
"data-testid": dataTestId,
|
|
1321
|
+
components: customComponents,
|
|
1322
|
+
styles: customStyles,
|
|
1323
|
+
tabSelectsValue: false,
|
|
1324
|
+
blurInputOnSelect: !isMulti,
|
|
1325
|
+
menuPortalTarget: props.menuPortalTarget || document.body,
|
|
1326
|
+
isSearchable: disabled || readOnly ? false : isSearchable,
|
|
1327
|
+
menuShouldBlockScroll: true,
|
|
1328
|
+
menuShouldScrollIntoView: true,
|
|
1329
|
+
openMenuOnFocus,
|
|
1330
|
+
menuIsOpen: !readOnly ? menuIsOpen : false,
|
|
1331
|
+
openMenuOnClick,
|
|
1332
|
+
closeMenuOnSelect: false,
|
|
1333
|
+
isMulti,
|
|
1334
|
+
classNamePrefix,
|
|
1335
|
+
isLoading,
|
|
1336
|
+
isClearable,
|
|
1337
|
+
id,
|
|
1338
|
+
onMenuScrollToBottom,
|
|
1339
|
+
onInputChange,
|
|
1409
1340
|
};
|
|
1341
|
+
return (jsxRuntime.jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: disabled || readOnly, className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined && (jsxRuntime.jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId && `${dataTestId}-prefix`, ref: refPrefix, children: prefix })), async ? (jsxRuntime.jsx(ReactAsyncSelect__default["default"], Object.assign({}, propsNoClassName, selectProps, async, { onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler }))) : (jsxRuntime.jsx(ReactSelect__default["default"], Object.assign({}, propsNoClassName, selectProps, { hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : options })))] }));
|
|
1410
1342
|
};
|
|
1343
|
+
Select.displayName = "Select";
|
|
1411
1344
|
|
|
1412
1345
|
const COUNTRY_CODES_NOT_SUPPORTED_BY_BACKEND = ["+53", "+98", "+211", "+247", "+249", "+383", "+850", "+963"];
|
|
1413
1346
|
const ADDITIONAL_COUNTRY_CODES_SUPPORTED_BY_BACKEND = [
|
|
@@ -2030,6 +1963,71 @@ const Search = React.forwardRef((_a, ref) => {
|
|
|
2030
1963
|
}, children: jsxRuntime.jsx(reactComponents.Icon, { name: "XMark", size: "small" }) })) : undefined, value: value })));
|
|
2031
1964
|
});
|
|
2032
1965
|
|
|
1966
|
+
const FormFieldSelectAdapter = React.forwardRef((_a, ref) => {
|
|
1967
|
+
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"]);
|
|
1968
|
+
const [innerValue, setInnerValue] = React.useState(value || defaultValue);
|
|
1969
|
+
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
1970
|
+
const htmlFor = React.useMemo(() => (id ? id : "selectField-" + uuid.v4()), [id]);
|
|
1971
|
+
const innerRef = React.useRef(null);
|
|
1972
|
+
React.useImperativeHandle(ref, () => innerRef.current, []);
|
|
1973
|
+
const handleChange = React.useCallback((newValue) => {
|
|
1974
|
+
setInnerValue(newValue === null || newValue === void 0 ? void 0 : newValue.value);
|
|
1975
|
+
}, []);
|
|
1976
|
+
React.useEffect(() => {
|
|
1977
|
+
var _a;
|
|
1978
|
+
if (!innerValue) {
|
|
1979
|
+
return;
|
|
1980
|
+
}
|
|
1981
|
+
const event = new Event("change");
|
|
1982
|
+
(_a = innerRef.current) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
|
|
1983
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(event);
|
|
1984
|
+
}, [onChange, innerValue]);
|
|
1985
|
+
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); });
|
|
1986
|
+
const defaultSelectedOption = options.find(option => option.value === defaultValue);
|
|
1987
|
+
return (jsxRuntime.jsxs(FormGroup, { isInvalid: renderAsInvalid,
|
|
1988
|
+
htmlFor,
|
|
1989
|
+
className,
|
|
1990
|
+
dataTestId,
|
|
1991
|
+
helpText,
|
|
1992
|
+
helpAddon,
|
|
1993
|
+
tip,
|
|
1994
|
+
label,
|
|
1995
|
+
disabled, children: [jsxRuntime.jsx("select", { onChange, ref: innerRef, name, value: innerValue, hidden: true, children: options.map(option => {
|
|
1996
|
+
return (jsxRuntime.jsx("option", { value: option.value, children: option.label }, option.value));
|
|
1997
|
+
}) }), children(Object.assign({ id, isDisabled: disabled, onBlur,
|
|
1998
|
+
options, onChange: handleChange, value: selectedOption, defaultValue: defaultSelectedOption }, rest))] }));
|
|
1999
|
+
});
|
|
2000
|
+
|
|
2001
|
+
/**
|
|
2002
|
+
* The CreatableSelectField component is a CreatableSelect component wrapped in the FromGroup component.
|
|
2003
|
+
*
|
|
2004
|
+
* This means that it can easily be added to any form alongside other Field components.
|
|
2005
|
+
*
|
|
2006
|
+
* This is done to make the field compatible with the React-hook-form library.
|
|
2007
|
+
*
|
|
2008
|
+
* @param {SelectFieldProps & CreatableSelectProps} props - The props for the CreatableSelectField component
|
|
2009
|
+
* @returns {JSX.Element} CreatableSelectField component
|
|
2010
|
+
*/
|
|
2011
|
+
const CreatableSelectField = (_a) => {
|
|
2012
|
+
var { allowCreateWhileLoading, onCreateOption } = _a, props = __rest(_a, ["allowCreateWhileLoading", "onCreateOption"]);
|
|
2013
|
+
const creatableSelectOnlyProps = { allowCreateWhileLoading, onCreateOption };
|
|
2014
|
+
return (jsxRuntime.jsx(FormFieldSelectAdapter, Object.assign({}, props, { children: convertedProps => jsxRuntime.jsx(CreatableSelect, Object.assign({}, convertedProps, creatableSelectOnlyProps)) })));
|
|
2015
|
+
};
|
|
2016
|
+
|
|
2017
|
+
/**
|
|
2018
|
+
* The SelectField component is a Select component wrapped in the FromGroup component.
|
|
2019
|
+
*
|
|
2020
|
+
* This means that it can easily be added to any form alongside other Field components.
|
|
2021
|
+
*
|
|
2022
|
+
* This is done to make the field compatible with the React-hook-form library.
|
|
2023
|
+
*
|
|
2024
|
+
* @param {SelectFieldProps} props - The props for the SelectField component
|
|
2025
|
+
* @returns {JSX.Element} SelectField component
|
|
2026
|
+
*/
|
|
2027
|
+
const SelectField = (props) => {
|
|
2028
|
+
return jsxRuntime.jsx(FormFieldSelectAdapter, Object.assign({}, props, { children: convertedProps => jsxRuntime.jsx(Select, Object.assign({}, convertedProps)) }));
|
|
2029
|
+
};
|
|
2030
|
+
|
|
2033
2031
|
const cvaTextArea = cssClassVarianceUtilities.cvaMerge([
|
|
2034
2032
|
cvaInputBase(),
|
|
2035
2033
|
"block",
|
|
@@ -2309,6 +2307,7 @@ exports.ActionButton = ActionButton;
|
|
|
2309
2307
|
exports.BaseInput = BaseInput;
|
|
2310
2308
|
exports.Checkbox = Checkbox;
|
|
2311
2309
|
exports.CreatableSelect = CreatableSelect;
|
|
2310
|
+
exports.CreatableSelectField = CreatableSelectField;
|
|
2312
2311
|
exports.DateField = DateField;
|
|
2313
2312
|
exports.DateInput = DateInput;
|
|
2314
2313
|
exports.DropZone = DropZone;
|