@trackunit/react-form-components 1.0.29 → 1.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/index.cjs.js +222 -135
  2. package/index.esm.js +224 -136
  3. package/package.json +2 -2
  4. package/src/components/ActionButton/ActionButton.d.ts +1 -7
  5. package/src/components/ActionButton/ActionButton.variants.d.ts +4 -2
  6. package/src/components/BaseInput/BaseInput.d.ts +26 -30
  7. package/src/components/BaseInput/BaseInput.variants.d.ts +9 -7
  8. package/src/components/BaseInput/InputLockReasonTooltip.d.ts +15 -0
  9. package/src/components/BaseInput/components/AddonAfterRenderer.d.ts +7 -0
  10. package/src/components/BaseInput/components/AddonBeforeRenderer.d.ts +7 -0
  11. package/src/components/BaseInput/components/GenericActionsRenderer.d.ts +8 -0
  12. package/src/components/BaseInput/components/LockReasonRenderer.d.ts +5 -0
  13. package/src/components/BaseInput/components/PrefixRenderer.d.ts +8 -0
  14. package/src/components/BaseInput/components/SuffixRenderer.d.ts +10 -0
  15. package/src/components/BaseInput/components/index.d.ts +6 -0
  16. package/src/components/EmailInput/EmailInput.d.ts +1 -2
  17. package/src/components/FormGroup/FormGroup.d.ts +6 -1
  18. package/src/components/FormGroup/FormGroup.variants.d.ts +1 -0
  19. package/src/components/PhoneInput/PhoneInput.d.ts +3 -3
  20. package/src/components/Search/Search.d.ts +4 -0
  21. package/src/components/Select/Select.variants.d.ts +1 -0
  22. package/src/components/Select/SelectMenuItem/SelectMenuItem.d.ts +7 -2
  23. package/src/components/Select/useCustomComponents.d.ts +3 -1
  24. package/src/components/Select/useCustomStyles.d.ts +3 -1
  25. package/src/components/Select/useSelect.d.ts +10 -3
  26. package/src/components/TextField/TextField.d.ts +0 -4
  27. package/src/components/UploadInput/UploadInput.variants.d.ts +0 -1
  28. package/src/translation.d.ts +2 -2
  29. package/src/types.d.ts +1 -0
  30. package/src/components/BaseInput/DisabledForReasonsTip.d.ts +0 -15
