@trackunit/react-form-components 1.0.29 → 1.0.30
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 +220 -133
- package/index.esm.js +222 -134
- package/package.json +2 -2
- package/src/components/ActionButton/ActionButton.d.ts +1 -7
- package/src/components/ActionButton/ActionButton.variants.d.ts +4 -2
- package/src/components/BaseInput/BaseInput.d.ts +26 -30
- package/src/components/BaseInput/BaseInput.variants.d.ts +9 -7
- package/src/components/BaseInput/InputLockReasonTooltip.d.ts +15 -0
- package/src/components/BaseInput/components/AddonAfterRenderer.d.ts +7 -0
- package/src/components/BaseInput/components/AddonBeforeRenderer.d.ts +7 -0
- package/src/components/BaseInput/components/GenericActionsRenderer.d.ts +8 -0
- package/src/components/BaseInput/components/LockReasonRenderer.d.ts +5 -0
- package/src/components/BaseInput/components/PrefixRenderer.d.ts +8 -0
- package/src/components/BaseInput/components/SuffixRenderer.d.ts +10 -0
- package/src/components/BaseInput/components/index.d.ts +6 -0
- package/src/components/EmailInput/EmailInput.d.ts +1 -2
- package/src/components/FormGroup/FormGroup.d.ts +6 -1
- package/src/components/FormGroup/FormGroup.variants.d.ts +1 -0
- package/src/components/PhoneInput/PhoneInput.d.ts +3 -3
- package/src/components/Select/Select.variants.d.ts +1 -0
- package/src/components/Select/SelectMenuItem/SelectMenuItem.d.ts +7 -2
- package/src/components/Select/useCustomComponents.d.ts +3 -1
- package/src/components/Select/useCustomStyles.d.ts +3 -1
- package/src/components/Select/useSelect.d.ts +10 -3
- package/src/components/TextField/TextField.d.ts +0 -4
- package/src/components/UploadInput/UploadInput.variants.d.ts +0 -1
- package/src/translation.d.ts +2 -2
- package/src/types.d.ts +1 -0
- package/src/components/BaseInput/DisabledForReasonsTip.d.ts +0 -15
package/index.cjs.js
CHANGED
|
@@ -37,6 +37,7 @@ function _interopNamespaceDefault(e) {
|
|
|
37
37
|
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
38
38
|
|
|
39
39
|
var defaultTranslations = {
|
|
40
|
+
"baseInput.copyAction.toolTip": "Copy value",
|
|
40
41
|
"clearIndicator.icon.tooltip.clearAll": "Clear all",
|
|
41
42
|
"colorField.error.INVALID_HEX_CODE": "Please enter a valid HEX code",
|
|
42
43
|
"colorField.error.REQUIRED": "This field is required",
|
|
@@ -116,15 +117,30 @@ const setupLibraryTranslations = () => {
|
|
|
116
117
|
const cvaActionButton = cssClassVarianceUtilities.cvaMerge(["drop-shadow-none", "rounded-md"], {
|
|
117
118
|
variants: {
|
|
118
119
|
size: {
|
|
119
|
-
small: ["w-6", "h-6"],
|
|
120
|
-
medium: ["w-
|
|
120
|
+
small: ["w-6", "h-6", "min-h-0"],
|
|
121
|
+
medium: ["w-6", "h-6", "min-h-0"],
|
|
122
|
+
large: ["w-8", "h-8"],
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
defaultVariants: {
|
|
126
|
+
size: "medium",
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
const cvaActionContainer = cssClassVarianceUtilities.cvaMerge(["flex", "items-center"], {
|
|
130
|
+
variants: {
|
|
131
|
+
size: {
|
|
132
|
+
//I just measured manually the top/bottom spacing
|
|
133
|
+
//when using the action button inside an input
|
|
134
|
+
//might need tweaking in the future
|
|
135
|
+
small: ["m-[1px]"],
|
|
136
|
+
medium: ["m-[3px]"],
|
|
137
|
+
large: ["m-[3px]"],
|
|
121
138
|
},
|
|
122
139
|
},
|
|
123
140
|
defaultVariants: {
|
|
124
141
|
size: "medium",
|
|
125
142
|
},
|
|
126
143
|
});
|
|
127
|
-
const cvaActionContainer = cssClassVarianceUtilities.cvaMerge(["flex", "items-center", "m-1"]);
|
|
128
144
|
|
|
129
145
|
/**
|
|
130
146
|
* The ActionButton component is a wrapper over IconButton to perform an action when the onClick event is triggered.
|
|
@@ -132,7 +148,7 @@ const cvaActionContainer = cssClassVarianceUtilities.cvaMerge(["flex", "items-ce
|
|
|
132
148
|
* @param {ActionButtonProps} props - The props for the ActionButton component
|
|
133
149
|
* @returns {JSX.Element} ActionButton component
|
|
134
150
|
*/
|
|
135
|
-
const ActionButton = ({ type, value, dataTestId,
|
|
151
|
+
const ActionButton = ({ type, value, dataTestId, size, disabled, className }) => {
|
|
136
152
|
const [, copyToClipboard] = usehooksTs.useCopyToClipboard();
|
|
137
153
|
const getIconName = () => {
|
|
138
154
|
switch (type) {
|
|
@@ -161,52 +177,12 @@ const ActionButton = ({ type, value, dataTestId, iconSize, disabled, className }
|
|
|
161
177
|
case "COPY":
|
|
162
178
|
// Typescript seems to be unable to detect RefObject
|
|
163
179
|
// as one of the members of the union RefObject | string | null which gives access to the `current` property
|
|
164
|
-
// eslint-disable-next-line react/prop-types
|
|
165
180
|
return copyToClipboard(value?.current?.value ?? "");
|
|
166
181
|
default:
|
|
167
182
|
return null;
|
|
168
183
|
}
|
|
169
184
|
};
|
|
170
|
-
return (jsxRuntime.jsx("div", { className: cvaActionContainer({ className }), children: jsxRuntime.jsx(reactComponents.IconButton, { className: cvaActionButton({ size
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Used to compare two React nodes for deep equality.
|
|
175
|
-
*/
|
|
176
|
-
const compareReactNodes = (node1, node2) => {
|
|
177
|
-
// Base case: If both objects are identical, return true.
|
|
178
|
-
if (node1 === node2) {
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
|
-
// Check if both objects are valid React elements.
|
|
182
|
-
if (React.isValidElement(node1) && React.isValidElement(node2)) {
|
|
183
|
-
const { type: type1, props: props1, key: key1 } = node1;
|
|
184
|
-
const { type: type2, props: props2, key: key2 } = node2;
|
|
185
|
-
if (type1 !== type2 || key1 !== key2) {
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
return compareReactNodes(props1, props2);
|
|
189
|
-
}
|
|
190
|
-
// Check if both objects are objects and not null.
|
|
191
|
-
if (typeof node1 !== "object" || typeof node2 !== "object" || node1 === null || node2 === null) {
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
// Get the keys of both objects.
|
|
195
|
-
const keys1 = Object.keys(node1);
|
|
196
|
-
const keys2 = Object.keys(node2);
|
|
197
|
-
// Check if the number of keys is the same.
|
|
198
|
-
if (keys1.length !== keys2.length) {
|
|
199
|
-
return false;
|
|
200
|
-
}
|
|
201
|
-
// Iterate through the keys and compare their values recursively.
|
|
202
|
-
for (const key of keys1) {
|
|
203
|
-
if (!keys2.includes(key) ||
|
|
204
|
-
!compareReactNodes(node1[key], node2[key])) {
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
// If all checks pass, the objects are deep equal.
|
|
209
|
-
return true;
|
|
185
|
+
return (jsxRuntime.jsx("div", { className: cvaActionContainer({ className, size }), children: jsxRuntime.jsx(reactComponents.IconButton, { className: cvaActionButton({ size }), dataTestId: dataTestId || "testIconButtonId", disabled: disabled, icon: jsxRuntime.jsx(reactComponents.Icon, { name: getIconName(), size: size }), onClick: buttonAction, size: "small", variant: "secondary" }) }));
|
|
210
186
|
};
|
|
211
187
|
|
|
212
188
|
const cvaInputBase = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -223,8 +199,9 @@ const cvaInputBaseInvalid = cssClassVarianceUtilities.cvaMerge(["border-danger-6
|
|
|
223
199
|
const cvaInput = cssClassVarianceUtilities.cvaMerge(["relative", "flex", "h-10", cvaInputBase()], {
|
|
224
200
|
variants: {
|
|
225
201
|
size: {
|
|
226
|
-
small: ["h-
|
|
227
|
-
medium: ["h-
|
|
202
|
+
small: ["h-7"],
|
|
203
|
+
medium: ["h-8"],
|
|
204
|
+
large: ["h-10"],
|
|
228
205
|
},
|
|
229
206
|
disabled: {
|
|
230
207
|
true: cvaInputBaseDisabled(),
|
|
@@ -234,6 +211,20 @@ const cvaInput = cssClassVarianceUtilities.cvaMerge(["relative", "flex", "h-10",
|
|
|
234
211
|
true: cvaInputBaseInvalid(),
|
|
235
212
|
false: [""],
|
|
236
213
|
},
|
|
214
|
+
isWarning: {
|
|
215
|
+
true: ["border-warning-600"],
|
|
216
|
+
false: [""],
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
compoundVariants: [
|
|
220
|
+
{
|
|
221
|
+
invalid: true,
|
|
222
|
+
isWarning: true,
|
|
223
|
+
className: ["border-danger-600"], // Ensures that 'invalid' takes precedence
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
defaultVariants: {
|
|
227
|
+
size: "medium",
|
|
237
228
|
},
|
|
238
229
|
});
|
|
239
230
|
const cvaInputField = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -241,18 +232,24 @@ const cvaInputField = cssClassVarianceUtilities.cvaMerge([
|
|
|
241
232
|
"px-3",
|
|
242
233
|
"border-0",
|
|
243
234
|
"bg-transparent",
|
|
244
|
-
"text-base",
|
|
245
235
|
"text-slate-900",
|
|
246
236
|
"placeholder-slate-400",
|
|
247
237
|
"component-baseInput-border",
|
|
238
|
+
"text-sm",
|
|
239
|
+
"truncate",
|
|
248
240
|
], {
|
|
249
241
|
variants: {
|
|
250
242
|
size: {
|
|
251
|
-
small: ["py-
|
|
252
|
-
medium: ["py-
|
|
243
|
+
small: ["py-0.5", "text-xs"],
|
|
244
|
+
medium: ["py-1"],
|
|
245
|
+
large: ["py-2"],
|
|
253
246
|
},
|
|
254
247
|
disabled: {
|
|
255
|
-
true: ["text-slate-
|
|
248
|
+
true: ["text-slate-400"],
|
|
249
|
+
false: [""],
|
|
250
|
+
},
|
|
251
|
+
readOnly: {
|
|
252
|
+
true: ["text-slate-500"],
|
|
256
253
|
false: [""],
|
|
257
254
|
},
|
|
258
255
|
autoFocus: {
|
|
@@ -274,6 +271,11 @@ const cvaInputField = cssClassVarianceUtilities.cvaMerge([
|
|
|
274
271
|
prefix: true,
|
|
275
272
|
className: ["ps-4"],
|
|
276
273
|
},
|
|
274
|
+
{
|
|
275
|
+
disabled: true,
|
|
276
|
+
readOnly: true,
|
|
277
|
+
className: "text-slate-400",
|
|
278
|
+
},
|
|
277
279
|
],
|
|
278
280
|
});
|
|
279
281
|
const cvaInputAddon = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -285,7 +287,15 @@ const cvaInputAddon = cssClassVarianceUtilities.cvaMerge([
|
|
|
285
287
|
"text-slate-500",
|
|
286
288
|
"bg-slate-50",
|
|
287
289
|
]);
|
|
288
|
-
const cvaInputAddonBefore = cssClassVarianceUtilities.cvaMerge([cvaInputAddon(), "border-r", "rounded-l-lg"]
|
|
290
|
+
const cvaInputAddonBefore = cssClassVarianceUtilities.cvaMerge([cvaInputAddon(), "border-r", "rounded-l-lg"], {
|
|
291
|
+
variants: {
|
|
292
|
+
size: {
|
|
293
|
+
small: ["text-xs"],
|
|
294
|
+
medium: ["text-sm"],
|
|
295
|
+
large: ["text-sm"],
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
});
|
|
289
299
|
const cvaInputPrefix = cssClassVarianceUtilities.cvaMerge([
|
|
290
300
|
"flex",
|
|
291
301
|
"justify-center",
|
|
@@ -304,7 +314,7 @@ const cvaInputPrefix = cssClassVarianceUtilities.cvaMerge([
|
|
|
304
314
|
false: [""],
|
|
305
315
|
},
|
|
306
316
|
addonBefore: {
|
|
307
|
-
true: ["relative"],
|
|
317
|
+
true: ["relative", "mr-1"],
|
|
308
318
|
false: [""],
|
|
309
319
|
},
|
|
310
320
|
},
|
|
@@ -320,7 +330,7 @@ const cvaInputSuffix = cssClassVarianceUtilities.cvaMerge(["flex", "justify-cent
|
|
|
320
330
|
false: [""],
|
|
321
331
|
},
|
|
322
332
|
actions: {
|
|
323
|
-
true: ["right-
|
|
333
|
+
true: ["right-6"],
|
|
324
334
|
false: [""],
|
|
325
335
|
},
|
|
326
336
|
},
|
|
@@ -332,41 +342,104 @@ const cvaInputSuffix = cssClassVarianceUtilities.cvaMerge(["flex", "justify-cent
|
|
|
332
342
|
},
|
|
333
343
|
],
|
|
334
344
|
});
|
|
335
|
-
const cvaInputAddonAfter = cssClassVarianceUtilities.cvaMerge([cvaInputAddon(), "border-l", "rounded-r-lg", "ml-[1px]"]
|
|
336
|
-
const cvaInputAction = cssClassVarianceUtilities.cvaMerge(["absolute", "end-0.5"], {
|
|
345
|
+
const cvaInputAddonAfter = cssClassVarianceUtilities.cvaMerge([cvaInputAddon(), "border-l", "rounded-r-lg", "ml-[1px]"], {
|
|
337
346
|
variants: {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
suffix: {
|
|
343
|
-
true: ["absolute"],
|
|
344
|
-
false: [""],
|
|
347
|
+
size: {
|
|
348
|
+
small: ["text-xs"],
|
|
349
|
+
medium: ["text-sm"],
|
|
350
|
+
large: ["text-sm"],
|
|
345
351
|
},
|
|
346
352
|
},
|
|
347
|
-
compoundVariants: [
|
|
348
|
-
{
|
|
349
|
-
addonAfter: true,
|
|
350
|
-
suffix: true,
|
|
351
|
-
className: ["relative"],
|
|
352
|
-
},
|
|
353
|
-
],
|
|
354
353
|
});
|
|
355
354
|
|
|
355
|
+
// Renders the "addonAfter" element if provided
|
|
356
|
+
const AddonAfterRenderer = ({ addonAfter, dataTestId, fieldSize, }) => {
|
|
357
|
+
if (!addonAfter) {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
return (jsxRuntime.jsx("div", { className: cvaInputAddonAfter({ size: fieldSize }), "data-testid": dataTestId ? `${dataTestId}-addonAfter` : null, children: addonAfter }));
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
// Renders the "addonBefore" element if provided
|
|
364
|
+
const AddonBeforeRenderer = ({ addonBefore, addonBeforeClassName, dataTestId, fieldSize, }) => {
|
|
365
|
+
if (!addonBefore) {
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
return (jsxRuntime.jsx("div", { className: cvaInputAddonBefore({ className: addonBeforeClassName, size: fieldSize }), "data-testid": dataTestId ? `${dataTestId}-addonBefore` : null, children: addonBefore }));
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
// Renders generic actions like "copy" if specified
|
|
372
|
+
const GenericActionsRenderer = ({ genericAction, fieldSize, innerRef, }) => {
|
|
373
|
+
const [t] = useTranslation();
|
|
374
|
+
if (!genericAction) {
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
// Currently only supports copy, can extend if more actions are added
|
|
378
|
+
return (jsxRuntime.jsx(reactComponents.Tooltip, { label: t("baseInput.copyAction.toolTip"), placement: "top", children: jsxRuntime.jsx(ActionButton, { dataTestId: "copy-value-button", size: fieldSize ?? undefined, type: "COPY", value: innerRef }) }));
|
|
379
|
+
};
|
|
380
|
+
|
|
356
381
|
/**
|
|
357
382
|
* Icon with explanation tooltip for why an input is locked or disabled.
|
|
358
383
|
* If locked, a permission lacks but the input **can** sometimes be edited.
|
|
359
384
|
* If disabled, the input **cannot** be edited and is only ever for displaying information.
|
|
360
385
|
*
|
|
361
|
-
* @param {
|
|
362
|
-
* @param {
|
|
386
|
+
* @param {LockedForReasons} props - The reasons for the disabled state.
|
|
387
|
+
* @param {LockedKind} kind - The kind of disabled state. If locked, the input can sometimes be edited. If disabled, the input cannot be edited.
|
|
363
388
|
*/
|
|
364
|
-
const
|
|
389
|
+
const InputLockReasonTooltip = ({ reasons, kind }) => {
|
|
365
390
|
const [t] = useTranslation();
|
|
366
391
|
if (!reasons || reasons.length === 0) {
|
|
367
392
|
return (jsxRuntime.jsx(reactComponents.Tooltip, { label: t("field.notEditable.tooltip"), children: jsxRuntime.jsx(reactComponents.Icon, { name: kind === "disabled" ? "QuestionMarkCircle" : "LockClosed", size: "small" }) }));
|
|
368
393
|
}
|
|
369
|
-
return (jsxRuntime.jsx(reactComponents.Tooltip, { label: jsxRuntime.jsx("ul", { className: typeof reasons === "string"
|
|
394
|
+
return (jsxRuntime.jsx(reactComponents.Tooltip, { label: jsxRuntime.jsx("ul", { className: typeof reasons === "string" ? "list-none !pl-0" : "list-disc", children: typeof reasons === "string" ? jsxRuntime.jsx("li", { children: reasons }) : reasons.map(reason => jsxRuntime.jsx("li", { children: reason }, reason)) }), placement: "top", children: jsxRuntime.jsx(reactComponents.Icon, { name: "LockClosed", size: "small" }) }));
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
// Renders a tooltip for lock reasons if the prop is an object
|
|
398
|
+
const LockReasonRenderer = ({ lockReason, dataTestId, }) => {
|
|
399
|
+
// Only render if lockReason is an object
|
|
400
|
+
if (typeof lockReason !== "object") {
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
return (jsxRuntime.jsx("div", { className: cvaInputSuffix({ disabled: false }), "data-testid": dataTestId ? `${dataTestId}-locked` : undefined, children: jsxRuntime.jsx(InputLockReasonTooltip, { ...lockReason }) }));
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
// Renders the prefix element or falls back to a default prefix for certain types
|
|
407
|
+
const PrefixRenderer = ({ prefix, type, addonBefore, dataTestId, disabled, }) => {
|
|
408
|
+
// Default icons for specific input types
|
|
409
|
+
const defaultPrefixMap = {
|
|
410
|
+
email: jsxRuntime.jsx(reactComponents.Icon, { name: "AtSymbol", size: "small" }),
|
|
411
|
+
number: jsxRuntime.jsx(reactComponents.Icon, { name: "Hashtag", size: "small" }),
|
|
412
|
+
url: jsxRuntime.jsx(reactComponents.Icon, { name: "Link", size: "small" }),
|
|
413
|
+
};
|
|
414
|
+
// Decide what to show as prefix
|
|
415
|
+
const resolvedPrefix = prefix || (type && type !== "text" ? (defaultPrefixMap[type] ?? type) : null);
|
|
416
|
+
if (!resolvedPrefix) {
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
return (jsxRuntime.jsx("div", { className: cvaInputPrefix({ disabled, addonBefore: addonBefore !== undefined }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, children: resolvedPrefix }));
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
// Renders the suffix element or shows an icon if invalid/warning
|
|
423
|
+
const SuffixRenderer = ({ suffix, addonAfter, actions, isInvalid, isWarning, dataTestId, disabled, }) => {
|
|
424
|
+
// If user provided suffix that's not identical to addonBefore, render it
|
|
425
|
+
if (suffix) {
|
|
426
|
+
return (jsxRuntime.jsx("div", { className: cvaInputSuffix({
|
|
427
|
+
disabled,
|
|
428
|
+
addonAfter: addonAfter !== undefined,
|
|
429
|
+
actions: Boolean(actions),
|
|
430
|
+
}), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix }));
|
|
431
|
+
}
|
|
432
|
+
// If invalid or warning, render an icon (unless within FormGroup)
|
|
433
|
+
if (isInvalid || isWarning) {
|
|
434
|
+
return (jsxRuntime.jsx("div", { className: cvaInputSuffix({
|
|
435
|
+
disabled,
|
|
436
|
+
addonAfter: addonAfter !== undefined,
|
|
437
|
+
actions: Boolean(actions),
|
|
438
|
+
// Hides the icon if inside a FormGroup
|
|
439
|
+
className: "group-[.form-group]:hidden",
|
|
440
|
+
}), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: jsxRuntime.jsx(reactComponents.Icon, { color: isInvalid ? "danger" : "warning", name: "ExclamationTriangle", size: "small" }) }));
|
|
441
|
+
}
|
|
442
|
+
return null;
|
|
370
443
|
};
|
|
371
444
|
|
|
372
445
|
/**
|
|
@@ -377,44 +450,33 @@ const DisabledForReasonsTip = ({ reasons, kind }) => {
|
|
|
377
450
|
* For specific input types make sure to use the corresponding input component.
|
|
378
451
|
* This is a base used by our other input components such as TextInput, NumberInput, PasswordInput, etc.
|
|
379
452
|
*/
|
|
380
|
-
const BaseInput =
|
|
381
|
-
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
453
|
+
const BaseInput = React.forwardRef(({ className, isInvalid, dataTestId, prefix, suffix, addonBefore, addonAfter, actions, fieldSize = "medium", nonInteractive = false, inputClassName, placeholder, addonBeforeClassName, isWarning, type, genericAction, style, ...rest }, ref) => {
|
|
454
|
+
// Derive final flags
|
|
455
|
+
const renderAsDisabled = Boolean(rest.disabled);
|
|
456
|
+
const renderAsReadonly = Boolean(rest.readOnly);
|
|
457
|
+
// Keep a reference to the input element
|
|
458
|
+
const innerRef = React.useRef(null);
|
|
459
|
+
React.useImperativeHandle(ref, () => innerRef.current, []);
|
|
385
460
|
return (jsxRuntime.jsxs("div", { className: cvaInput({
|
|
386
461
|
disabled: renderAsDisabled,
|
|
387
462
|
invalid: isInvalid,
|
|
463
|
+
isWarning,
|
|
388
464
|
size: fieldSize,
|
|
389
465
|
className,
|
|
390
|
-
}), "data-testid": dataTestId ? `${dataTestId}-container` : null, style: style, children: [
|
|
391
|
-
disabled: renderAsDisabled,
|
|
392
|
-
addonBefore: addonBefore !== undefined,
|
|
393
|
-
}), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, children: prefix })) : null, jsxRuntime.jsx("input", { "aria-required": rest.required, className: cvaInputField({
|
|
466
|
+
}), "data-testid": dataTestId ? `${dataTestId}-container` : null, style: style, children: [jsxRuntime.jsx(AddonBeforeRenderer, { addonBefore: addonBefore, addonBeforeClassName: addonBeforeClassName, dataTestId: dataTestId, fieldSize: fieldSize }), jsxRuntime.jsx(PrefixRenderer, { addonBefore: addonBefore, dataTestId: dataTestId, disabled: renderAsDisabled, prefix: prefix, type: type }), jsxRuntime.jsx("input", { "aria-required": rest.required, className: cvaInputField({
|
|
394
467
|
autoFocus: rest.autoFocus,
|
|
468
|
+
readOnly: renderAsReadonly,
|
|
395
469
|
size: fieldSize,
|
|
396
470
|
disabled: renderAsDisabled,
|
|
397
471
|
className: inputClassName,
|
|
398
472
|
addonBefore: addonBefore !== undefined,
|
|
399
|
-
prefix:
|
|
400
|
-
}), "data-testid": dataTestId, placeholder: renderAsDisabled ? undefined : placeholder, ref: innerRef, ...rest, disabled:
|
|
401
|
-
disabled: false,
|
|
402
|
-
}), "data-testid": dataTestId ? `${dataTestId}-locked` : undefined, children: jsxRuntime.jsx(DisabledForReasonsTip, { ...rest.disabled }) })) : null, suffix && addonBefore !== suffix ? (jsxRuntime.jsx("div", { className: cvaInputSuffix({
|
|
403
|
-
disabled: renderAsDisabled,
|
|
404
|
-
addonAfter: addonAfter !== undefined && !compareReactNodes(addonBefore, addonAfter),
|
|
405
|
-
actions: (actions && !compareReactNodes(addonBefore, actions)) || false,
|
|
406
|
-
}), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix })) : null, rest.readOnly === true &&
|
|
407
|
-
showDefaultActions &&
|
|
408
|
-
innerRef.current?.value.length &&
|
|
409
|
-
innerRef.current.value.length > 0 ? (jsxRuntime.jsx(ActionButton, { type: "COPY", value: innerRef }, "default-copy-action")) : null, actions && !compareReactNodes(addonBefore, actions) ? (jsxRuntime.jsx("div", { className: cvaInputAction({
|
|
410
|
-
addonAfter: addonAfter !== undefined && !compareReactNodes(addonBefore, addonAfter),
|
|
411
|
-
suffix: !compareReactNodes(addonBefore, suffix),
|
|
412
|
-
}), children: actions })) : null, addonAfter && !compareReactNodes(addonBefore, addonAfter) && !compareReactNodes(addonAfter, suffix) ? (jsxRuntime.jsx("div", { className: cvaInputAddonAfter(), "data-testid": dataTestId ? `${dataTestId}-addonAfter` : null, children: addonAfter })) : null] }));
|
|
473
|
+
prefix: !!prefix || (type && type !== "text"),
|
|
474
|
+
}), "data-testid": dataTestId, placeholder: renderAsDisabled ? undefined : placeholder, ref: innerRef, type: type, ...rest, disabled: renderAsDisabled, readOnly: renderAsReadonly || nonInteractive }), jsxRuntime.jsx(LockReasonRenderer, { dataTestId: dataTestId + "-disabled", lockReason: rest.disabled }), jsxRuntime.jsx(LockReasonRenderer, { dataTestId: dataTestId + "-readonly", lockReason: rest.readOnly && !rest.disabled ? rest.readOnly : undefined }), jsxRuntime.jsx(GenericActionsRenderer, { fieldSize: fieldSize, genericAction: genericAction, innerRef: innerRef }), jsxRuntime.jsx(SuffixRenderer, { actions: actions, addonAfter: addonAfter, dataTestId: dataTestId, disabled: renderAsDisabled, isInvalid: isInvalid, isWarning: isWarning, suffix: suffix }), actions, jsxRuntime.jsx(AddonAfterRenderer, { addonAfter: addonAfter, dataTestId: dataTestId, fieldSize: fieldSize })] }));
|
|
413
475
|
});
|
|
414
476
|
BaseInput.displayName = "BaseInput";
|
|
415
477
|
|
|
416
478
|
const cvaLabel = cssClassVarianceUtilities.cvaMerge([
|
|
417
|
-
"text-
|
|
479
|
+
"text-sm",
|
|
418
480
|
"text-slate-700",
|
|
419
481
|
"truncate",
|
|
420
482
|
"hover:text-slate-800",
|
|
@@ -615,7 +677,7 @@ const Label = ({ id, htmlFor, children, className, dataTestId, disabled, isInval
|
|
|
615
677
|
return (jsxRuntime.jsx("label", { className: cvaLabel({ invalid: isInvalid, disabled, className }), "data-testid": dataTestId, htmlFor: htmlFor || "", id: id || "", children: children }));
|
|
616
678
|
};
|
|
617
679
|
|
|
618
|
-
const cvaFormGroup = cssClassVarianceUtilities.cvaMerge(["component-formGroup-gap"]);
|
|
680
|
+
const cvaFormGroup = cssClassVarianceUtilities.cvaMerge(["component-formGroup-gap", "group", "form-group"]);
|
|
619
681
|
const cvaFormGroupContainerBefore = cssClassVarianceUtilities.cvaMerge(["flex", "mb-1", "items-center"]);
|
|
620
682
|
const cvaFormGroupContainerAfter = cssClassVarianceUtilities.cvaMerge(["flex", "justify-between", "mt-1", "text-xs", "text-slate-500"], {
|
|
621
683
|
variants: {
|
|
@@ -623,7 +685,18 @@ const cvaFormGroupContainerAfter = cssClassVarianceUtilities.cvaMerge(["flex", "
|
|
|
623
685
|
true: "text-danger-500",
|
|
624
686
|
false: "",
|
|
625
687
|
},
|
|
688
|
+
isWarning: {
|
|
689
|
+
true: "text-default-500 ",
|
|
690
|
+
false: "",
|
|
691
|
+
},
|
|
626
692
|
},
|
|
693
|
+
compoundVariants: [
|
|
694
|
+
{
|
|
695
|
+
invalid: true,
|
|
696
|
+
isWarning: true,
|
|
697
|
+
className: "text-danger-500 ", // Ensures that 'invalid' takes precedence
|
|
698
|
+
},
|
|
699
|
+
],
|
|
627
700
|
});
|
|
628
701
|
const cvaHelpAddon = cssClassVarianceUtilities.cvaMerge(["ml-auto"]);
|
|
629
702
|
|
|
@@ -634,9 +707,13 @@ const cvaHelpAddon = cssClassVarianceUtilities.cvaMerge(["ml-auto"]);
|
|
|
634
707
|
* @param {FormGroupProps} props - The props for the FormGroup component
|
|
635
708
|
* @returns {JSX.Element} FormGroup component
|
|
636
709
|
*/
|
|
637
|
-
const FormGroup = ({ isInvalid, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, required = false, }) => {
|
|
710
|
+
const FormGroup = ({ isInvalid, isWarning, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, required = false, }) => {
|
|
638
711
|
const [t] = useTranslation();
|
|
639
|
-
|
|
712
|
+
const validationStateIcon = React__namespace.useMemo(() => {
|
|
713
|
+
const color = isInvalid ? "danger" : isWarning ? "warning" : null;
|
|
714
|
+
return color ? jsxRuntime.jsx(reactComponents.Icon, { color: color, name: "ExclamationTriangle", size: "small" }) : null;
|
|
715
|
+
}, [isInvalid, isWarning]);
|
|
716
|
+
return (jsxRuntime.jsxs("div", { className: cvaFormGroup({ className }), "data-testid": dataTestId, children: [jsxRuntime.jsxs("div", { className: cvaFormGroupContainerBefore(), children: [label ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Label, { className: "component-formGroup-font", dataTestId: dataTestId ? `${dataTestId}-label` : undefined, htmlFor: htmlFor, id: htmlFor + "-label", children: label }), required ? (jsxRuntime.jsx(reactComponents.Tooltip, { "data-testid": "required-asterisk", label: t("field.required.asterisk.tooltip"), children: "*" })) : null] })) : null, tip ? (jsxRuntime.jsx(reactComponents.Tooltip, { className: "ml-1", dataTestId: dataTestId ? `${dataTestId}-tooltip` : undefined, label: tip, placement: "bottom" })) : null] }), children, helpText || helpAddon ? (jsxRuntime.jsxs("div", { className: cvaFormGroupContainerAfter({ invalid: isInvalid, isWarning: isWarning }), children: [helpText ? (jsxRuntime.jsxs("div", { className: "flex gap-1", children: [validationStateIcon, jsxRuntime.jsx("span", { "data-testid": dataTestId ? `${dataTestId}-helpText` : undefined, children: helpText })] })) : undefined, helpAddon ? (jsxRuntime.jsx("span", { className: cvaHelpAddon(), "data-testid": dataTestId ? `${dataTestId}-helpAddon` : null, children: helpAddon })) : null] })) : null] }));
|
|
640
717
|
};
|
|
641
718
|
|
|
642
719
|
/**
|
|
@@ -917,8 +994,8 @@ const validateEmailId = (emailId, required) => {
|
|
|
917
994
|
* A reference to the input element is provided as the `ref` prop.
|
|
918
995
|
* For specific input types make sure to use the corresponding input component.
|
|
919
996
|
*/
|
|
920
|
-
const EmailInput =
|
|
921
|
-
const [email, setEmail] =
|
|
997
|
+
const EmailInput = React.forwardRef(({ fieldSize = "medium", disabled = false, dataTestId, isInvalid = false, onChange, disableAction = false, ...rest }, ref) => {
|
|
998
|
+
const [email, setEmail] = React.useState("");
|
|
922
999
|
const sendEmail = () => {
|
|
923
1000
|
return window.open(`mailto:${email}`);
|
|
924
1001
|
};
|
|
@@ -928,7 +1005,7 @@ const EmailInput = React__namespace.forwardRef(({ fieldSize = "medium", disabled
|
|
|
928
1005
|
setEmail(newValue);
|
|
929
1006
|
}, [onChange]);
|
|
930
1007
|
const renderAsInvalid = (email && !validateEmailAddress(email)) || isInvalid;
|
|
931
|
-
return (jsxRuntime.jsx(BaseInput, { actions: email && email.length > 0 ? (jsxRuntime.jsx(ActionButton, { dataTestId: dataTestId ? `${dataTestId}-emailIcon` : undefined, disabled: disableAction || isInvalid,
|
|
1008
|
+
return (jsxRuntime.jsx(BaseInput, { actions: email && email.length > 0 ? (jsxRuntime.jsx(ActionButton, { dataTestId: dataTestId ? `${dataTestId}-emailIcon` : undefined, disabled: disableAction || isInvalid, onClick: sendEmail, size: fieldSize ?? undefined, type: "EMAIL", value: email })) : null, dataTestId: dataTestId, disabled: disabled, isInvalid: renderAsInvalid, onChange: handleChange, placeholder: rest.placeholder || "mail@example.com", ref: ref, type: "email", ...rest }));
|
|
932
1009
|
});
|
|
933
1010
|
EmailInput.displayName = "EmailInput";
|
|
934
1011
|
|
|
@@ -1115,7 +1192,7 @@ OptionCard.displayName = "OptionCard";
|
|
|
1115
1192
|
*/
|
|
1116
1193
|
const PasswordInput = React.forwardRef((props, ref) => {
|
|
1117
1194
|
const [showPassword, setShowPassword] = React.useState(false);
|
|
1118
|
-
return (jsxRuntime.jsx(BaseInput, { ref: ref, ...props, actions: jsxRuntime.jsx("div", { className: cvaActionContainer(), children: jsxRuntime.jsx(reactComponents.IconButton, { className: cvaActionButton({ size: props.fieldSize }), icon: jsxRuntime.jsx(reactComponents.Icon, { name: showPassword ? "EyeSlash" : "Eye", size: "small" }), onClick: () => setShowPassword(prevState => !prevState), size: "small", variant: "secondary" }) }), type: showPassword ? "text" : "password" }));
|
|
1195
|
+
return (jsxRuntime.jsx(BaseInput, { ref: ref, ...props, actions: jsxRuntime.jsx("div", { className: cvaActionContainer({ size: props.fieldSize }), children: jsxRuntime.jsx(reactComponents.IconButton, { className: cvaActionButton({ size: props.fieldSize }), icon: jsxRuntime.jsx(reactComponents.Icon, { name: showPassword ? "EyeSlash" : "Eye", size: "small" }), onClick: () => setShowPassword(prevState => !prevState), size: "small", variant: "secondary" }) }), type: showPassword ? "text" : "password" }));
|
|
1119
1196
|
});
|
|
1120
1197
|
PasswordInput.displayName = "PasswordInput";
|
|
1121
1198
|
|
|
@@ -1243,7 +1320,7 @@ const PhoneInput = React.forwardRef(({ dataTestId, isInvalid, disabled = false,
|
|
|
1243
1320
|
onFocus?.(event);
|
|
1244
1321
|
fieldIsFocused.current = true;
|
|
1245
1322
|
}, [onFocus]);
|
|
1246
|
-
return (jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-2", "data-testid": dataTestId ? `${dataTestId}-container` : null, children: jsxRuntime.jsx(BaseInput, { actions: !disableAction && innerValue && innerValue.length > 0 ? (jsxRuntime.jsx(ActionButton, { dataTestId: dataTestId ? `${dataTestId}-phoneIcon` : undefined, disabled: isInvalid,
|
|
1323
|
+
return (jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-2", "data-testid": dataTestId ? `${dataTestId}-container` : null, children: jsxRuntime.jsx(BaseInput, { actions: !disableAction && innerValue && innerValue.length > 0 ? (jsxRuntime.jsx(ActionButton, { dataTestId: dataTestId ? `${dataTestId}-phoneIcon` : undefined, disabled: isInvalid, size: fieldSize ?? undefined, type: "PHONE_NUMBER", value: value?.toString() || "" })) : null, dataTestId: dataTestId ? `${dataTestId}-phoneNumberInput` : undefined, disabled: disabled, fieldSize: fieldSize, id: "phoneInput-number", isInvalid: isInvalid, name: name, onBlur: handleBlur, onChange: handleChange, onFocus: handleFocus, prefix: (countryCode && countryCodeToFlagEmoji(countryCode)) || undefined, readOnly: readOnly, ref: ref, type: "tel", value: innerValue, ...rest }) }));
|
|
1247
1324
|
});
|
|
1248
1325
|
PhoneInput.displayName = "PhoneInput";
|
|
1249
1326
|
|
|
@@ -1743,8 +1820,15 @@ const cvaSelect = cssClassVarianceUtilities.cvaMerge([
|
|
|
1743
1820
|
"hover:bg-slate-50",
|
|
1744
1821
|
"bg-white",
|
|
1745
1822
|
"transition",
|
|
1823
|
+
"text-sm",
|
|
1824
|
+
"min-h-0",
|
|
1746
1825
|
], {
|
|
1747
1826
|
variants: {
|
|
1827
|
+
fieldSize: {
|
|
1828
|
+
small: ["h-7", "text-xs"],
|
|
1829
|
+
medium: ["h-8"],
|
|
1830
|
+
large: ["h-10"],
|
|
1831
|
+
},
|
|
1748
1832
|
invalid: {
|
|
1749
1833
|
true: "border border-red-600 text-red-600 hover:border-red-600",
|
|
1750
1834
|
false: "",
|
|
@@ -1829,8 +1913,8 @@ const cvaSelectMenu = cssClassVarianceUtilities.cvaMerge(["relative", "p-1", "gr
|
|
|
1829
1913
|
* @param {SelectMenuItemProps} props - The props for the SingleSelectMenuItem
|
|
1830
1914
|
* @returns {JSX.Element} SingleSelectMenuItem
|
|
1831
1915
|
*/
|
|
1832
|
-
const SingleSelectMenuItem = ({ label, icon, onClick, selected, dataTestId, disabled, optionLabelDescription, }) => {
|
|
1833
|
-
return (jsxRuntime.jsx(reactComponents.MenuItem, { dataTestId: dataTestId, disabled: disabled, label: label, onClick: onClick, optionLabelDescription: optionLabelDescription, prefix: icon, selected: selected, suffix: selected ? jsxRuntime.jsx(reactComponents.Icon, { className: "block text-blue-600", name: "Check", size: "medium" }) : undefined }));
|
|
1916
|
+
const SingleSelectMenuItem = ({ label, icon, onClick, selected, dataTestId, disabled, optionLabelDescription, fieldSize, }) => {
|
|
1917
|
+
return (jsxRuntime.jsx(reactComponents.MenuItem, { dataTestId: dataTestId, disabled: disabled, fieldSize: fieldSize, label: label, onClick: onClick, optionLabelDescription: optionLabelDescription, prefix: icon, selected: selected, suffix: selected ? jsxRuntime.jsx(reactComponents.Icon, { className: "block text-blue-600", name: "Check", size: "medium" }) : undefined }));
|
|
1834
1918
|
};
|
|
1835
1919
|
/**
|
|
1836
1920
|
* A multi select menu item is a basic wrapper around Menu item designed to be used as a multi value render in Select list
|
|
@@ -1838,8 +1922,8 @@ const SingleSelectMenuItem = ({ label, icon, onClick, selected, dataTestId, disa
|
|
|
1838
1922
|
* @param {SelectMenuItemProps} props - The props for the MultiSelectMenuItem
|
|
1839
1923
|
* @returns {JSX.Element} multi select menu item
|
|
1840
1924
|
*/
|
|
1841
|
-
const MultiSelectMenuItem = ({ label, onClick, selected, dataTestId, disabled, optionLabelDescription, }) => {
|
|
1842
|
-
return (jsxRuntime.jsx(reactComponents.MenuItem, { dataTestId: dataTestId, disabled: disabled, label: label, onClick: e => {
|
|
1925
|
+
const MultiSelectMenuItem = ({ label, onClick, selected, dataTestId, disabled, optionLabelDescription, fieldSize, }) => {
|
|
1926
|
+
return (jsxRuntime.jsx(reactComponents.MenuItem, { dataTestId: dataTestId, disabled: disabled, fieldSize: fieldSize, label: label, onClick: e => {
|
|
1843
1927
|
e.stopPropagation();
|
|
1844
1928
|
onClick && onClick(e);
|
|
1845
1929
|
}, optionLabelDescription: optionLabelDescription, prefix: jsxRuntime.jsx(Checkbox, { checked: selected, disabled: disabled, onChange: () => null, onClick: e => {
|
|
@@ -1939,7 +2023,7 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 5, postFix, disabled
|
|
|
1939
2023
|
* @param {JSX.Element} prefix a prefix element
|
|
1940
2024
|
* @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
|
|
1941
2025
|
*/
|
|
1942
|
-
const useCustomComponents = ({ componentsProps, disabled, readOnly, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon, prefix, hasError, getOptionLabelDescription, }) => {
|
|
2026
|
+
const useCustomComponents = ({ componentsProps, disabled, readOnly, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon, prefix, hasError, fieldSize, getOptionLabelDescription, }) => {
|
|
1943
2027
|
const [t] = useTranslation();
|
|
1944
2028
|
// perhaps it should not be wrap in memo (causing some issues with opening and closing on mobiles)
|
|
1945
2029
|
const customComponents = React.useMemo(() => {
|
|
@@ -2039,7 +2123,7 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, refMenuIsEna
|
|
|
2039
2123
|
...props.innerProps,
|
|
2040
2124
|
role: "option",
|
|
2041
2125
|
onClick: () => { },
|
|
2042
|
-
}, children: props.isMulti ? (jsxRuntime.jsx(MultiSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled, optionLabelDescription: getOptionLabelDescription?.(props.data) })) : (jsxRuntime.jsx(SingleSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled || props.isDisabled, optionLabelDescription: getOptionLabelDescription?.(props.data) })) }));
|
|
2126
|
+
}, children: props.isMulti ? (jsxRuntime.jsx(MultiSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data) })) : (jsxRuntime.jsx(SingleSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled || props.isDisabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data) })) }));
|
|
2043
2127
|
},
|
|
2044
2128
|
...componentsProps,
|
|
2045
2129
|
};
|
|
@@ -2057,12 +2141,13 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, refMenuIsEna
|
|
|
2057
2141
|
* @param {StylesConfig<Option, IsMulti, Group> | undefined} styles a optional object to override styles of react-select
|
|
2058
2142
|
* @returns {StylesConfig<Option, boolean>} styles to override in select
|
|
2059
2143
|
*/
|
|
2060
|
-
const useCustomStyles = ({ refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled, }) => {
|
|
2144
|
+
const useCustomStyles = ({ refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled, fieldSize, }) => {
|
|
2061
2145
|
const customStyles = React__namespace.useMemo(() => {
|
|
2062
2146
|
return {
|
|
2063
2147
|
control: base => {
|
|
2064
2148
|
return {
|
|
2065
2149
|
...base,
|
|
2150
|
+
minHeight: fieldSize === "small" ? "28px" : fieldSize === "large" ? "40px" : "32px",
|
|
2066
2151
|
borderRadius: "var(--border-radius-lg)",
|
|
2067
2152
|
backgroundColor: "",
|
|
2068
2153
|
};
|
|
@@ -2125,6 +2210,7 @@ const useCustomStyles = ({ refContainer, refPrefix, maxSelectedDisplayCount, sty
|
|
|
2125
2210
|
valueContainer: base => {
|
|
2126
2211
|
return {
|
|
2127
2212
|
...base,
|
|
2213
|
+
paddingBlock: 0,
|
|
2128
2214
|
flexWrap: maxSelectedDisplayCount !== undefined ? "wrap" : "nowrap",
|
|
2129
2215
|
gap: "0.25rem",
|
|
2130
2216
|
};
|
|
@@ -2156,7 +2242,7 @@ const useCustomStyles = ({ refContainer, refPrefix, maxSelectedDisplayCount, sty
|
|
|
2156
2242
|
* @param {SelectProps} props - The props for the Select component
|
|
2157
2243
|
* @returns {UseSelectProps} Select component
|
|
2158
2244
|
*/
|
|
2159
|
-
const useSelect = ({ 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, getOptionLabelDescription, ...props }) => {
|
|
2245
|
+
const useSelect = ({ 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, getOptionLabelDescription, fieldSize = "medium", ...props }) => {
|
|
2160
2246
|
const refContainer = React.useRef(null);
|
|
2161
2247
|
const refPrefix = React.useRef(null);
|
|
2162
2248
|
const { customStyles } = useCustomStyles({
|
|
@@ -2165,6 +2251,7 @@ const useSelect = ({ id, className, dataTestId = "select", prefix, async, dropdo
|
|
|
2165
2251
|
maxSelectedDisplayCount,
|
|
2166
2252
|
styles,
|
|
2167
2253
|
disabled: Boolean(disabled),
|
|
2254
|
+
fieldSize,
|
|
2168
2255
|
});
|
|
2169
2256
|
const [menuIsOpen, setMenuIsOpen] = React.useState(props.menuIsOpen ?? false);
|
|
2170
2257
|
const refMenuIsEnabled = React.useRef(true);
|
|
@@ -2178,6 +2265,7 @@ const useSelect = ({ id, className, dataTestId = "select", prefix, async, dropdo
|
|
|
2178
2265
|
dropdownIcon,
|
|
2179
2266
|
prefix,
|
|
2180
2267
|
hasError,
|
|
2268
|
+
fieldSize,
|
|
2181
2269
|
getOptionLabelDescription,
|
|
2182
2270
|
});
|
|
2183
2271
|
const menuPlacement = "auto";
|
|
@@ -2271,7 +2359,7 @@ const CreatableSelect = (props) => {
|
|
|
2271
2359
|
value,
|
|
2272
2360
|
]);
|
|
2273
2361
|
const renderAsDisabled = Boolean(props.disabled) || props.readOnly;
|
|
2274
|
-
return (jsxRuntime.jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: renderAsDisabled, className: props.className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined ? (jsxRuntime.jsx("div", { className: cvaSelectPrefixSuffix({ kind: "prefix" }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: refPrefix, children: prefix })) : null, async ? (jsxRuntime.jsx(ReactAsyncCreatableSelect, { ...props, ...reactCreatableSelectProps, ...async, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : props.placeholder })) : (jsxRuntime.jsx(ReactCreatableSelect, { ...props, ...reactCreatableSelectProps, hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: options, placeholder: renderAsDisabled ? null : props.placeholder })), typeof props.disabled === "object" ? (jsxRuntime.jsx("div", { className: cvaSelectPrefixSuffix({ kind: "suffix" }), "data-testid": dataTestId ? `${dataTestId}-locked` : null, children: jsxRuntime.jsx(
|
|
2362
|
+
return (jsxRuntime.jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: renderAsDisabled, className: props.className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined ? (jsxRuntime.jsx("div", { className: cvaSelectPrefixSuffix({ kind: "prefix" }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: refPrefix, children: prefix })) : null, async ? (jsxRuntime.jsx(ReactAsyncCreatableSelect, { ...props, ...reactCreatableSelectProps, ...async, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : props.placeholder })) : (jsxRuntime.jsx(ReactCreatableSelect, { ...props, ...reactCreatableSelectProps, hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: options, placeholder: renderAsDisabled ? null : props.placeholder })), typeof props.disabled === "object" ? (jsxRuntime.jsx("div", { className: cvaSelectPrefixSuffix({ kind: "suffix" }), "data-testid": dataTestId ? `${dataTestId}-locked` : null, children: jsxRuntime.jsx(InputLockReasonTooltip, { ...props.disabled }) })) : null] }));
|
|
2275
2363
|
};
|
|
2276
2364
|
CreatableSelect.displayName = "CreatableSelect";
|
|
2277
2365
|
|
|
@@ -2282,7 +2370,7 @@ CreatableSelect.displayName = "CreatableSelect";
|
|
|
2282
2370
|
* @returns {JSX.Element} Select component
|
|
2283
2371
|
*/
|
|
2284
2372
|
const Select = (props) => {
|
|
2285
|
-
const { id, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, menuPosition = "absolute", value, options, onChange, isLoading, classNamePrefix = "select", onMenuScrollToBottom, onInputChange, isSearchable, isClearable = false, readOnly, openMenuOnClick = !disabled, openMenuOnFocus = !disabled, hideSelectedOptions = false, } = props;
|
|
2373
|
+
const { id, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, menuPosition = "absolute", value, options, onChange, isLoading, classNamePrefix = "select", onMenuScrollToBottom, onInputChange, isSearchable, isClearable = false, readOnly, fieldSize = "medium", openMenuOnClick = !disabled, openMenuOnFocus = !disabled, hideSelectedOptions = false, } = props;
|
|
2286
2374
|
const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, } = useSelect(props);
|
|
2287
2375
|
const reactSelectProps = React.useMemo(() => ({
|
|
2288
2376
|
value,
|
|
@@ -2341,7 +2429,12 @@ const Select = (props) => {
|
|
|
2341
2429
|
value,
|
|
2342
2430
|
]);
|
|
2343
2431
|
const renderAsDisabled = Boolean(props.disabled) || props.readOnly;
|
|
2344
|
-
return (jsxRuntime.jsxs("div", { className: cvaSelect({
|
|
2432
|
+
return (jsxRuntime.jsxs("div", { className: cvaSelect({
|
|
2433
|
+
invalid: hasError,
|
|
2434
|
+
fieldSize: fieldSize,
|
|
2435
|
+
disabled: renderAsDisabled,
|
|
2436
|
+
className: props.className,
|
|
2437
|
+
}), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined ? (jsxRuntime.jsx("div", { className: cvaSelectPrefixSuffix({ kind: "prefix" }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: refPrefix, children: prefix })) : null, async ? (jsxRuntime.jsx(ReactAsyncSelect, { ...props, ...reactSelectProps, ...async, menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : props.placeholder })) : (jsxRuntime.jsx(ReactSelect, { ...props, ...reactSelectProps, isMulti: isMulti, menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: options, placeholder: renderAsDisabled ? null : props.placeholder })), typeof props.disabled === "object" ? (jsxRuntime.jsx("div", { className: cvaSelectPrefixSuffix({ kind: "suffix" }), "data-testid": dataTestId ? `${dataTestId}-locked` : null, children: jsxRuntime.jsx(InputLockReasonTooltip, { ...props.disabled }) })) : null] }));
|
|
2345
2438
|
};
|
|
2346
2439
|
Select.displayName = "Select";
|
|
2347
2440
|
|
|
@@ -2502,12 +2595,8 @@ TextAreaField.displayName = "TextAreaField";
|
|
|
2502
2595
|
|
|
2503
2596
|
/**
|
|
2504
2597
|
* Text fields enable the user to interact with and input content and data. This component can be used for long and short form entries. Allow the size of the text input box to reflect the length of the content you expect the user to enter.
|
|
2505
|
-
*
|
|
2506
|
-
* _**Do use** when the user has to input or edit simple text based information, such as metadata._
|
|
2507
|
-
*
|
|
2508
|
-
* _**Do not use** to confirm user actions, such as deleting. Use a checkbox for such flows._
|
|
2509
2598
|
*/
|
|
2510
|
-
const TextField = React__namespace.forwardRef(({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, dataTestId, ...rest }, ref) => {
|
|
2599
|
+
const TextField = React__namespace.forwardRef(({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, dataTestId, isWarning, ...rest }, ref) => {
|
|
2511
2600
|
const [valueLength, setValueLength] = React__namespace.useState(value ? `${value}`.length : 0);
|
|
2512
2601
|
const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
|
|
2513
2602
|
const htmlFor = id ? id : "textField-" + sharedUtils.uuidv4();
|
|
@@ -2518,7 +2607,7 @@ const TextField = React__namespace.forwardRef(({ id, label, tip, helpText, helpA
|
|
|
2518
2607
|
}
|
|
2519
2608
|
}, [onChange]);
|
|
2520
2609
|
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon ||
|
|
2521
|
-
(typeof maxLength === "number" && jsxRuntime.jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsxRuntime.jsx(TextInput, { "aria-labelledby": htmlFor + "-label", id: htmlFor, isInvalid: renderAsInvalid, maxLength: maxLength, ref: ref, value: value, ...rest, className: className, dataTestId: dataTestId, onChange: handleChange }) }));
|
|
2610
|
+
(typeof maxLength === "number" && jsxRuntime.jsx(TextLengthIndicator, { length: valueLength, maxLength: maxLength })), helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, label: label, required: rest.required ? !(rest.disabled || rest.readOnly) : false, tip: tip, children: jsxRuntime.jsx(TextInput, { "aria-labelledby": htmlFor + "-label", id: htmlFor, isInvalid: renderAsInvalid, isWarning: isWarning, maxLength: maxLength, ref: ref, value: value, ...rest, className: className, dataTestId: dataTestId, onChange: handleChange }) }));
|
|
2522
2611
|
});
|
|
2523
2612
|
TextField.displayName = "TextField";
|
|
2524
2613
|
|
|
@@ -2637,20 +2726,19 @@ const cvaUploadInputField = cssClassVarianceUtilities.cvaMerge([
|
|
|
2637
2726
|
"dark:text-gray-400",
|
|
2638
2727
|
"self-center",
|
|
2639
2728
|
]);
|
|
2640
|
-
const cvaUploadInputAddonBefore = cssClassVarianceUtilities.cvaMerge(["block", "truncate", "w-28", "pt-2"]);
|
|
2641
2729
|
|
|
2642
2730
|
/**
|
|
2643
2731
|
* A thin wrapper around the `BaseInput` component for upload input fields.
|
|
2644
2732
|
*
|
|
2645
2733
|
* NOTE: If shown with a label, please use the `UploadField` component instead.
|
|
2646
2734
|
*/
|
|
2647
|
-
const UploadInput = React.forwardRef(({ disabled, acceptedTypes, nonInteractive, uploadLabel, multipleFiles, ...rest }, ref) => (jsxRuntime.jsx(
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2735
|
+
const UploadInput = React.forwardRef(({ disabled, acceptedTypes, nonInteractive, uploadLabel, multipleFiles, ...rest }, ref) => (jsxRuntime.jsx(BaseInput, { accept: acceptedTypes, addonBefore: uploadLabel, disabled: disabled, inputClassName: cvaUploadInputField(), multiple: multipleFiles, nonInteractive: nonInteractive, onClick: event => {
|
|
2736
|
+
// onClick used to work with nonInteractive option
|
|
2737
|
+
if (nonInteractive) {
|
|
2738
|
+
event.preventDefault();
|
|
2739
|
+
event.stopPropagation();
|
|
2740
|
+
}
|
|
2741
|
+
}, ref: ref, type: "file", ...rest })));
|
|
2654
2742
|
UploadInput.displayName = "UploadInput";
|
|
2655
2743
|
|
|
2656
2744
|
/**
|
|
@@ -2702,7 +2790,7 @@ const validateUrl = (url, required) => {
|
|
|
2702
2790
|
const UrlInput = React.forwardRef(({ dataTestId, isInvalid, disabled = false, fieldSize = "medium", disableAction = false, value, defaultValue, ...rest }, ref) => {
|
|
2703
2791
|
const [url, setUrl] = React.useState(value?.toString() || defaultValue?.toString());
|
|
2704
2792
|
const renderAsInvalid = (url && typeof url === "string" && !validateUrlAddress(url)) || isInvalid;
|
|
2705
|
-
return (jsxRuntime.jsx(BaseInput, { dataTestId: dataTestId ? `${dataTestId}-url-input` : undefined, disabled: disabled, id: "url-input", isInvalid: renderAsInvalid, onChange: e => setUrl(e.target.value), placeholder: rest.placeholder || "https://www.example.com", ref: ref, type: "url", value: url, ...rest, actions: !disableAction && (jsxRuntime.jsx(ActionButton, { dataTestId: (dataTestId && `${dataTestId}-url-input-Icon`) || "url-input-action-icon", disabled: renderAsInvalid || disableAction,
|
|
2793
|
+
return (jsxRuntime.jsx(BaseInput, { dataTestId: dataTestId ? `${dataTestId}-url-input` : undefined, disabled: disabled, id: "url-input", isInvalid: renderAsInvalid, onChange: e => setUrl(e.target.value), placeholder: rest.placeholder || "https://www.example.com", ref: ref, type: "url", value: url, ...rest, actions: !disableAction && (jsxRuntime.jsx(ActionButton, { dataTestId: (dataTestId && `${dataTestId}-url-input-Icon`) || "url-input-action-icon", disabled: renderAsInvalid || Boolean(disabled) || disableAction, size: fieldSize ?? undefined, type: "WEB_ADDRESS", value: url })) }));
|
|
2706
2794
|
});
|
|
2707
2795
|
UrlInput.displayName = "UrlField";
|
|
2708
2796
|
|
|
@@ -2892,7 +2980,6 @@ exports.countryCodeToFlagEmoji = countryCodeToFlagEmoji;
|
|
|
2892
2980
|
exports.cvaActionButton = cvaActionButton;
|
|
2893
2981
|
exports.cvaActionContainer = cvaActionContainer;
|
|
2894
2982
|
exports.cvaInput = cvaInput;
|
|
2895
|
-
exports.cvaInputAction = cvaInputAction;
|
|
2896
2983
|
exports.cvaInputAddon = cvaInputAddon;
|
|
2897
2984
|
exports.cvaInputAddonAfter = cvaInputAddonAfter;
|
|
2898
2985
|
exports.cvaInputAddonBefore = cvaInputAddonBefore;
|