package/index.esm.js CHANGED
@@ -4,7 +4,7 @@ import { IconButton, Icon, Tooltip, useIsTextTruncated, Heading, Text, Spinner,
4
4
  import { useCopyToClipboard } from 'usehooks-ts';
5
5
  import { cvaMerge } from '@trackunit/css-class-variance-utilities';
6
6
  import * as React from 'react';
7
- import React__default, { isValidElement, forwardRef, useMemo, useState, useCallback, useRef, cloneElement, useEffect, useContext, useImperativeHandle } from 'react';
7
+ import React__default, { forwardRef, useRef, useImperativeHandle, useMemo, useState, useCallback, cloneElement, useEffect, useContext } from 'react';
8
8
  import { uuidv4, nonNullable } from '@trackunit/shared-utils';
9
9
  import { Temporal } from '@js-temporal/polyfill';
10
10
  import parsePhoneNumberFromString, { isSupportedCountry, getCountries, getCountryCallingCode, AsYouType, parseIncompletePhoneNumber, isValidPhoneNumber } from 'libphonenumber-js';
@@ -18,6 +18,7 @@ import { twMerge } from 'tailwind-merge';
18
18
  import { z } from 'zod';
19
19
 
20
20
  var defaultTranslations = {
21
+ "baseInput.copyAction.toolTip": "Copy value",
21
22
  "clearIndicator.icon.tooltip.clearAll": "Clear all",
22
23
  "colorField.error.INVALID_HEX_CODE": "Please enter a valid HEX code",
23
24
  "colorField.error.REQUIRED": "This field is required",
@@ -97,15 +98,30 @@ const setupLibraryTranslations = () => {
97
98
  const cvaActionButton = cvaMerge(["drop-shadow-none", "rounded-md"], {
98
99
  variants: {
99
100
  size: {
100
- small: ["w-6", "h-6"],
101
- medium: ["w-8", "h-8"],
101
+ small: ["w-6", "h-6", "min-h-0"],
102
+ medium: ["w-6", "h-6", "min-h-0"],
103
+ large: ["w-8", "h-8"],
104
+ },
105
+ },
106
+ defaultVariants: {
107
+ size: "medium",
108
+ },
109
+ });
110
+ const cvaActionContainer = cvaMerge(["flex", "items-center"], {
111
+ variants: {
112
+ size: {
113
+ //I just measured manually the top/bottom spacing
114
+ //when using the action button inside an input
115
+ //might need tweaking in the future
116
+ small: ["m-[1px]"],
117
+ medium: ["m-[3px]"],
118
+ large: ["m-[3px]"],
102
119
  },
103
120
  },
104
121
  defaultVariants: {
105
122
  size: "medium",
106
123
  },
107
124
  });
108
- const cvaActionContainer = cvaMerge(["flex", "items-center", "m-1"]);
109
125
 
110
126
  /**
111
127
  * The ActionButton component is a wrapper over IconButton to perform an action when the onClick event is triggered.
@@ -113,7 +129,7 @@ const cvaActionContainer = cvaMerge(["flex", "items-center", "m-1"]);
113
129
  * @param {ActionButtonProps} props - The props for the ActionButton component
114
130
  * @returns {JSX.Element} ActionButton component
115
131
  */
116
- const ActionButton = ({ type, value, dataTestId, iconSize, disabled, className }) => {
132
+ const ActionButton = ({ type, value, dataTestId, size, disabled, className }) => {
117
133
  const [, copyToClipboard] = useCopyToClipboard();
118
134
  const getIconName = () => {
119
135
  switch (type) {
@@ -142,52 +158,12 @@ const ActionButton = ({ type, value, dataTestId, iconSize, disabled, className }
142
158
  case "COPY":
143
159
  // Typescript seems to be unable to detect RefObject
144
160
  // as one of the members of the union RefObject | string | null which gives access to the `current` property
145
- // eslint-disable-next-line react/prop-types
146
161
  return copyToClipboard(value?.current?.value ?? "");
147
162
  default:
148
163
  return null;
149
164
  }
150
165
  };
151
- return (jsx("div", { className: cvaActionContainer({ className }), children: jsx(IconButton, { className: cvaActionButton({ size: iconSize }), dataTestId: dataTestId || "testIconButtonId", disabled: disabled, icon: jsx(Icon, { name: getIconName(), size: "small" }), onClick: buttonAction, size: "small", variant: "secondary" }) }));
152
- };
153
-
154
- /**
155
- * Used to compare two React nodes for deep equality.
156
- */
157
- const compareReactNodes = (node1, node2) => {
158
- // Base case: If both objects are identical, return true.
159
- if (node1 === node2) {
160
- return true;
161
- }
162
- // Check if both objects are valid React elements.
163
- if (isValidElement(node1) && isValidElement(node2)) {
164
- const { type: type1, props: props1, key: key1 } = node1;
165
- const { type: type2, props: props2, key: key2 } = node2;
166
- if (type1 !== type2 || key1 !== key2) {
167
- return false;
168
- }
169
- return compareReactNodes(props1, props2);
170
- }
171
- // Check if both objects are objects and not null.
172
- if (typeof node1 !== "object" || typeof node2 !== "object" || node1 === null || node2 === null) {
173
- return false;
174
- }
175
- // Get the keys of both objects.
176
- const keys1 = Object.keys(node1);
177
- const keys2 = Object.keys(node2);
178
- // Check if the number of keys is the same.
179
- if (keys1.length !== keys2.length) {
180
- return false;
181
- }
182
- // Iterate through the keys and compare their values recursively.
183
- for (const key of keys1) {
184
- if (!keys2.includes(key) ||
185
- !compareReactNodes(node1[key], node2[key])) {
186
- return false;
187
- }
188
- }
189
- // If all checks pass, the objects are deep equal.
190
- return true;
166
+ return (jsx("div", { className: cvaActionContainer({ className, size }), children: jsx(IconButton, { className: cvaActionButton({ size }), dataTestId: dataTestId || "testIconButtonId", disabled: disabled, icon: jsx(Icon, { name: getIconName(), size: size }), onClick: buttonAction, size: "small", variant: "secondary" }) }));
191
167
  };
192
168
 
193
169
  const cvaInputBase = cvaMerge([
@@ -204,8 +180,9 @@ const cvaInputBaseInvalid = cvaMerge(["border-danger-600"]);
204
180
  const cvaInput = cvaMerge(["relative", "flex", "h-10", cvaInputBase()], {
205
181
  variants: {
206
182
  size: {
207
- small: ["h-8"],
208
- medium: ["h-10"],
183
+ small: ["h-7"],
184
+ medium: ["h-8"],
185
+ large: ["h-10"],
209
186
  },
210
187
  disabled: {
211
188
  true: cvaInputBaseDisabled(),
@@ -215,6 +192,20 @@ const cvaInput = cvaMerge(["relative", "flex", "h-10", cvaInputBase()], {
215
192
  true: cvaInputBaseInvalid(),
216
193
  false: [""],
217
194
  },
195
+ isWarning: {
196
+ true: ["border-warning-600"],
197
+ false: [""],
198
+ },
199
+ },
200
+ compoundVariants: [
201
+ {
202
+ invalid: true,
203
+ isWarning: true,
204
+ className: ["border-danger-600"], // Ensures that 'invalid' takes precedence
205
+ },
206
+ ],
207
+ defaultVariants: {
208
+ size: "medium",
218
209
  },
219
210
  });
220
211
  const cvaInputField = cvaMerge([
@@ -222,18 +213,24 @@ const cvaInputField = cvaMerge([
222
213
  "px-3",
223
214
  "border-0",
224
215
  "bg-transparent",
225
- "text-base",
226
216
  "text-slate-900",
227
217
  "placeholder-slate-400",
228
218
  "component-baseInput-border",
219
+ "text-sm",
220
+ "truncate",
229
221
  ], {
230
222
  variants: {
231
223
  size: {
232
- small: ["py-1"],
233
- medium: ["py-2"],
224
+ small: ["py-0.5", "text-xs"],
225
+ medium: ["py-1"],
226
+ large: ["py-2"],
234
227
  },
235
228
  disabled: {
236
- true: ["text-slate-700"],
229
+ true: ["text-slate-400"],
230
+ false: [""],
231
+ },
232
+ readOnly: {
233
+ true: ["text-slate-500"],
237
234
  false: [""],
238
235
  },
239
236
  autoFocus: {
@@ -255,6 +252,11 @@ const cvaInputField = cvaMerge([
255
252
  prefix: true,
256
253
  className: ["ps-4"],
257
254
  },
255
+ {
256
+ disabled: true,
257
+ readOnly: true,
258
+ className: "text-slate-400",
259
+ },
258
260
  ],
259
261
  });
260
262
  const cvaInputAddon = cvaMerge([
@@ -266,7 +268,15 @@ const cvaInputAddon = cvaMerge([
266
268
  "text-slate-500",
267
269
  "bg-slate-50",
268
270
  ]);
269
- const cvaInputAddonBefore = cvaMerge([cvaInputAddon(), "border-r", "rounded-l-lg"]);
271
+ const cvaInputAddonBefore = cvaMerge([cvaInputAddon(), "border-r", "rounded-l-lg"], {
272
+ variants: {
273
+ size: {
274
+ small: ["text-xs"],
275
+ medium: ["text-sm"],
276
+ large: ["text-sm"],
277
+ },
278
+ },
279
+ });
270
280
  const cvaInputPrefix = cvaMerge([
271
281
  "flex",
272
282
  "justify-center",
@@ -285,7 +295,7 @@ const cvaInputPrefix = cvaMerge([
285
295
  false: [""],
286
296
  },
287
297
  addonBefore: {
288
- true: ["relative"],
298
+ true: ["relative", "mr-1"],
289
299
  false: [""],
290
300
  },
291
301
  },
@@ -301,7 +311,7 @@ const cvaInputSuffix = cvaMerge(["flex", "justify-center", "items-center", "text
301
311
  false: [""],
302
312
  },
303
313
  actions: {
304
- true: ["right-10"],
314
+ true: ["right-6"],
305
315
  false: [""],
306
316
  },
307
317
  },
@@ -313,41 +323,104 @@ const cvaInputSuffix = cvaMerge(["flex", "justify-center", "items-center", "text
313
323
  },
314
324
  ],
315
325
  });
316
- const cvaInputAddonAfter = cvaMerge([cvaInputAddon(), "border-l", "rounded-r-lg", "ml-[1px]"]);
317
- const cvaInputAction = cvaMerge(["absolute", "end-0.5"], {
326
+ const cvaInputAddonAfter = cvaMerge([cvaInputAddon(), "border-l", "rounded-r-lg", "ml-[1px]"], {
318
327
  variants: {
319
- addonAfter: {
320
- true: ["relative"],
321
- false: [""],
322
- },
323
- suffix: {
324
- true: ["absolute"],
325
- false: [""],
328
+ size: {
329
+ small: ["text-xs"],
330
+ medium: ["text-sm"],
331
+ large: ["text-sm"],
326
332
  },
327
333
  },
328
- compoundVariants: [
329
- {
330
- addonAfter: true,
331
- suffix: true,
332
- className: ["relative"],
333
- },
334
- ],
335
334
  });
336
335
 
336
+ // Renders the "addonAfter" element if provided
337
+ const AddonAfterRenderer = ({ addonAfter, dataTestId, fieldSize, }) => {
338
+ if (!addonAfter) {
339
+ return null;
340
+ }
341
+ return (jsx("div", { className: cvaInputAddonAfter({ size: fieldSize }), "data-testid": dataTestId ? `${dataTestId}-addonAfter` : null, children: addonAfter }));
342
+ };
343
+
344
+ // Renders the "addonBefore" element if provided
345
+ const AddonBeforeRenderer = ({ addonBefore, addonBeforeClassName, dataTestId, fieldSize, }) => {
346
+ if (!addonBefore) {
347
+ return null;
348
+ }
349
+ return (jsx("div", { className: cvaInputAddonBefore({ className: addonBeforeClassName, size: fieldSize }), "data-testid": dataTestId ? `${dataTestId}-addonBefore` : null, children: addonBefore }));
350
+ };
351
+
352
+ // Renders generic actions like "copy" if specified
353
+ const GenericActionsRenderer = ({ genericAction, fieldSize, innerRef, }) => {
354
+ const [t] = useTranslation();
355
+ if (!genericAction) {
356
+ return null;
357
+ }
358
+ // Currently only supports copy, can extend if more actions are added
359
+ return (jsx(Tooltip, { label: t("baseInput.copyAction.toolTip"), placement: "top", children: jsx(ActionButton, { dataTestId: "copy-value-button", size: fieldSize ?? undefined, type: "COPY", value: innerRef }) }));
360
+ };
361
+
337
362
  /**
338
363
  * Icon with explanation tooltip for why an input is locked or disabled.
339
364
  * If locked, a permission lacks but the input **can** sometimes be edited.
340
365
  * If disabled, the input **cannot** be edited and is only ever for displaying information.
341
366
  *
342
- * @param {DisabledForReasons} props - The reasons for the disabled state.
343
- * @param {DisabledKind} kind - The kind of disabled state. If locked, the input can sometimes be edited. If disabled, the input cannot be edited.
367
+ * @param {LockedForReasons} props - The reasons for the disabled state.
368
+ * @param {LockedKind} kind - The kind of disabled state. If locked, the input can sometimes be edited. If disabled, the input cannot be edited.
344
369
  */
345
- const DisabledForReasonsTip = ({ reasons, kind }) => {
370
+ const InputLockReasonTooltip = ({ reasons, kind }) => {
346
371
  const [t] = useTranslation();
347
372
  if (!reasons || reasons.length === 0) {
348
373
  return (jsx(Tooltip, { label: t("field.notEditable.tooltip"), children: jsx(Icon, { name: kind === "disabled" ? "QuestionMarkCircle" : "LockClosed", size: "small" }) }));
349
374
  }
350
- return (jsx(Tooltip, { label: jsx("ul", { className: typeof reasons === "string" || reasons.length === 1 ? "list-inside" : "list-disc", children: typeof reasons === "string" ? jsx("li", { children: reasons }) : reasons.map(reason => jsx("li", { children: reason }, reason)) }), placement: "top", children: jsx(Icon, { name: "LockClosed", size: "small" }) }));
375
+ return (jsx(Tooltip, { label: jsx("ul", { className: typeof reasons === "string" ? "list-none !pl-0" : "list-disc", children: typeof reasons === "string" ? jsx("li", { children: reasons }) : reasons.map(reason => jsx("li", { children: reason }, reason)) }), placement: "top", children: jsx(Icon, { name: "LockClosed", size: "small" }) }));
376
+ };
377
+
378
+ // Renders a tooltip for lock reasons if the prop is an object
379
+ const LockReasonRenderer = ({ lockReason, dataTestId, }) => {
380
+ // Only render if lockReason is an object
381
+ if (typeof lockReason !== "object") {
382
+ return null;
383
+ }
384
+ return (jsx("div", { className: cvaInputSuffix({ disabled: false }), "data-testid": dataTestId ? `${dataTestId}-locked` : undefined, children: jsx(InputLockReasonTooltip, { ...lockReason }) }));
385
+ };
386
+
387
+ // Renders the prefix element or falls back to a default prefix for certain types
388
+ const PrefixRenderer = ({ prefix, type, addonBefore, dataTestId, disabled, }) => {
389
+ // Default icons for specific input types
390
+ const defaultPrefixMap = {
391
+ email: jsx(Icon, { name: "AtSymbol", size: "small" }),
392
+ number: jsx(Icon, { name: "Hashtag", size: "small" }),
393
+ url: jsx(Icon, { name: "Link", size: "small" }),
394
+ };
395
+ // Decide what to show as prefix
396
+ const resolvedPrefix = prefix || (type && type !== "text" ? (defaultPrefixMap[type] ?? type) : null);
397
+ if (!resolvedPrefix) {
398
+ return null;
399
+ }
400
+ return (jsx("div", { className: cvaInputPrefix({ disabled, addonBefore: addonBefore !== undefined }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, children: resolvedPrefix }));
401
+ };
402
+
403
+ // Renders the suffix element or shows an icon if invalid/warning
404
+ const SuffixRenderer = ({ suffix, addonAfter, actions, isInvalid, isWarning, dataTestId, disabled, }) => {
405
+ // If user provided suffix that's not identical to addonBefore, render it
406
+ if (suffix) {
407
+ return (jsx("div", { className: cvaInputSuffix({
408
+ disabled,
409
+ addonAfter: addonAfter !== undefined,
410
+ actions: Boolean(actions),
411
+ }), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix }));
412
+ }
413
+ // If invalid or warning, render an icon (unless within FormGroup)
414
+ if (isInvalid || isWarning) {
415
+ return (jsx("div", { className: cvaInputSuffix({
416
+ disabled,
417
+ addonAfter: addonAfter !== undefined,
418
+ actions: Boolean(actions),
419
+ // Hides the icon if inside a FormGroup
420
+ className: "group-[.form-group]:hidden",
421
+ }), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: jsx(Icon, { color: isInvalid ? "danger" : "warning", name: "ExclamationTriangle", size: "small" }) }));
422
+ }
423
+ return null;
351
424
  };
352
425
 
353
426
  /**
@@ -358,44 +431,33 @@ const DisabledForReasonsTip = ({ reasons, kind }) => {
358
431
  * For specific input types make sure to use the corresponding input component.
359
432
  * This is a base used by our other input components such as TextInput, NumberInput, PasswordInput, etc.
360
433
  */
361
- const BaseInput = React.forwardRef(({ className, isInvalid, dataTestId, prefix, suffix, addonBefore, addonAfter, actions, fieldSize = "medium", nonInteractive = false, showDefaultActions = false, inputClassName, placeholder, addonBeforeClassName, style, ...rest }, ref) => {
362
- const renderAsDisabled = Boolean(rest.disabled) || rest.readOnly;
363
- const innerRef = React.useRef(null);
364
- // eslint-disable-next-line local-rules/no-typescript-assertion
365
- React.useImperativeHandle(ref, () => innerRef.current, []);
434
+ const BaseInput = forwardRef(({ className, isInvalid, dataTestId, prefix, suffix, addonBefore, addonAfter, actions, fieldSize = "medium", nonInteractive = false, inputClassName, placeholder, addonBeforeClassName, isWarning, type, genericAction, style, ...rest }, ref) => {
435
+ // Derive final flags
436
+ const renderAsDisabled = Boolean(rest.disabled);
437
+ const renderAsReadonly = Boolean(rest.readOnly);
438
+ // Keep a reference to the input element
439
+ const innerRef = useRef(null);
440
+ useImperativeHandle(ref, () => innerRef.current, []);
366
441
  return (jsxs("div", { className: cvaInput({
367
442
  disabled: renderAsDisabled,
368
443
  invalid: isInvalid,
444
+ isWarning,
369
445
  size: fieldSize,
370
446
  className,
371
- }), "data-testid": dataTestId ? `${dataTestId}-container` : null, style: style, children: [addonBefore ? (jsx("div", { className: cvaInputAddonBefore({ className: addonBeforeClassName }), "data-testid": dataTestId ? `${dataTestId}-addonBefore` : null, children: addonBefore })) : null, prefix && !compareReactNodes(addonBefore, prefix) ? (jsx("div", { className: cvaInputPrefix({
372
- disabled: renderAsDisabled,
373
- addonBefore: addonBefore !== undefined,
374
- }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, children: prefix })) : null, jsx("input", { "aria-required": rest.required, className: cvaInputField({
447
+ }), "data-testid": dataTestId ? `${dataTestId}-container` : null, style: style, children: [jsx(AddonBeforeRenderer, { addonBefore: addonBefore, addonBeforeClassName: addonBeforeClassName, dataTestId: dataTestId, fieldSize: fieldSize }), jsx(PrefixRenderer, { addonBefore: addonBefore, dataTestId: dataTestId, disabled: renderAsDisabled, prefix: prefix, type: type }), jsx("input", { "aria-required": rest.required, className: cvaInputField({
375
448
  autoFocus: rest.autoFocus,
449
+ readOnly: renderAsReadonly,
376
450
  size: fieldSize,
377
451
  disabled: renderAsDisabled,
378
452
  className: inputClassName,
379
453
  addonBefore: addonBefore !== undefined,
380
- prefix: !compareReactNodes(addonBefore, prefix),
381
- }), "data-testid": dataTestId, placeholder: renderAsDisabled ? undefined : placeholder, ref: innerRef, ...rest, disabled: Boolean(rest.disabled), readOnly: rest.readOnly || nonInteractive }), typeof rest.disabled === "object" ? (jsx("div", { className: cvaInputSuffix({
382
- disabled: false,
383
- }), "data-testid": dataTestId ? `${dataTestId}-locked` : undefined, children: jsx(DisabledForReasonsTip, { ...rest.disabled }) })) : null, suffix && addonBefore !== suffix ? (jsx("div", { className: cvaInputSuffix({
384
- disabled: renderAsDisabled,
385
- addonAfter: addonAfter !== undefined && !compareReactNodes(addonBefore, addonAfter),
386
- actions: (actions && !compareReactNodes(addonBefore, actions)) || false,
387
- }), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix })) : null, rest.readOnly === true &&
388
- showDefaultActions &&
389
- innerRef.current?.value.length &&
390
- innerRef.current.value.length > 0 ? (jsx(ActionButton, { type: "COPY", value: innerRef }, "default-copy-action")) : null, actions && !compareReactNodes(addonBefore, actions) ? (jsx("div", { className: cvaInputAction({
391
- addonAfter: addonAfter !== undefined && !compareReactNodes(addonBefore, addonAfter),
392
- suffix: !compareReactNodes(addonBefore, suffix),
393
- }), children: actions })) : null, addonAfter && !compareReactNodes(addonBefore, addonAfter) && !compareReactNodes(addonAfter, suffix) ? (jsx("div", { className: cvaInputAddonAfter(), "data-testid": dataTestId ? `${dataTestId}-addonAfter` : null, children: addonAfter })) : null] }));
454
+ prefix: !!prefix || (type && type !== "text"),
455
+ }), "data-testid": dataTestId, placeholder: renderAsDisabled ? undefined : placeholder, ref: innerRef, type: type, ...rest, disabled: renderAsDisabled, readOnly: renderAsReadonly || nonInteractive }), jsx(LockReasonRenderer, { dataTestId: dataTestId + "-disabled", lockReason: rest.disabled }), jsx(LockReasonRenderer, { dataTestId: dataTestId + "-readonly", lockReason: rest.readOnly && !rest.disabled ? rest.readOnly : undefined }), jsx(GenericActionsRenderer, { fieldSize: fieldSize, genericAction: genericAction, innerRef: innerRef }), jsx(SuffixRenderer, { actions: actions, addonAfter: addonAfter, dataTestId: dataTestId, disabled: renderAsDisabled, isInvalid: isInvalid, isWarning: isWarning, suffix: suffix }), actions, jsx(AddonAfterRenderer, { addonAfter: addonAfter, dataTestId: dataTestId, fieldSize: fieldSize })] }));
394
456
  });
395
457
  BaseInput.displayName = "BaseInput";
396
458
 
397
459
  const cvaLabel = cvaMerge([
398
- "text-base",
460
+ "text-sm",
399
461
  "text-slate-700",
400
462
  "truncate",
401
463
  "hover:text-slate-800",
@@ -596,7 +658,7 @@ const Label = ({ id, htmlFor, children, className, dataTestId, disabled, isInval
596
658
  return (jsx("label", { className: cvaLabel({ invalid: isInvalid, disabled, className }), "data-testid": dataTestId, htmlFor: htmlFor || "", id: id || "", children: children }));
597
659
  };
598
660
 
599
- const cvaFormGroup = cvaMerge(["component-formGroup-gap"]);
661
+ const cvaFormGroup = cvaMerge(["component-formGroup-gap", "group", "form-group"]);
600
662
  const cvaFormGroupContainerBefore = cvaMerge(["flex", "mb-1", "items-center"]);
601
663
  const cvaFormGroupContainerAfter = cvaMerge(["flex", "justify-between", "mt-1", "text-xs", "text-slate-500"], {
602
664
  variants: {
@@ -604,7 +666,18 @@ const cvaFormGroupContainerAfter = cvaMerge(["flex", "justify-between", "mt-1",
604
666
  true: "text-danger-500",
605
667
  false: "",
606
668
  },
669
+ isWarning: {
670
+ true: "text-default-500 ",
671
+ false: "",
672
+ },
607
673
  },
674
+ compoundVariants: [
675
+ {
676
+ invalid: true,
677
+ isWarning: true,
678
+ className: "text-danger-500 ", // Ensures that 'invalid' takes precedence
679
+ },
680
+ ],
608
681
  });
609
682
  const cvaHelpAddon = cvaMerge(["ml-auto"]);
610
683
 
@@ -615,9 +688,13 @@ const cvaHelpAddon = cvaMerge(["ml-auto"]);
615
688
  * @param {FormGroupProps} props - The props for the FormGroup component
616
689
  * @returns {JSX.Element} FormGroup component
617
690
  */
618
- const FormGroup = ({ isInvalid, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, required = false, }) => {
691
+ const FormGroup = ({ isInvalid, isWarning, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, required = false, }) => {
619
692
  const [t] = useTranslation();
620
- return (jsxs("div", { className: cvaFormGroup({ className }), "data-testid": dataTestId, children: [jsxs("div", { className: cvaFormGroupContainerBefore(), children: [label ? (jsxs(Fragment, { children: [jsx(Label, { className: "component-formGroup-font", dataTestId: dataTestId ? `${dataTestId}-label` : undefined, htmlFor: htmlFor, id: htmlFor + "-label", children: label }), required ? (jsx(Tooltip, { "data-testid": "required-asterisk", label: t("field.required.asterisk.tooltip"), children: "*" })) : null] })) : null, tip ? (jsx(Tooltip, { dataTestId: dataTestId ? `${dataTestId}-tooltip` : undefined, label: tip, placement: "bottom" })) : null] }), children, helpText || helpAddon ? (jsxs("div", { className: cvaFormGroupContainerAfter({ invalid: isInvalid }), children: [helpText ? (jsx("span", { "data-testid": dataTestId ? `${dataTestId}-helpText` : undefined, children: helpText })) : undefined, helpAddon ? (jsx("span", { className: cvaHelpAddon(), "data-testid": dataTestId ? `${dataTestId}-helpAddon` : null, children: helpAddon })) : null] })) : null] }));
693
+ const validationStateIcon = React.useMemo(() => {
694
+ const color = isInvalid ? "danger" : isWarning ? "warning" : null;
695
+ return color ? jsx(Icon, { color: color, name: "ExclamationTriangle", size: "small" }) : null;
696
+ }, [isInvalid, isWarning]);
697
+ return (jsxs("div", { className: cvaFormGroup({ className }), "data-testid": dataTestId, children: [jsxs("div", { className: cvaFormGroupContainerBefore(), children: [label ? (jsxs(Fragment, { children: [jsx(Label, { className: "component-formGroup-font", dataTestId: dataTestId ? `${dataTestId}-label` : undefined, htmlFor: htmlFor, id: htmlFor + "-label", children: label }), required ? (jsx(Tooltip, { "data-testid": "required-asterisk", label: t("field.required.asterisk.tooltip"), children: "*" })) : null] })) : null, tip ? (jsx(Tooltip, { className: "ml-1", dataTestId: dataTestId ? `${dataTestId}-tooltip` : undefined, label: tip, placement: "bottom" })) : null] }), children, helpText || helpAddon ? (jsxs("div", { className: cvaFormGroupContainerAfter({ invalid: isInvalid, isWarning: isWarning }), children: [helpText ? (jsxs("div", { className: "flex gap-1", children: [validationStateIcon, jsx("span", { "data-testid": dataTestId ? `${dataTestId}-helpText` : undefined, children: helpText })] })) : undefined, helpAddon ? (jsx("span", { className: cvaHelpAddon(), "data-testid": dataTestId ? `${dataTestId}-helpAddon` : null, children: helpAddon })) : null] })) : null] }));
621
698
  };
622
699
 
623
700
  /**
@@ -898,8 +975,8 @@ const validateEmailId = (emailId, required) => {
898
975
  * A reference to the input element is provided as the `ref` prop.
899
976
  * For specific input types make sure to use the corresponding input component.
900
977
  */
901
- const EmailInput = React.forwardRef(({ fieldSize = "medium", disabled = false, dataTestId, isInvalid = false, onChange, disableAction = false, ...rest }, ref) => {
902
- const [email, setEmail] = React.useState("");
978
+ const EmailInput = forwardRef(({ fieldSize = "medium", disabled = false, dataTestId, isInvalid = false, onChange, disableAction = false, ...rest }, ref) => {
979
+ const [email, setEmail] = useState("");
903
980
  const sendEmail = () => {
904
981
  return window.open(`mailto:${email}`);
905
982
  };
@@ -909,7 +986,7 @@ const EmailInput = React.forwardRef(({ fieldSize = "medium", disabled = false, d
909
986
  setEmail(newValue);
910
987
  }, [onChange]);
911
988
  const renderAsInvalid = (email && !validateEmailAddress(email)) || isInvalid;
912
- return (jsx(BaseInput, { actions: email && email.length > 0 ? (jsx(ActionButton, { dataTestId: dataTestId ? `${dataTestId}-emailIcon` : undefined, disabled: disableAction || isInvalid, iconSize: fieldSize, onClick: sendEmail, type: "EMAIL", value: email })) : null, dataTestId: dataTestId, disabled: disabled, isInvalid: renderAsInvalid, onChange: handleChange, placeholder: rest.placeholder || "mail@example.com", ref: ref, type: "email", ...rest }));
989
+ return (jsx(BaseInput, { actions: email && email.length > 0 ? (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 }));
913
990
  });
914
991
  EmailInput.displayName = "EmailInput";
915
992
 
@@ -1096,7 +1173,7 @@ OptionCard.displayName = "OptionCard";
1096
1173
  */
1097
1174
  const PasswordInput = forwardRef((props, ref) => {
1098
1175
  const [showPassword, setShowPassword] = useState(false);
1099
- return (jsx(BaseInput, { ref: ref, ...props, actions: jsx("div", { className: cvaActionContainer(), children: jsx(IconButton, { className: cvaActionButton({ size: props.fieldSize }), icon: jsx(Icon, { name: showPassword ? "EyeSlash" : "Eye", size: "small" }), onClick: () => setShowPassword(prevState => !prevState), size: "small", variant: "secondary" }) }), type: showPassword ? "text" : "password" }));
1176
+ return (jsx(BaseInput, { ref: ref, ...props, actions: jsx("div", { className: cvaActionContainer({ size: props.fieldSize }), children: jsx(IconButton, { className: cvaActionButton({ size: props.fieldSize }), icon: jsx(Icon, { name: showPassword ? "EyeSlash" : "Eye", size: "small" }), onClick: () => setShowPassword(prevState => !prevState), size: "small", variant: "secondary" }) }), type: showPassword ? "text" : "password" }));
1100
1177
  });
1101
1178
  PasswordInput.displayName = "PasswordInput";
1102
1179
 
@@ -1224,7 +1301,7 @@ const PhoneInput = forwardRef(({ dataTestId, isInvalid, disabled = false, value,
1224
1301
  onFocus?.(event);
1225
1302
  fieldIsFocused.current = true;
1226
1303
  }, [onFocus]);
1227
- return (jsx("div", { className: "grid grid-cols-1 gap-2", "data-testid": dataTestId ? `${dataTestId}-container` : null, children: jsx(BaseInput, { actions: !disableAction && innerValue && innerValue.length > 0 ? (jsx(ActionButton, { dataTestId: dataTestId ? `${dataTestId}-phoneIcon` : undefined, disabled: isInvalid, iconSize: fieldSize, 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 }) }));
1304
+ return (jsx("div", { className: "grid grid-cols-1 gap-2", "data-testid": dataTestId ? `${dataTestId}-container` : null, children: jsx(BaseInput, { actions: !disableAction && innerValue && innerValue.length > 0 ? (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 }) }));
1228
1305
  });
1229
1306
  PhoneInput.displayName = "PhoneInput";
1230
1307
 
@@ -1705,12 +1782,12 @@ const cvaSearch = cvaMerge([
1705
1782
  * @param {SearchProps} props - The props for the Search component
1706
1783
  * @returns {JSX.Element} Search component
1707
1784
  */
1708
- const Search = forwardRef(({ className, placeholder = "Search", value, widenInputOnFocus, hideBorderWhenNotInFocus = false, disabled, onKeyUp, onChange, onFocus, onBlur, name, onClear, dataTestId, autoComplete = "on", loading, inputClassName, iconName = "MagnifyingGlass", ...rest }, ref) => {
1785
+ const Search = forwardRef(({ className, placeholder = "Search", value, widenInputOnFocus, hideBorderWhenNotInFocus = false, disabled, onKeyUp, onChange, onFocus, onBlur, name, onClear, dataTestId, autoComplete = "on", loading, inputClassName, iconName = "MagnifyingGlass", xMarkRef, ...rest }, ref) => {
1709
1786
  return (jsx(TextInput, { ...rest, autoComplete: autoComplete, className: cvaSearch({ className, border: hideBorderWhenNotInFocus, widenOnFocus: widenInputOnFocus }), dataTestId: dataTestId, disabled: disabled, inputClassName: inputClassName, name: name, onBlur: onBlur, onChange: onChange, onFocus: onFocus, onKeyUp: onKeyUp, placeholder: placeholder, prefix: loading ? (jsx(Spinner, { centering: "centered", size: rest.fieldSize ?? undefined })) : (jsx(Icon, { name: iconName, size: rest.fieldSize ?? undefined })), ref: ref, suffix:
1710
1787
  //only show the clear button if there is a value and the onClear function is provided
1711
1788
  onClear && value ? (jsx("button", { className: "flex", "data-testid": dataTestId ? `${dataTestId}_suffix_component` : null, onClick: () => {
1712
1789
  onClear();
1713
- }, type: "button", children: jsx(Icon, { name: "XMark", size: "small" }) })) : undefined, value: value }));
1790
+ }, ref: xMarkRef, type: "button", children: jsx(Icon, { name: "XMark", size: "small" }) })) : undefined, value: value }));
1714
1791
  });
1715
1792
  Search.displayName = "Search";
1716
1793
 
@@ -1724,8 +1801,15 @@ const cvaSelect = cvaMerge([
1724
1801
  "hover:bg-slate-50",
1725
1802
  "bg-white",
1726
1803
  "transition",
1804
+ "text-sm",
1805
+ "min-h-0",
1727
1806
  ], {
1728
1807
  variants: {
1808
+ fieldSize: {
1809
+ small: ["h-7", "text-xs"],
1810
+ medium: ["h-8"],
1811
+ large: ["h-10"],
1812
+ },
1729
1813
  invalid: {
1730
1814
  true: "border border-red-600 text-red-600 hover:border-red-600",
1731
1815
  false: "",
@@ -1810,8 +1894,8 @@ const cvaSelectMenu = cvaMerge(["relative", "p-1", "grid", "gap-1"]);
1810
1894
  * @param {SelectMenuItemProps} props - The props for the SingleSelectMenuItem
1811
1895
  * @returns {JSX.Element} SingleSelectMenuItem
1812
1896
  */
1813
- const SingleSelectMenuItem = ({ label, icon, onClick, selected, dataTestId, disabled, optionLabelDescription, }) => {
1814
- return (jsx(MenuItem, { dataTestId: dataTestId, disabled: disabled, label: label, onClick: onClick, optionLabelDescription: optionLabelDescription, prefix: icon, selected: selected, suffix: selected ? jsx(Icon, { className: "block text-blue-600", name: "Check", size: "medium" }) : undefined }));
1897
+ const SingleSelectMenuItem = ({ label, icon, onClick, selected, dataTestId, disabled, optionLabelDescription, fieldSize, }) => {
1898
+ return (jsx(MenuItem, { dataTestId: dataTestId, disabled: disabled, fieldSize: fieldSize, label: label, onClick: onClick, optionLabelDescription: optionLabelDescription, prefix: icon, selected: selected, suffix: selected ? jsx(Icon, { className: "block text-blue-600", name: "Check", size: "medium" }) : undefined }));
1815
1899
  };
1816
1900
  /**
1817
1901
  * A multi select menu item is a basic wrapper around Menu item designed to be used as a multi value render in Select list
@@ -1819,8 +1903,8 @@ const SingleSelectMenuItem = ({ label, icon, onClick, selected, dataTestId, disa
1819
1903
  * @param {SelectMenuItemProps} props - The props for the MultiSelectMenuItem
1820
1904
  * @returns {JSX.Element} multi select menu item
1821
1905
  */
1822
- const MultiSelectMenuItem = ({ label, onClick, selected, dataTestId, disabled, optionLabelDescription, }) => {
1823
- return (jsx(MenuItem, { dataTestId: dataTestId, disabled: disabled, label: label, onClick: e => {
1906
+ const MultiSelectMenuItem = ({ label, onClick, selected, dataTestId, disabled, optionLabelDescription, fieldSize, }) => {
1907
+ return (jsx(MenuItem, { dataTestId: dataTestId, disabled: disabled, fieldSize: fieldSize, label: label, onClick: e => {
1824
1908
  e.stopPropagation();
1825
1909
  onClick && onClick(e);
1826
1910
  }, optionLabelDescription: optionLabelDescription, prefix: jsx(Checkbox, { checked: selected, disabled: disabled, onChange: () => null, onClick: e => {
@@ -1920,7 +2004,7 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 5, postFix, disabled
1920
2004
  * @param {JSX.Element} prefix a prefix element
1921
2005
  * @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
1922
2006
  */
1923
- const useCustomComponents = ({ componentsProps, disabled, readOnly, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon, prefix, hasError, getOptionLabelDescription, }) => {
2007
+ const useCustomComponents = ({ componentsProps, disabled, readOnly, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon, prefix, hasError, fieldSize, getOptionLabelDescription, }) => {
1924
2008
  const [t] = useTranslation();
1925
2009
  // perhaps it should not be wrap in memo (causing some issues with opening and closing on mobiles)
1926
2010
  const customComponents = useMemo(() => {
@@ -2020,7 +2104,7 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, refMenuIsEna
2020
2104
  ...props.innerProps,
2021
2105
  role: "option",
2022
2106
  onClick: () => { },
2023
- }, children: props.isMulti ? (jsx(MultiSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled, optionLabelDescription: getOptionLabelDescription?.(props.data) })) : (jsx(SingleSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled || props.isDisabled, optionLabelDescription: getOptionLabelDescription?.(props.data) })) }));
2107
+ }, children: props.isMulti ? (jsx(MultiSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data) })) : (jsx(SingleSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled || props.isDisabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data) })) }));
2024
2108
  },
2025
2109
  ...componentsProps,
2026
2110
  };
@@ -2038,12 +2122,13 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, refMenuIsEna
2038
2122
  * @param {StylesConfig<Option, IsMulti, Group> | undefined} styles a optional object to override styles of react-select
2039
2123
  * @returns {StylesConfig<Option, boolean>} styles to override in select
2040
2124
  */
2041
- const useCustomStyles = ({ refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled, }) => {
2125
+ const useCustomStyles = ({ refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled, fieldSize, }) => {
2042
2126
  const customStyles = React.useMemo(() => {
2043
2127
  return {
2044
2128
  control: base => {
2045
2129
  return {
2046
2130
  ...base,
2131
+ minHeight: fieldSize === "small" ? "28px" : fieldSize === "large" ? "40px" : "32px",
2047
2132
  borderRadius: "var(--border-radius-lg)",
2048
2133
  backgroundColor: "",
2049
2134
  };
@@ -2106,6 +2191,7 @@ const useCustomStyles = ({ refContainer, refPrefix, maxSelectedDisplayCount, sty
2106
2191
  valueContainer: base => {
2107
2192
  return {
2108
2193
  ...base,
2194
+ paddingBlock: 0,
2109
2195
  flexWrap: maxSelectedDisplayCount !== undefined ? "wrap" : "nowrap",
2110
2196
  gap: "0.25rem",
2111
2197
  };
@@ -2137,7 +2223,7 @@ const useCustomStyles = ({ refContainer, refPrefix, maxSelectedDisplayCount, sty
2137
2223
  * @param {SelectProps} props - The props for the Select component
2138
2224
  * @returns {UseSelectProps} Select component
2139
2225
  */
2140
- 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 }) => {
2226
+ 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 }) => {
2141
2227
  const refContainer = React__default.useRef(null);
2142
2228
  const refPrefix = React__default.useRef(null);
2143
2229
  const { customStyles } = useCustomStyles({
@@ -2146,6 +2232,7 @@ const useSelect = ({ id, className, dataTestId = "select", prefix, async, dropdo
2146
2232
  maxSelectedDisplayCount,
2147
2233
  styles,
2148
2234
  disabled: Boolean(disabled),
2235
+ fieldSize,
2149
2236
  });
2150
2237
  const [menuIsOpen, setMenuIsOpen] = React__default.useState(props.menuIsOpen ?? false);
2151
2238
  const refMenuIsEnabled = React__default.useRef(true);
@@ -2159,6 +2246,7 @@ const useSelect = ({ id, className, dataTestId = "select", prefix, async, dropdo
2159
2246
  dropdownIcon,
2160
2247
  prefix,
2161
2248
  hasError,
2249
+ fieldSize,
2162
2250
  getOptionLabelDescription,
2163
2251
  });
2164
2252
  const menuPlacement = "auto";
@@ -2252,7 +2340,7 @@ const CreatableSelect = (props) => {
2252
2340
  value,
2253
2341
  ]);
2254
2342
  const renderAsDisabled = Boolean(props.disabled) || props.readOnly;
2255
- return (jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: renderAsDisabled, className: props.className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined ? (jsx("div", { className: cvaSelectPrefixSuffix({ kind: "prefix" }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: refPrefix, children: prefix })) : null, async ? (jsx(ReactAsyncCreatableSelect, { ...props, ...reactCreatableSelectProps, ...async, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : props.placeholder })) : (jsx(ReactCreatableSelect, { ...props, ...reactCreatableSelectProps, hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: options, placeholder: renderAsDisabled ? null : props.placeholder })), typeof props.disabled === "object" ? (jsx("div", { className: cvaSelectPrefixSuffix({ kind: "suffix" }), "data-testid": dataTestId ? `${dataTestId}-locked` : null, children: jsx(DisabledForReasonsTip, { ...props.disabled }) })) : null] }));
2343
+ return (jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: renderAsDisabled, className: props.className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined ? (jsx("div", { className: cvaSelectPrefixSuffix({ kind: "prefix" }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: refPrefix, children: prefix })) : null, async ? (jsx(ReactAsyncCreatableSelect, { ...props, ...reactCreatableSelectProps, ...async, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : props.placeholder })) : (jsx(ReactCreatableSelect, { ...props, ...reactCreatableSelectProps, hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: options, placeholder: renderAsDisabled ? null : props.placeholder })), typeof props.disabled === "object" ? (jsx("div", { className: cvaSelectPrefixSuffix({ kind: "suffix" }), "data-testid": dataTestId ? `${dataTestId}-locked` : null, children: jsx(InputLockReasonTooltip, { ...props.disabled }) })) : null] }));
2256
2344
  };
2257
2345
  CreatableSelect.displayName = "CreatableSelect";
2258
2346
 
@@ -2263,7 +2351,7 @@ CreatableSelect.displayName = "CreatableSelect";
2263
2351
  * @returns {JSX.Element} Select component
2264
2352
  */
2265
2353
  const Select = (props) => {
2266
- 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;
2354
+ 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;
2267
2355
  const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, } = useSelect(props);
2268
2356
  const reactSelectProps = useMemo(() => ({
2269
2357
  value,
@@ -2322,7 +2410,12 @@ const Select = (props) => {
2322
2410
  value,
2323
2411
  ]);
2324
2412
  const renderAsDisabled = Boolean(props.disabled) || props.readOnly;
2325
- return (jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: renderAsDisabled, className: props.className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined ? (jsx("div", { className: cvaSelectPrefixSuffix({ kind: "prefix" }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: refPrefix, children: prefix })) : null, async ? (jsx(ReactAsyncSelect, { ...props, ...reactSelectProps, ...async, menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : props.placeholder })) : (jsx(ReactSelect, { ...props, ...reactSelectProps, isMulti: isMulti, menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: options, placeholder: renderAsDisabled ? null : props.placeholder })), typeof props.disabled === "object" ? (jsx("div", { className: cvaSelectPrefixSuffix({ kind: "suffix" }), "data-testid": dataTestId ? `${dataTestId}-locked` : null, children: jsx(DisabledForReasonsTip, { ...props.disabled }) })) : null] }));
2413
+ return (jsxs("div", { className: cvaSelect({
2414
+ invalid: hasError,
2415
+ fieldSize: fieldSize,
2416
+ disabled: renderAsDisabled,
2417
+ className: props.className,
2418
+ }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined ? (jsx("div", { className: cvaSelectPrefixSuffix({ kind: "prefix" }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: refPrefix, children: prefix })) : null, async ? (jsx(ReactAsyncSelect, { ...props, ...reactSelectProps, ...async, menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : props.placeholder })) : (jsx(ReactSelect, { ...props, ...reactSelectProps, isMulti: isMulti, menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: options, placeholder: renderAsDisabled ? null : props.placeholder })), typeof props.disabled === "object" ? (jsx("div", { className: cvaSelectPrefixSuffix({ kind: "suffix" }), "data-testid": dataTestId ? `${dataTestId}-locked` : null, children: jsx(InputLockReasonTooltip, { ...props.disabled }) })) : null] }));
2326
2419
  };
2327
2420
  Select.displayName = "Select";
2328
2421
 
@@ -2483,12 +2576,8 @@ TextAreaField.displayName = "TextAreaField";
2483
2576
 
2484
2577
  /**
2485
2578
  * 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.
2486
- *
2487
- * _**Do use** when the user has to input or edit simple text based information, such as metadata._
2488
- *
2489
- * _**Do not use** to confirm user actions, such as deleting. Use a checkbox for such flows._
2490
2579
  */
2491
- const TextField = React.forwardRef(({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, dataTestId, ...rest }, ref) => {
2580
+ const TextField = React.forwardRef(({ id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, dataTestId, isWarning, ...rest }, ref) => {
2492
2581
  const [valueLength, setValueLength] = React.useState(value ? `${value}`.length : 0);
2493
2582
  const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
2494
2583
  const htmlFor = id ? id : "textField-" + uuidv4();
@@ -2499,7 +2588,7 @@ const TextField = React.forwardRef(({ id, label, tip, helpText, helpAddon, error
2499
2588
  }
2500
2589
  }, [onChange]);
2501
2590
  return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon ||
2502
- (typeof maxLength === "number" && 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: jsx(TextInput, { "aria-labelledby": htmlFor + "-label", id: htmlFor, isInvalid: renderAsInvalid, maxLength: maxLength, ref: ref, value: value, ...rest, className: className, dataTestId: dataTestId, onChange: handleChange }) }));
2591
+ (typeof maxLength === "number" && 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: 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 }) }));
2503
2592
  });
2504
2593
  TextField.displayName = "TextField";
2505
2594
 
@@ -2618,20 +2707,19 @@ const cvaUploadInputField = cvaMerge([
2618
2707
  "dark:text-gray-400",
2619
2708
  "self-center",
2620
2709
  ]);
2621
- const cvaUploadInputAddonBefore = cvaMerge(["block", "truncate", "w-28", "pt-2"]);
2622
2710
 
2623
2711
  /**
2624
2712
  * A thin wrapper around the `BaseInput` component for upload input fields.
2625
2713
  *
2626
2714
  * NOTE: If shown with a label, please use the `UploadField` component instead.
2627
2715
  */
2628
- const UploadInput = forwardRef(({ disabled, acceptedTypes, nonInteractive, uploadLabel, multipleFiles, ...rest }, ref) => (jsx("label", { className: "tu-upload-input", children: jsx(BaseInput, { accept: acceptedTypes, addonBefore: uploadLabel, addonBeforeClassName: cvaUploadInputAddonBefore(), disabled: disabled, inputClassName: cvaUploadInputField(), multiple: multipleFiles, nonInteractive: nonInteractive, onClick: event => {
2629
- // onClick used to work with nonInteractive option
2630
- if (nonInteractive) {
2631
- event.preventDefault();
2632
- event.stopPropagation();
2633
- }
2634
- }, ref: ref, type: "file", ...rest }) })));
2716
+ const UploadInput = forwardRef(({ disabled, acceptedTypes, nonInteractive, uploadLabel, multipleFiles, ...rest }, ref) => (jsx(BaseInput, { accept: acceptedTypes, addonBefore: uploadLabel, disabled: disabled, inputClassName: cvaUploadInputField(), multiple: multipleFiles, nonInteractive: nonInteractive, onClick: event => {
2717
+ // onClick used to work with nonInteractive option
2718
+ if (nonInteractive) {
2719
+ event.preventDefault();
2720
+ event.stopPropagation();
2721
+ }
2722
+ }, ref: ref, type: "file", ...rest })));
2635
2723
  UploadInput.displayName = "UploadInput";
2636
2724
 
2637
2725
  /**
@@ -2683,7 +2771,7 @@ const validateUrl = (url, required) => {
2683
2771
  const UrlInput = forwardRef(({ dataTestId, isInvalid, disabled = false, fieldSize = "medium", disableAction = false, value, defaultValue, ...rest }, ref) => {
2684
2772
  const [url, setUrl] = useState(value?.toString() || defaultValue?.toString());
2685
2773
  const renderAsInvalid = (url && typeof url === "string" && !validateUrlAddress(url)) || isInvalid;
2686
- return (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 && (jsx(ActionButton, { dataTestId: (dataTestId && `${dataTestId}-url-input-Icon`) || "url-input-action-icon", disabled: renderAsInvalid || disableAction, iconSize: fieldSize, type: "WEB_ADDRESS", value: url })) }));
2774
+ return (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 && (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 })) }));
2687
2775
  });
2688
2776
  UrlInput.displayName = "UrlField";
2689
2777
 
@@ -2823,4 +2911,4 @@ const useZodValidators = () => {
2823
2911
  */
2824
2912
  setupLibraryTranslations();
2825
2913
 
2826
- export { ActionButton, BaseInput, Checkbox, CheckboxField, ColorField, CreatableSelect, CreatableSelectField, DateField, DateInput, DropZone, DropZoneDefaultLabel, EMAIL_REGEX, EmailField, EmailInput, FormFieldSelectAdapter, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PasswordField, PasswordInput, PhoneField, PhoneFieldWithController, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SelectField, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField, Toggle, UploadField, UploadInput, UrlField, UrlInput, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaActionButton, cvaActionContainer, cvaInput, cvaInputAction, cvaInputAddon, cvaInputAddonAfter, cvaInputAddonBefore, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputField, cvaInputPrefix, cvaInputSuffix, cvaSelect, cvaSelectControl, cvaSelectCounter, cvaSelectDynamicTagContainer, cvaSelectIcon, cvaSelectMenu, cvaSelectMenuList, cvaSelectPrefixSuffix, cvaSelectXIcon, getCountryAbbreviation, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isValidHEXColor, parseSchedule, phoneErrorMessage, serializeSchedule, useCustomComponents, useGetPhoneValidationRules, usePhoneInput, useZodValidators, validateEmailAddress, validatePhoneNumber, weekDay };
2914
+ export { ActionButton, BaseInput, Checkbox, CheckboxField, ColorField, CreatableSelect, CreatableSelectField, DateField, DateInput, DropZone, DropZoneDefaultLabel, EMAIL_REGEX, EmailField, EmailInput, FormFieldSelectAdapter, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PasswordField, PasswordInput, PhoneField, PhoneFieldWithController, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SelectField, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField, Toggle, UploadField, UploadInput, UrlField, UrlInput, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaActionButton, cvaActionContainer, cvaInput, cvaInputAddon, cvaInputAddonAfter, cvaInputAddonBefore, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputField, cvaInputPrefix, cvaInputSuffix, cvaSelect, cvaSelectControl, cvaSelectCounter, cvaSelectDynamicTagContainer, cvaSelectIcon, cvaSelectMenu, cvaSelectMenuList, cvaSelectPrefixSuffix, cvaSelectXIcon, getCountryAbbreviation, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isValidHEXColor, parseSchedule, phoneErrorMessage, serializeSchedule, useCustomComponents, useGetPhoneValidationRules, usePhoneInput, useZodValidators, validateEmailAddress, validatePhoneNumber, weekDay };