@trackunit/react-form-components 0.0.460 → 0.0.462

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 CHANGED
@@ -10,7 +10,6 @@ var cssClassVarianceUtilities = require('@trackunit/css-class-variance-utilities
10
10
  var React = require('react');
11
11
  var uuid = require('uuid');
12
12
  var dateFns = require('date-fns');
13
- var isDate = require('rxjs/internal/util/isDate');
14
13
  var parsePhoneNumberFromString = require('libphonenumber-js');
15
14
  var reactHookForm = require('react-hook-form');
16
15
  var ReactSelect = require('react-select');
@@ -53,6 +52,8 @@ var defaultTranslations = {
53
52
  "clearIndicator.icon.tooltip.clearAll": "Clear all",
54
53
  "dropzone.input.title": "Drag-and-drop file input",
55
54
  "dropzone.label.default": "<clickable>Browse</clickable> or drag files here...",
55
+ "field.notEditable.tooltip": "This field is not editable",
56
+ "field.required.asterisk.tooltip": "This field is required",
56
57
  "phoneField.error.INVALID_COUNTRY": "The country code is not valid",
57
58
  "phoneField.error.INVALID_LENGTH": "The phone number is not valid",
58
59
  "phoneField.error.INVALID_NUMBER": "The phone number is not valid",
@@ -384,6 +385,22 @@ const cvaInputAction = cssClassVarianceUtilities.cvaMerge(["absolute", "end-0.5"
384
385
  ],
385
386
  });
386
387
 
388
+ /**
389
+ * Icon with explanation tooltip for why an input is locked or disabled.
390
+ * If locked, a permission lacks but the input **can** sometimes be edited.
391
+ * If disabled, the input **cannot** be edited and is only ever for displaying information.
392
+ *
393
+ * @param {DisabledForReasons} props - The reasons for the disabled state.
394
+ * @param {DisabledKind} kind - The kind of disabled state. If locked, the input can sometimes be edited. If disabled, the input cannot be edited.
395
+ */
396
+ const DisabledForReasonsTip = ({ reasons, kind }) => {
397
+ const [t] = useTranslation();
398
+ if (!reasons || reasons.length === 0) {
399
+ jsxRuntime.jsx(reactComponents.Tooltip, { label: t("field.notEditable.tooltip"), children: jsxRuntime.jsx(reactComponents.Icon, { name: kind === "disabled" ? "QuestionMarkCircle" : "LockClosed", size: "small" }) });
400
+ }
401
+ return (jsxRuntime.jsx(reactComponents.Tooltip, { label: jsxRuntime.jsx("ul", { className: typeof reasons === "string" || (reasons === null || reasons === void 0 ? void 0 : reasons.length) === 1 ? "list-inside" : "list-disc", children: typeof reasons === "string" ? jsxRuntime.jsx("li", { children: reasons }) : reasons === null || reasons === void 0 ? void 0 : reasons.map(reason => jsxRuntime.jsx("li", { children: reason }, reason)) }), placement: "top", children: jsxRuntime.jsx(reactComponents.Icon, { name: "LockClosed", size: "small" }) }));
402
+ };
403
+
387
404
  /**
388
405
  * A base input component that can be used for text inputs, password inputs, etc.
389
406
  * A reference to the input element is provided as the `ref` prop.
@@ -395,7 +412,7 @@ const cvaInputAction = cssClassVarianceUtilities.cvaMerge(["absolute", "end-0.5"
395
412
  const BaseInput = React__namespace.forwardRef((_a, ref) => {
396
413
  var _b;
397
414
  var { className, isInvalid, dataTestId, prefix, suffix, addonBefore, addonAfter, actions, fieldSize = "medium", nonInteractive = false, showDefaultActions = false, inputClassName, placeholder, addonBeforeClassName } = _a, rest = __rest(_a, ["className", "isInvalid", "dataTestId", "prefix", "suffix", "addonBefore", "addonAfter", "actions", "fieldSize", "nonInteractive", "showDefaultActions", "inputClassName", "placeholder", "addonBeforeClassName"]);
398
- const renderAsDisabled = rest.disabled || rest.readOnly;
415
+ const renderAsDisabled = Boolean(rest.disabled) || rest.readOnly;
399
416
  const innerRef = React__namespace.useRef(null);
400
417
  // eslint-disable-next-line local-rules/no-typescript-assertion
401
418
  React__namespace.useImperativeHandle(ref, () => innerRef.current, []);
@@ -414,7 +431,9 @@ const BaseInput = React__namespace.forwardRef((_a, ref) => {
414
431
  className: inputClassName,
415
432
  addonBefore: addonBefore !== undefined,
416
433
  prefix: !compareReactNodes(addonBefore, prefix),
417
- }), "data-testid": dataTestId, placeholder: renderAsDisabled ? undefined : placeholder, ref: innerRef }, rest, { disabled: renderAsDisabled, readOnly: rest.readOnly || nonInteractive })), suffix && addonBefore !== suffix ? (jsxRuntime.jsx("div", { className: cvaInputSuffix({
434
+ }), "data-testid": dataTestId, placeholder: renderAsDisabled ? undefined : placeholder, ref: innerRef }, rest, { disabled: renderAsDisabled, readOnly: rest.readOnly || nonInteractive })), typeof rest.disabled === "object" ? (jsxRuntime.jsx("div", { className: cvaInputSuffix({
435
+ disabled: false,
436
+ }), "data-testid": dataTestId ? `${dataTestId}-locked` : undefined, children: jsxRuntime.jsx(DisabledForReasonsTip, Object.assign({}, rest.disabled)) })) : null, suffix && addonBefore !== suffix ? (jsxRuntime.jsx("div", { className: cvaInputSuffix({
418
437
  disabled: renderAsDisabled,
419
438
  addonAfter: addonAfter !== undefined && !compareReactNodes(addonBefore, addonAfter),
420
439
  actions: (actions && !compareReactNodes(addonBefore, actions)) || false,
@@ -631,14 +650,7 @@ const Label = ({ id, htmlFor, children, className, dataTestId, disabled, isInval
631
650
  return (jsxRuntime.jsx("label", { className: cvaLabel({ invalid: isInvalid, disabled, className }), "data-testid": dataTestId, htmlFor: htmlFor || "", id: id || "", children: children }));
632
651
  };
633
652
 
634
- const cvaFormGroup = cssClassVarianceUtilities.cvaMerge(["component-formGroup-gap"], {
635
- variants: {
636
- disabled: {
637
- true: "pointer-events-none",
638
- false: "",
639
- },
640
- },
641
- });
653
+ const cvaFormGroup = cssClassVarianceUtilities.cvaMerge(["component-formGroup-gap"]);
642
654
  const cvaFormGroupContainerBefore = cssClassVarianceUtilities.cvaMerge(["flex", "mb-1", "items-center"]);
643
655
  const cvaFormGroupContainerAfter = cssClassVarianceUtilities.cvaMerge(["flex", "justify-between", "mt-1", "text-xs", "text-slate-500"], {
644
656
  variants: {
@@ -657,8 +669,9 @@ const cvaHelpAddon = cssClassVarianceUtilities.cvaMerge(["ml-auto"]);
657
669
  * @param {FormGroupProps} props - The props for the FormGroup component
658
670
  * @returns {JSX.Element} FormGroup component
659
671
  */
660
- const FormGroup = ({ isInvalid, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, tipIconProps, disabled = false, required = false, }) => {
661
- return (jsxRuntime.jsxs("div", { className: cvaFormGroup({ disabled, 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("span", { className: "required-asterisk", children: "*" }) : null] })) : null, tip ? (jsxRuntime.jsx(reactComponents.Tooltip, { className: "ml-1", dataTestId: dataTestId ? `${dataTestId}-tooltip` : undefined, iconProps: tipIconProps, label: tip, placement: "bottom" })) : null] }), children, jsxRuntime.jsxs("div", { className: cvaFormGroupContainerAfter({ invalid: isInvalid }), children: [helpText ? 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] })] }));
672
+ const FormGroup = ({ isInvalid, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, required = false, }) => {
673
+ const [t] = useTranslation();
674
+ 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, { dataTestId: dataTestId ? `${dataTestId}-tooltip` : undefined, label: tip, placement: "bottom" })) : null] }), children, jsxRuntime.jsxs("div", { className: cvaFormGroupContainerAfter({ invalid: isInvalid }), children: [helpText ? 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] })] }));
662
675
  };
663
676
 
664
677
  /**
@@ -669,7 +682,7 @@ const FormGroup = ({ isInvalid, helpText, helpAddon, tip, className, dataTestId,
669
682
  const CheckboxField = React.forwardRef((_a, ref) => {
670
683
  var { label, id, tip, helpText, helpAddon, isInvalid, className, checked, dataTestId, checkboxLabel, onChange } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "helpAddon", "isInvalid", "className", "checked", "dataTestId", "checkboxLabel", "onChange"]);
671
684
  const htmlForId = id ? id : "checkboxField-" + uuid.v4();
672
- return (jsxRuntime.jsx(FormGroup, { className: "flex flex-col gap-1", dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: rest.disabled, helpAddon: helpAddon, helpText: helpText, htmlFor: htmlForId, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(Checkbox, Object.assign({ checked: checked, className: className, dataTestId: dataTestId, id: htmlForId, label: checkboxLabel, onChange: onChange, ref: ref }, rest)) }));
685
+ return (jsxRuntime.jsx(FormGroup, { className: "flex flex-col gap-1", dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: helpText, htmlFor: htmlForId, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(Checkbox, Object.assign({ checked: checked, className: className, dataTestId: dataTestId, id: htmlForId, label: checkboxLabel, onChange: onChange, ref: ref }, rest)) }));
673
686
  });
674
687
  CheckboxField.displayName = "CheckboxField";
675
688
 
@@ -704,11 +717,11 @@ const ColorField = React.forwardRef((_a, ref) => {
704
717
  }
705
718
  }, [onChange]);
706
719
  const renderAsInvalid = !!errorMessage || (value && typeof value === "string" && !isValidHEXColor(value)) || isInvalid;
707
- return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsxs("div", { className: cvaInput({
720
+ return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsxs("div", { className: cvaInput({
708
721
  disabled: false,
709
722
  invalid: false,
710
723
  className,
711
- }), "data-testid": dataTestId ? `${dataTestId}-container` : null, children: [jsxRuntime.jsx("input", { "aria-labelledby": htmlForId + "-label-text", className: cvaInputField({ disabled: false }), "data-testid": dataTestId ? `${dataTestId}-textField` : null, onChange: handleChange, type: "text", value: value }), jsxRuntime.jsx("input", { "aria-labelledby": htmlForId + "-label", className: "mr-1 h-[25px] w-[25px] self-center bg-inherit", "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, onChange: handleChange, ref: innerRef, type: "color", value: value }), jsxRuntime.jsx(reactComponents.IconButton, { className: "mr-1 self-center", icon: jsxRuntime.jsx(reactComponents.Icon, { name: "Pencil", type: "outline" }), onClick: () => {
724
+ }), "data-testid": dataTestId ? `${dataTestId}-container` : undefined, children: [jsxRuntime.jsx("input", { "aria-labelledby": htmlForId + "-label-text", className: cvaInputField({ disabled: false }), "data-testid": dataTestId ? `${dataTestId}-textField` : undefined, onChange: handleChange, type: "text", value: value }), jsxRuntime.jsx("input", { "aria-labelledby": htmlForId + "-label", className: "mr-1 h-[25px] w-[25px] self-center bg-inherit", "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, onChange: handleChange, ref: innerRef, type: "color", value: value }), jsxRuntime.jsx(reactComponents.IconButton, { className: "mr-1 self-center", icon: jsxRuntime.jsx(reactComponents.Icon, { name: "Pencil", type: "outline" }), onClick: () => {
712
725
  if (innerRef.current) {
713
726
  innerRef.current.click();
714
727
  }
@@ -723,7 +736,7 @@ ColorField.displayName = "ColorField";
723
736
  */
724
737
  const DateInput = React.forwardRef((_a, ref) => {
725
738
  var { min, max, defaultValue, value } = _a, rest = __rest(_a, ["min", "max", "defaultValue", "value"]);
726
- const formatDateToInputString = (date) => isDate.isValidDate(date) ? dateFns.format(date, "yyyy-MM-dd") : date;
739
+ const formatDateToInputString = (date) => date instanceof Date ? dateFns.format(date, "yyyy-MM-dd") : date;
727
740
  // Chrome and Firefox need their default icon to have datepicker functionality.
728
741
  const showIcon = !/Chrome/.test(navigator.userAgent) && !/Firefox/.test(navigator.userAgent);
729
742
  return (jsxRuntime.jsx(BaseInput, Object.assign({ defaultValue: formatDateToInputString(defaultValue), max: formatDateToInputString(max), min: formatDateToInputString(min), ref: ref, suffix: showIcon ? jsxRuntime.jsx(reactComponents.Icon, { dataTestId: "calendar", name: "Calendar", size: "medium", type: "solid" }) : null, type: "date", value: formatDateToInputString(value) }, rest)));
@@ -741,7 +754,7 @@ const DateField = React.forwardRef((_a, ref) => {
741
754
  var { label, id, tip, helpText, errorMessage, helpAddon, isInvalid, className, defaultValue, dataTestId } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "errorMessage", "helpAddon", "isInvalid", "className", "defaultValue", "dataTestId"]);
742
755
  const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
743
756
  const htmlForId = id ? id : "dateField-" + uuid.v4();
744
- return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(DateInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref }, rest, { className: className, dataTestId: dataTestId })) }));
757
+ return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(DateInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref }, rest, { className: className, dataTestId: dataTestId })) }));
745
758
  });
746
759
  DateField.displayName = "DateField";
747
760
 
@@ -916,7 +929,7 @@ const EmailField = React.forwardRef((_a, ref) => {
916
929
  onChange(event);
917
930
  }
918
931
  }, [onChange]);
919
- return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(EmailInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, disabled: disabled, id: htmlForId, isInvalid: renderAsInvalid, onChange: handleChange, ref: ref, value: value }, rest, { className: className, dataTestId: dataTestId })) }));
932
+ return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(EmailInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, disabled: disabled, id: htmlForId, isInvalid: renderAsInvalid, onChange: handleChange, ref: ref, value: value }, rest, { className: className, dataTestId: dataTestId })) }));
920
933
  });
921
934
  EmailField.displayName = "EmailField";
922
935
 
@@ -1145,7 +1158,7 @@ const PhoneField = React.forwardRef((_a, ref) => {
1145
1158
  var { label, id, tip, helpText, isInvalid, errorMessage, value, helpAddon, className, defaultValue, dataTestId, name, onChange, onBlur } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "isInvalid", "errorMessage", "value", "helpAddon", "className", "defaultValue", "dataTestId", "name", "onChange", "onBlur"]);
1146
1159
  const htmlForId = id ? id : "phoneField-" + uuid.v4();
1147
1160
  const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
1148
- return (jsxRuntime.jsx(FormGroup, { className: className, dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(PhoneInput, Object.assign({ "aria-labelledby": htmlForId + "-label", dataTestId: dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, name: name, onBlur: onBlur, onChange: onChange, ref: ref, value: value }, rest)) }));
1161
+ return (jsxRuntime.jsx(FormGroup, { className: className, dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(PhoneInput, Object.assign({ "aria-labelledby": htmlForId + "-label", dataTestId: dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, name: name, onBlur: onBlur, onChange: onChange, ref: ref, value: value }, rest)) }));
1149
1162
  });
1150
1163
  PhoneField.displayName = "PhoneField";
1151
1164
 
@@ -1585,15 +1598,14 @@ const cvaSelectIcon = cssClassVarianceUtilities.cvaMerge([
1585
1598
  "text-slate-400",
1586
1599
  "hover:text-slate-500",
1587
1600
  ]);
1588
- const cvaSelectPrefix = cssClassVarianceUtilities.cvaMerge([
1589
- "flex",
1590
- "justify-center",
1591
- "items-center",
1592
- "text-slate-400",
1593
- "pl-2",
1594
- "absolute",
1595
- "inset-y-0",
1596
- ]);
1601
+ const cvaSelectPrefixSuffix = cssClassVarianceUtilities.cvaMerge(["flex", "justify-center", "items-center", "text-slate-400", "absolute", "inset-y-0"], {
1602
+ variants: {
1603
+ kind: {
1604
+ prefix: ["pl-3", "left-0"],
1605
+ suffix: ["pr-3", "right-0"],
1606
+ },
1607
+ },
1608
+ });
1597
1609
  const cvaSelectXIcon = cssClassVarianceUtilities.cvaMerge([
1598
1610
  "mr-2",
1599
1611
  "flex",
@@ -1784,10 +1796,12 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 5, postFix, disabled
1784
1796
  * @param {React.MutableRefObject<boolean>} refMenuIsEnabled a flag to block menu from open
1785
1797
  * @param {string} dataTestId a test id
1786
1798
  * @param {number} maxSelectedDisplayCount a number of max display count
1787
- * @param {JSX.Element} dropdownIcon an custom dropdown icon
1799
+ * @param {JSX.Element} dropdownIcon an custom dropdown icon
1800
+ * @param {boolean} hasError decide to override hasError variant
1801
+ * @param {JSX.Element} prefix a prefix element
1788
1802
  * @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
1789
1803
  */
1790
- const useCustomComponents = (componentsProps, disabled, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon, prefix, hasError) => {
1804
+ const useCustomComponents = ({ componentsProps, disabled, readOnly, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon, prefix, hasError, }) => {
1791
1805
  const [t] = useTranslation();
1792
1806
  // perhaps it should not be wrap in memo (causing some issues with opening and closing on mobiles)
1793
1807
  const customComponents = React__namespace.useMemo(() => {
@@ -1827,11 +1841,11 @@ const useCustomComponents = (componentsProps, disabled, menuIsOpen, refMenuIsEna
1827
1841
  : null, tags && tags.length > maxSelectedDisplayCount ? (jsxRuntime.jsxs(reactComponents.Tag, { color: "neutral", dataTestId: "counter-tag", children: ["+", tags.length - maxSelectedDisplayCount] })) : null, searchInput] })) })));
1828
1842
  }
1829
1843
  return (jsxRuntime.jsx(ReactSelect.components.ValueContainer, Object.assign({}, props, { isDisabled: props.selectProps.isDisabled, children: props.children })));
1830
- }, LoadingIndicator: props => {
1831
- return jsxRuntime.jsx(reactComponents.Spinner, { className: "mr-1 mt-1.5", size: "small" });
1844
+ }, LoadingIndicator: () => {
1845
+ return jsxRuntime.jsx(reactComponents.Spinner, { centering: "vertically", className: "mr-2", size: "small" });
1832
1846
  }, DropdownIndicator: props => {
1833
1847
  const icon = props.selectProps.menuIsOpen ? (jsxRuntime.jsx(reactComponents.Icon, { name: "ChevronUp", size: "medium" })) : (jsxRuntime.jsx(reactComponents.Icon, { name: "ChevronDown", size: "medium" }));
1834
- return props.selectProps.isLoading ? null : (jsxRuntime.jsx(ReactSelect.components.DropdownIndicator, Object.assign({}, props, { children: jsxRuntime.jsx("div", { className: cvaSelectIcon(), children: dropdownIcon ? dropdownIcon : icon }) })));
1848
+ return props.selectProps.isLoading || props.selectProps.isDisabled || readOnly ? null : (jsxRuntime.jsx(ReactSelect.components.DropdownIndicator, Object.assign({}, props, { children: jsxRuntime.jsx("div", { className: cvaSelectIcon(), children: dropdownIcon !== null && dropdownIcon !== void 0 ? dropdownIcon : icon }) })));
1835
1849
  }, IndicatorSeparator: () => null, ClearIndicator: props => {
1836
1850
  if (disabled) {
1837
1851
  return null;
@@ -1879,7 +1893,7 @@ const useCustomComponents = (componentsProps, disabled, menuIsOpen, refMenuIsEna
1879
1893
  * @param {StylesConfig<Option, IsMulti, Group> | undefined} styles a optional object to override styles of react-select
1880
1894
  * @returns {StylesConfig<Option, boolean>} styles to override in select
1881
1895
  */
1882
- const useCustomStyles = (refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled) => {
1896
+ const useCustomStyles = ({ refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled, }) => {
1883
1897
  const customStyles = React__namespace.useMemo(() => {
1884
1898
  return Object.assign({ control: base => {
1885
1899
  return Object.assign(Object.assign({}, base), { borderRadius: "var(--border-radius-lg)", backgroundColor: "" });
@@ -1887,7 +1901,7 @@ const useCustomStyles = (refContainer, refPrefix, maxSelectedDisplayCount, style
1887
1901
  width: "0px",
1888
1902
  }), menu: base => {
1889
1903
  return Object.assign(Object.assign({}, base), { width: "100%", marginTop: "4px", marginBottom: "18px", transition: "all 1s ease-in-out" });
1890
- }, input: base => (Object.assign(Object.assign({}, base), { marginLeft: "0px" })), placeholder: base => (Object.assign({}, base)), option: () => ({}), menuPortal: base => (Object.assign(Object.assign({}, base), { width: refContainer.current ? `${refContainer.current.clientWidth}px` : base.width, transform: "translate(0px, 0px)", backgroundColor: "#ffffff", borderRadius: "var(--border-radius-lg)", zIndex: 20, borderColor: "rgb(var(--color-slate-300))", boxShadow: "var(--tw-ring-inset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)" })), menuList: base => {
1904
+ }, input: base => (Object.assign(Object.assign({}, base), { marginLeft: "0px" })), placeholder: base => (Object.assign({}, base)), option: () => ({}), menuPortal: base => (Object.assign(Object.assign({}, base), { width: refContainer.current ? `${refContainer.current.clientWidth}px` : base.width, backgroundColor: "#ffffff", borderRadius: "var(--border-radius-lg)", zIndex: 20, borderColor: "rgb(var(--color-slate-300))", boxShadow: "var(--tw-ring-inset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)" })), menuList: base => {
1891
1905
  return Object.assign(Object.assign({}, base), { position: "relative", padding: "var(--spacing-1)", display: "grid", gap: "var(--spacing-1)", width: "100%", borderRadius: "0px", boxShadow: "none", paddingTop: "0px" });
1892
1906
  }, valueContainer: base => {
1893
1907
  return Object.assign(Object.assign({}, base), { flexWrap: maxSelectedDisplayCount !== undefined ? "wrap" : "nowrap", gap: "0.25rem" });
@@ -1903,20 +1917,36 @@ const useCustomStyles = (refContainer, refPrefix, maxSelectedDisplayCount, style
1903
1917
  * A hook used by selects to share the common code
1904
1918
  *
1905
1919
  * @param {SelectProps} props - The props for the Select component
1906
- * @returns {IUseSelect} Select component
1920
+ * @returns {UseSelectProps} Select component
1907
1921
  */
1908
1922
  const useSelect = (_a) => {
1909
1923
  var _b;
1910
1924
  var { id, className, dataTestId = "select", prefix, async, dropdownIcon, maxMenuHeight = 200, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix = "", onMenuOpen, onMenuClose, maxSelectedDisplayCount = undefined, isClearable = false, isSearchable = true, onMenuScrollToBottom, styles, filterOption, onInputChange } = _a, props = __rest(_a, ["id", "className", "dataTestId", "prefix", "async", "dropdownIcon", "maxMenuHeight", "label", "hasError", "disabled", "isMulti", "components", "value", "options", "onChange", "isLoading", "classNamePrefix", "onMenuOpen", "onMenuClose", "maxSelectedDisplayCount", "isClearable", "isSearchable", "onMenuScrollToBottom", "styles", "filterOption", "onInputChange"]);
1911
1925
  const refContainer = React__default["default"].useRef(null);
1912
1926
  const refPrefix = React__default["default"].useRef(null);
1913
- const { customStyles } = useCustomStyles(refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled);
1927
+ const { customStyles } = useCustomStyles({
1928
+ refContainer,
1929
+ refPrefix,
1930
+ maxSelectedDisplayCount,
1931
+ styles,
1932
+ disabled: Boolean(disabled),
1933
+ });
1914
1934
  const [menuIsOpen, setMenuIsOpen] = React__default["default"].useState((_b = props.menuIsOpen) !== null && _b !== void 0 ? _b : false);
1915
1935
  const refMenuIsEnabled = React__default["default"].useRef(true);
1916
- const customComponents = useCustomComponents(components, disabled || false, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon, prefix, hasError);
1936
+ const customComponents = useCustomComponents({
1937
+ componentsProps: components,
1938
+ disabled: Boolean(disabled),
1939
+ readOnly: Boolean(props.readOnly),
1940
+ refMenuIsEnabled,
1941
+ dataTestId,
1942
+ maxSelectedDisplayCount,
1943
+ dropdownIcon,
1944
+ prefix,
1945
+ hasError,
1946
+ });
1917
1947
  const menuPlacement = "auto";
1918
1948
  const openMenuHandler = () => __awaiter(void 0, void 0, void 0, function* () {
1919
- onMenuOpen && onMenuOpen();
1949
+ onMenuOpen === null || onMenuOpen === void 0 ? void 0 : onMenuOpen();
1920
1950
  if (refMenuIsEnabled.current) {
1921
1951
  setMenuIsOpen(true);
1922
1952
  }
@@ -1955,10 +1985,9 @@ const useSelect = (_a) => {
1955
1985
  * @returns {JSX.Element} CreatableSelect component
1956
1986
  */
1957
1987
  const CreatableSelect = (props) => {
1958
- const { className, placeholder } = props, rest = __rest(props, ["className", "placeholder"]);
1959
- const { id, dataTestId = "creatableSelect", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, value, options, onChange, isLoading, classNamePrefix = dataTestId, onMenuScrollToBottom, filterOption, onInputChange, isSearchable, isClearable = false, readOnly, openMenuOnClick = !disabled, openMenuOnFocus = !disabled, allowCreateWhileLoading, onCreateOption, } = rest;
1988
+ const { id, dataTestId = "creatableSelect", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, value, options, onChange, isLoading, classNamePrefix = "creatableSelect", onMenuScrollToBottom, filterOption, onInputChange, isSearchable, isClearable = false, readOnly, openMenuOnClick = !disabled, openMenuOnFocus = !disabled, allowCreateWhileLoading, onCreateOption, } = props;
1960
1989
  const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
1961
- const creatableSelectProps = {
1990
+ const reactCreatableSelectProps = React.useMemo(() => ({
1962
1991
  value,
1963
1992
  menuPlacement,
1964
1993
  maxMenuHeight,
@@ -1986,11 +2015,35 @@ const CreatableSelect = (props) => {
1986
2015
  onInputChange,
1987
2016
  allowCreateWhileLoading,
1988
2017
  onCreateOption,
1989
- isDisabled: disabled || props.isDisabled,
2018
+ isDisabled: Boolean(disabled),
2019
+ }), [
2020
+ allowCreateWhileLoading,
2021
+ classNamePrefix,
2022
+ customComponents,
2023
+ customStyles,
2024
+ dataTestId,
2025
+ disabled,
2026
+ id,
2027
+ isClearable,
2028
+ isLoading,
2029
+ isMulti,
2030
+ isSearchable,
2031
+ label,
2032
+ maxMenuHeight,
2033
+ menuIsOpen,
2034
+ menuPlacement,
2035
+ onChange,
2036
+ onCreateOption,
2037
+ onInputChange,
2038
+ onMenuScrollToBottom,
2039
+ openMenuOnClick,
2040
+ openMenuOnFocus,
2041
+ props.menuPortalTarget,
1990
2042
  readOnly,
1991
- };
1992
- const renderAsDisabled = rest.disabled || rest.readOnly || rest.isDisabled; // TODO remove one of the disable props from the type
1993
- return (jsxRuntime.jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: disabled || readOnly, className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined && (jsxRuntime.jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: refPrefix, children: prefix })), async ? (jsxRuntime.jsx(ReactAsyncCreatableSelect__default["default"], Object.assign({}, rest, creatableSelectProps, async, { onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : placeholder }))) : (jsxRuntime.jsx(ReactCreatableSelect__default["default"], Object.assign({}, rest, creatableSelectProps, { hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : options, placeholder: renderAsDisabled ? null : placeholder })))] }));
2043
+ value,
2044
+ ]);
2045
+ const renderAsDisabled = Boolean(props.disabled) || props.readOnly;
2046
+ 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__default["default"], Object.assign({}, props, reactCreatableSelectProps, async, { onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : props.placeholder }))) : (jsxRuntime.jsx(ReactCreatableSelect__default["default"], Object.assign({}, props, reactCreatableSelectProps, { hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : 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(DisabledForReasonsTip, Object.assign({}, props.disabled)) })) : null] }));
1994
2047
  };
1995
2048
  CreatableSelect.displayName = "CreatableSelect";
1996
2049
 
@@ -2001,10 +2054,9 @@ CreatableSelect.displayName = "CreatableSelect";
2001
2054
  * @returns {JSX.Element} Select component
2002
2055
  */
2003
2056
  const Select = (props) => {
2004
- const { className, placeholder } = props, rest = __rest(props, ["className", "placeholder"]);
2005
- const { id, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, menuPosition = "absolute", value, options, onChange, isLoading, classNamePrefix = dataTestId, onMenuScrollToBottom, filterOption, onInputChange, isSearchable, isClearable = false, readOnly, openMenuOnClick = !disabled, openMenuOnFocus = !disabled, hideSelectedOptions = false, } = props;
2057
+ const { id, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, menuPosition = "absolute", value, options, onChange, isLoading, classNamePrefix = "select", onMenuScrollToBottom, filterOption, onInputChange, isSearchable, isClearable = false, readOnly, openMenuOnClick = !disabled, openMenuOnFocus = !disabled, hideSelectedOptions = false, } = props;
2006
2058
  const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
2007
- const selectProps = {
2059
+ const reactSelectProps = React.useMemo(() => ({
2008
2060
  value,
2009
2061
  menuPlacement,
2010
2062
  maxMenuHeight,
@@ -2031,11 +2083,34 @@ const Select = (props) => {
2031
2083
  onMenuScrollToBottom,
2032
2084
  onInputChange,
2033
2085
  hideSelectedOptions,
2034
- isDisabled: disabled || props.isDisabled,
2086
+ isDisabled: Boolean(disabled),
2087
+ }), [
2088
+ classNamePrefix,
2089
+ customComponents,
2090
+ customStyles,
2091
+ dataTestId,
2092
+ disabled,
2093
+ hideSelectedOptions,
2094
+ id,
2095
+ isClearable,
2096
+ isLoading,
2097
+ isMulti,
2098
+ isSearchable,
2099
+ label,
2100
+ maxMenuHeight,
2101
+ menuIsOpen,
2102
+ menuPlacement,
2103
+ onChange,
2104
+ onInputChange,
2105
+ onMenuScrollToBottom,
2106
+ openMenuOnClick,
2107
+ openMenuOnFocus,
2108
+ props.menuPortalTarget,
2035
2109
  readOnly,
2036
- };
2037
- const renderAsDisabled = rest.disabled || rest.readOnly || rest.isDisabled; // TODO remove one of the disable props from the type
2038
- return (jsxRuntime.jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: disabled || readOnly, className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined && (jsxRuntime.jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: refPrefix, children: prefix })), async ? (jsxRuntime.jsx(ReactAsyncSelect__default["default"], Object.assign({}, rest, selectProps, async, { menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : placeholder }))) : (jsxRuntime.jsx(ReactSelect__default["default"], Object.assign({}, rest, selectProps, { isMulti: isMulti, menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : options, placeholder: renderAsDisabled ? null : placeholder })))] }));
2110
+ value,
2111
+ ]);
2112
+ const renderAsDisabled = Boolean(props.disabled) || props.readOnly;
2113
+ 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(ReactAsyncSelect__default["default"], Object.assign({}, props, reactSelectProps, async, { menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : props.placeholder }))) : (jsxRuntime.jsx(ReactSelect__default["default"], Object.assign({}, props, reactSelectProps, { isMulti: isMulti, menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : 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(DisabledForReasonsTip, Object.assign({}, props.disabled)) })) : null] }));
2039
2114
  };
2040
2115
  Select.displayName = "Select";
2041
2116
 
@@ -2078,10 +2153,11 @@ const FormFieldSelectAdapter = React.forwardRef((_a, ref) => {
2078
2153
  helpText: (renderAsInvalid && errorMessage) || helpText,
2079
2154
  helpAddon,
2080
2155
  tip,
2081
- label,
2082
- disabled, children: [jsxRuntime.jsx("select", { onChange, ref: innerRef, name, value: innerValue, hidden: true, children: optionsWithCurrentSelectionBackupOption.map(option => {
2156
+ label, children: [jsxRuntime.jsx("select", { onChange, ref: innerRef, name, value: innerValue, hidden: true, disabled: Boolean(disabled), children: optionsWithCurrentSelectionBackupOption.map(option => {
2083
2157
  return (jsxRuntime.jsx("option", { value: option.value, children: option.label }, option.value));
2084
- }) }), children(Object.assign(Object.assign({}, rest), { id, isDisabled: disabled, onBlur, options: optionsWithCurrentSelectionBackupOption, onChange: e => {
2158
+ }) }), children(Object.assign(Object.assign({}, rest), { id,
2159
+ disabled,
2160
+ onBlur, options: optionsWithCurrentSelectionBackupOption, onChange: e => {
2085
2161
  // If theres no value, set the inner value to an empty string
2086
2162
  // A native select can not have a null value
2087
2163
  // So even if react-select sends a null value, we need to convert it to an empty string
@@ -2222,10 +2298,10 @@ TextField.displayName = "TextField";
2222
2298
  * @returns {JSX.Element} TimeRangeField component
2223
2299
  */
2224
2300
  const TimeRangeField = (_a) => {
2225
- var { className, dataTestId, onChange, isInvalid, errorMessage, label, tip, disabled, children, helpText, id } = _a, rest = __rest(_a, ["className", "dataTestId", "onChange", "isInvalid", "errorMessage", "label", "tip", "disabled", "children", "helpText", "id"]);
2301
+ var { className, dataTestId, onChange, isInvalid, errorMessage, label, tip, children, helpText, id } = _a, rest = __rest(_a, ["className", "dataTestId", "onChange", "isInvalid", "errorMessage", "label", "tip", "children", "helpText", "id"]);
2226
2302
  const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
2227
2303
  const htmlFor = id ? id : "timeRangeField-" + uuid.v4();
2228
- return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: disabled, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsxRuntime.jsx(TimeRange, Object.assign({ className: className, dataTestId: dataTestId, disabled: disabled, isInvalid: renderAsInvalid, onChange: onChange }, rest, { children: children })) }));
2304
+ return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsxRuntime.jsx(TimeRange, Object.assign({ className: className, dataTestId: dataTestId, isInvalid: renderAsInvalid, onChange: onChange }, rest, { children: children })) }));
2229
2305
  };
2230
2306
 
2231
2307
  const cvaToggleWrapper = cssClassVarianceUtilities.cvaMerge(["flex", "gap-2", "items-center"]);
@@ -2379,7 +2455,7 @@ const UrlField = React.forwardRef((_a, ref) => {
2379
2455
  return typeof inputValue === "string";
2380
2456
  }
2381
2457
  const renderAsInvalid = !!errorMessage || (value && isString(value) && !validateUrlAddress(value)) || isInvalid;
2382
- return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: rest.disabled, helpAddon: helpAddon, helpText: renderAsInvalid ? errorMessage : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(UrlInput, Object.assign({ "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, ref: ref, value: value || defaultValue }, rest, { className: className, dataTestId: dataTestId })) }));
2458
+ return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? errorMessage : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxRuntime.jsx(UrlInput, Object.assign({ "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, ref: ref, value: value || defaultValue }, rest, { className: className, dataTestId: dataTestId })) }));
2383
2459
  });
2384
2460
  UrlField.displayName = "UrlField";
2385
2461
 
@@ -2556,7 +2632,7 @@ exports.cvaSelectDynamicTagContainer = cvaSelectDynamicTagContainer;
2556
2632
  exports.cvaSelectIcon = cvaSelectIcon;
2557
2633
  exports.cvaSelectMenu = cvaSelectMenu;
2558
2634
  exports.cvaSelectMenuList = cvaSelectMenuList;
2559
- exports.cvaSelectPrefix = cvaSelectPrefix;
2635
+ exports.cvaSelectPrefixSuffix = cvaSelectPrefixSuffix;
2560
2636
  exports.cvaSelectXIcon = cvaSelectXIcon;
2561
2637
  exports.getCountryAbbreviation = getCountryAbbreviation;
2562
2638
  exports.getOrderedOptions = getOrderedOptions;
package/index.esm.js CHANGED
@@ -7,7 +7,6 @@ import * as React from 'react';
7
7
  import React__default, { isValidElement, forwardRef, useState, useCallback, useRef, cloneElement, useEffect, useMemo, useImperativeHandle } from 'react';
8
8
  import { v4 } from 'uuid';
9
9
  import { format } from 'date-fns';
10
- import { isValidDate } from 'rxjs/internal/util/isDate';
11
10
  import parsePhoneNumberFromString, { isSupportedCountry, getCountries, getCountryCallingCode, AsYouType, parseIncompletePhoneNumber, isValidPhoneNumber } from 'libphonenumber-js';
12
11
  import { Controller } from 'react-hook-form';
13
12
  import ReactSelect, { components } from 'react-select';
@@ -23,6 +22,8 @@ var defaultTranslations = {
23
22
  "clearIndicator.icon.tooltip.clearAll": "Clear all",
24
23
  "dropzone.input.title": "Drag-and-drop file input",
25
24
  "dropzone.label.default": "<clickable>Browse</clickable> or drag files here...",
25
+ "field.notEditable.tooltip": "This field is not editable",
26
+ "field.required.asterisk.tooltip": "This field is required",
26
27
  "phoneField.error.INVALID_COUNTRY": "The country code is not valid",
27
28
  "phoneField.error.INVALID_LENGTH": "The phone number is not valid",
28
29
  "phoneField.error.INVALID_NUMBER": "The phone number is not valid",
@@ -354,6 +355,22 @@ const cvaInputAction = cvaMerge(["absolute", "end-0.5"], {
354
355
  ],
355
356
  });
356
357
 
358
+ /**
359
+ * Icon with explanation tooltip for why an input is locked or disabled.
360
+ * If locked, a permission lacks but the input **can** sometimes be edited.
361
+ * If disabled, the input **cannot** be edited and is only ever for displaying information.
362
+ *
363
+ * @param {DisabledForReasons} props - The reasons for the disabled state.
364
+ * @param {DisabledKind} kind - The kind of disabled state. If locked, the input can sometimes be edited. If disabled, the input cannot be edited.
365
+ */
366
+ const DisabledForReasonsTip = ({ reasons, kind }) => {
367
+ const [t] = useTranslation();
368
+ if (!reasons || reasons.length === 0) {
369
+ jsx(Tooltip, { label: t("field.notEditable.tooltip"), children: jsx(Icon, { name: kind === "disabled" ? "QuestionMarkCircle" : "LockClosed", size: "small" }) });
370
+ }
371
+ return (jsx(Tooltip, { label: jsx("ul", { className: typeof reasons === "string" || (reasons === null || reasons === void 0 ? void 0 : reasons.length) === 1 ? "list-inside" : "list-disc", children: typeof reasons === "string" ? jsx("li", { children: reasons }) : reasons === null || reasons === void 0 ? void 0 : reasons.map(reason => jsx("li", { children: reason }, reason)) }), placement: "top", children: jsx(Icon, { name: "LockClosed", size: "small" }) }));
372
+ };
373
+
357
374
  /**
358
375
  * A base input component that can be used for text inputs, password inputs, etc.
359
376
  * A reference to the input element is provided as the `ref` prop.
@@ -365,7 +382,7 @@ const cvaInputAction = cvaMerge(["absolute", "end-0.5"], {
365
382
  const BaseInput = React.forwardRef((_a, ref) => {
366
383
  var _b;
367
384
  var { className, isInvalid, dataTestId, prefix, suffix, addonBefore, addonAfter, actions, fieldSize = "medium", nonInteractive = false, showDefaultActions = false, inputClassName, placeholder, addonBeforeClassName } = _a, rest = __rest(_a, ["className", "isInvalid", "dataTestId", "prefix", "suffix", "addonBefore", "addonAfter", "actions", "fieldSize", "nonInteractive", "showDefaultActions", "inputClassName", "placeholder", "addonBeforeClassName"]);
368
- const renderAsDisabled = rest.disabled || rest.readOnly;
385
+ const renderAsDisabled = Boolean(rest.disabled) || rest.readOnly;
369
386
  const innerRef = React.useRef(null);
370
387
  // eslint-disable-next-line local-rules/no-typescript-assertion
371
388
  React.useImperativeHandle(ref, () => innerRef.current, []);
@@ -384,7 +401,9 @@ const BaseInput = React.forwardRef((_a, ref) => {
384
401
  className: inputClassName,
385
402
  addonBefore: addonBefore !== undefined,
386
403
  prefix: !compareReactNodes(addonBefore, prefix),
387
- }), "data-testid": dataTestId, placeholder: renderAsDisabled ? undefined : placeholder, ref: innerRef }, rest, { disabled: renderAsDisabled, readOnly: rest.readOnly || nonInteractive })), suffix && addonBefore !== suffix ? (jsx("div", { className: cvaInputSuffix({
404
+ }), "data-testid": dataTestId, placeholder: renderAsDisabled ? undefined : placeholder, ref: innerRef }, rest, { disabled: renderAsDisabled, readOnly: rest.readOnly || nonInteractive })), typeof rest.disabled === "object" ? (jsx("div", { className: cvaInputSuffix({
405
+ disabled: false,
406
+ }), "data-testid": dataTestId ? `${dataTestId}-locked` : undefined, children: jsx(DisabledForReasonsTip, Object.assign({}, rest.disabled)) })) : null, suffix && addonBefore !== suffix ? (jsx("div", { className: cvaInputSuffix({
388
407
  disabled: renderAsDisabled,
389
408
  addonAfter: addonAfter !== undefined && !compareReactNodes(addonBefore, addonAfter),
390
409
  actions: (actions && !compareReactNodes(addonBefore, actions)) || false,
@@ -601,14 +620,7 @@ const Label = ({ id, htmlFor, children, className, dataTestId, disabled, isInval
601
620
  return (jsx("label", { className: cvaLabel({ invalid: isInvalid, disabled, className }), "data-testid": dataTestId, htmlFor: htmlFor || "", id: id || "", children: children }));
602
621
  };
603
622
 
604
- const cvaFormGroup = cvaMerge(["component-formGroup-gap"], {
605
- variants: {
606
- disabled: {
607
- true: "pointer-events-none",
608
- false: "",
609
- },
610
- },
611
- });
623
+ const cvaFormGroup = cvaMerge(["component-formGroup-gap"]);
612
624
  const cvaFormGroupContainerBefore = cvaMerge(["flex", "mb-1", "items-center"]);
613
625
  const cvaFormGroupContainerAfter = cvaMerge(["flex", "justify-between", "mt-1", "text-xs", "text-slate-500"], {
614
626
  variants: {
@@ -627,8 +639,9 @@ const cvaHelpAddon = cvaMerge(["ml-auto"]);
627
639
  * @param {FormGroupProps} props - The props for the FormGroup component
628
640
  * @returns {JSX.Element} FormGroup component
629
641
  */
630
- const FormGroup = ({ isInvalid, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, tipIconProps, disabled = false, required = false, }) => {
631
- return (jsxs("div", { className: cvaFormGroup({ disabled, 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("span", { className: "required-asterisk", children: "*" }) : null] })) : null, tip ? (jsx(Tooltip, { className: "ml-1", dataTestId: dataTestId ? `${dataTestId}-tooltip` : undefined, iconProps: tipIconProps, label: tip, placement: "bottom" })) : null] }), children, 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] })] }));
642
+ const FormGroup = ({ isInvalid, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, required = false, }) => {
643
+ const [t] = useTranslation();
644
+ 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, 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] })] }));
632
645
  };
633
646
 
634
647
  /**
@@ -639,7 +652,7 @@ const FormGroup = ({ isInvalid, helpText, helpAddon, tip, className, dataTestId,
639
652
  const CheckboxField = forwardRef((_a, ref) => {
640
653
  var { label, id, tip, helpText, helpAddon, isInvalid, className, checked, dataTestId, checkboxLabel, onChange } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "helpAddon", "isInvalid", "className", "checked", "dataTestId", "checkboxLabel", "onChange"]);
641
654
  const htmlForId = id ? id : "checkboxField-" + v4();
642
- return (jsx(FormGroup, { className: "flex flex-col gap-1", dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: rest.disabled, helpAddon: helpAddon, helpText: helpText, htmlFor: htmlForId, label: label, required: rest.required, tip: tip, children: jsx(Checkbox, Object.assign({ checked: checked, className: className, dataTestId: dataTestId, id: htmlForId, label: checkboxLabel, onChange: onChange, ref: ref }, rest)) }));
655
+ return (jsx(FormGroup, { className: "flex flex-col gap-1", dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: helpText, htmlFor: htmlForId, label: label, required: rest.required, tip: tip, children: jsx(Checkbox, Object.assign({ checked: checked, className: className, dataTestId: dataTestId, id: htmlForId, label: checkboxLabel, onChange: onChange, ref: ref }, rest)) }));
643
656
  });
644
657
  CheckboxField.displayName = "CheckboxField";
645
658
 
@@ -674,11 +687,11 @@ const ColorField = forwardRef((_a, ref) => {
674
687
  }
675
688
  }, [onChange]);
676
689
  const renderAsInvalid = !!errorMessage || (value && typeof value === "string" && !isValidHEXColor(value)) || isInvalid;
677
- return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxs("div", { className: cvaInput({
690
+ return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsxs("div", { className: cvaInput({
678
691
  disabled: false,
679
692
  invalid: false,
680
693
  className,
681
- }), "data-testid": dataTestId ? `${dataTestId}-container` : null, children: [jsx("input", { "aria-labelledby": htmlForId + "-label-text", className: cvaInputField({ disabled: false }), "data-testid": dataTestId ? `${dataTestId}-textField` : null, onChange: handleChange, type: "text", value: value }), jsx("input", { "aria-labelledby": htmlForId + "-label", className: "mr-1 h-[25px] w-[25px] self-center bg-inherit", "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, onChange: handleChange, ref: innerRef, type: "color", value: value }), jsx(IconButton, { className: "mr-1 self-center", icon: jsx(Icon, { name: "Pencil", type: "outline" }), onClick: () => {
694
+ }), "data-testid": dataTestId ? `${dataTestId}-container` : undefined, children: [jsx("input", { "aria-labelledby": htmlForId + "-label-text", className: cvaInputField({ disabled: false }), "data-testid": dataTestId ? `${dataTestId}-textField` : undefined, onChange: handleChange, type: "text", value: value }), jsx("input", { "aria-labelledby": htmlForId + "-label", className: "mr-1 h-[25px] w-[25px] self-center bg-inherit", "data-testid": dataTestId, defaultValue: defaultValue, id: htmlForId, onChange: handleChange, ref: innerRef, type: "color", value: value }), jsx(IconButton, { className: "mr-1 self-center", icon: jsx(Icon, { name: "Pencil", type: "outline" }), onClick: () => {
682
695
  if (innerRef.current) {
683
696
  innerRef.current.click();
684
697
  }
@@ -693,7 +706,7 @@ ColorField.displayName = "ColorField";
693
706
  */
694
707
  const DateInput = forwardRef((_a, ref) => {
695
708
  var { min, max, defaultValue, value } = _a, rest = __rest(_a, ["min", "max", "defaultValue", "value"]);
696
- const formatDateToInputString = (date) => isValidDate(date) ? format(date, "yyyy-MM-dd") : date;
709
+ const formatDateToInputString = (date) => date instanceof Date ? format(date, "yyyy-MM-dd") : date;
697
710
  // Chrome and Firefox need their default icon to have datepicker functionality.
698
711
  const showIcon = !/Chrome/.test(navigator.userAgent) && !/Firefox/.test(navigator.userAgent);
699
712
  return (jsx(BaseInput, Object.assign({ defaultValue: formatDateToInputString(defaultValue), max: formatDateToInputString(max), min: formatDateToInputString(min), ref: ref, suffix: showIcon ? jsx(Icon, { dataTestId: "calendar", name: "Calendar", size: "medium", type: "solid" }) : null, type: "date", value: formatDateToInputString(value) }, rest)));
@@ -711,7 +724,7 @@ const DateField = forwardRef((_a, ref) => {
711
724
  var { label, id, tip, helpText, errorMessage, helpAddon, isInvalid, className, defaultValue, dataTestId } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "errorMessage", "helpAddon", "isInvalid", "className", "defaultValue", "dataTestId"]);
712
725
  const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
713
726
  const htmlForId = id ? id : "dateField-" + v4();
714
- return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(DateInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref }, rest, { className: className, dataTestId: dataTestId })) }));
727
+ return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(DateInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, ref: ref }, rest, { className: className, dataTestId: dataTestId })) }));
715
728
  });
716
729
  DateField.displayName = "DateField";
717
730
 
@@ -886,7 +899,7 @@ const EmailField = forwardRef((_a, ref) => {
886
899
  onChange(event);
887
900
  }
888
901
  }, [onChange]);
889
- return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(EmailInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, disabled: disabled, id: htmlForId, isInvalid: renderAsInvalid, onChange: handleChange, ref: ref, value: value }, rest, { className: className, dataTestId: dataTestId })) }));
902
+ return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(EmailInput, Object.assign({ "aria-labelledby": htmlForId + "-label", defaultValue: defaultValue, disabled: disabled, id: htmlForId, isInvalid: renderAsInvalid, onChange: handleChange, ref: ref, value: value }, rest, { className: className, dataTestId: dataTestId })) }));
890
903
  });
891
904
  EmailField.displayName = "EmailField";
892
905
 
@@ -1115,7 +1128,7 @@ const PhoneField = forwardRef((_a, ref) => {
1115
1128
  var { label, id, tip, helpText, isInvalid, errorMessage, value, helpAddon, className, defaultValue, dataTestId, name, onChange, onBlur } = _a, rest = __rest(_a, ["label", "id", "tip", "helpText", "isInvalid", "errorMessage", "value", "helpAddon", "className", "defaultValue", "dataTestId", "name", "onChange", "onBlur"]);
1116
1129
  const htmlForId = id ? id : "phoneField-" + v4();
1117
1130
  const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
1118
- return (jsx(FormGroup, { className: className, dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: rest.disabled, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(PhoneInput, Object.assign({ "aria-labelledby": htmlForId + "-label", dataTestId: dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, name: name, onBlur: onBlur, onChange: onChange, ref: ref, value: value }, rest)) }));
1131
+ return (jsx(FormGroup, { className: className, dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(PhoneInput, Object.assign({ "aria-labelledby": htmlForId + "-label", dataTestId: dataTestId, defaultValue: defaultValue, id: htmlForId, isInvalid: renderAsInvalid, name: name, onBlur: onBlur, onChange: onChange, ref: ref, value: value }, rest)) }));
1119
1132
  });
1120
1133
  PhoneField.displayName = "PhoneField";
1121
1134
 
@@ -1555,15 +1568,14 @@ const cvaSelectIcon = cvaMerge([
1555
1568
  "text-slate-400",
1556
1569
  "hover:text-slate-500",
1557
1570
  ]);
1558
- const cvaSelectPrefix = cvaMerge([
1559
- "flex",
1560
- "justify-center",
1561
- "items-center",
1562
- "text-slate-400",
1563
- "pl-2",
1564
- "absolute",
1565
- "inset-y-0",
1566
- ]);
1571
+ const cvaSelectPrefixSuffix = cvaMerge(["flex", "justify-center", "items-center", "text-slate-400", "absolute", "inset-y-0"], {
1572
+ variants: {
1573
+ kind: {
1574
+ prefix: ["pl-3", "left-0"],
1575
+ suffix: ["pr-3", "right-0"],
1576
+ },
1577
+ },
1578
+ });
1567
1579
  const cvaSelectXIcon = cvaMerge([
1568
1580
  "mr-2",
1569
1581
  "flex",
@@ -1754,10 +1766,12 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 5, postFix, disabled
1754
1766
  * @param {React.MutableRefObject<boolean>} refMenuIsEnabled a flag to block menu from open
1755
1767
  * @param {string} dataTestId a test id
1756
1768
  * @param {number} maxSelectedDisplayCount a number of max display count
1757
- * @param {JSX.Element} dropdownIcon an custom dropdown icon
1769
+ * @param {JSX.Element} dropdownIcon an custom dropdown icon
1770
+ * @param {boolean} hasError decide to override hasError variant
1771
+ * @param {JSX.Element} prefix a prefix element
1758
1772
  * @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
1759
1773
  */
1760
- const useCustomComponents = (componentsProps, disabled, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon, prefix, hasError) => {
1774
+ const useCustomComponents = ({ componentsProps, disabled, readOnly, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon, prefix, hasError, }) => {
1761
1775
  const [t] = useTranslation();
1762
1776
  // perhaps it should not be wrap in memo (causing some issues with opening and closing on mobiles)
1763
1777
  const customComponents = React.useMemo(() => {
@@ -1797,11 +1811,11 @@ const useCustomComponents = (componentsProps, disabled, menuIsOpen, refMenuIsEna
1797
1811
  : null, tags && tags.length > maxSelectedDisplayCount ? (jsxs(Tag, { color: "neutral", dataTestId: "counter-tag", children: ["+", tags.length - maxSelectedDisplayCount] })) : null, searchInput] })) })));
1798
1812
  }
1799
1813
  return (jsx(components.ValueContainer, Object.assign({}, props, { isDisabled: props.selectProps.isDisabled, children: props.children })));
1800
- }, LoadingIndicator: props => {
1801
- return jsx(Spinner, { className: "mr-1 mt-1.5", size: "small" });
1814
+ }, LoadingIndicator: () => {
1815
+ return jsx(Spinner, { centering: "vertically", className: "mr-2", size: "small" });
1802
1816
  }, DropdownIndicator: props => {
1803
1817
  const icon = props.selectProps.menuIsOpen ? (jsx(Icon, { name: "ChevronUp", size: "medium" })) : (jsx(Icon, { name: "ChevronDown", size: "medium" }));
1804
- return props.selectProps.isLoading ? null : (jsx(components.DropdownIndicator, Object.assign({}, props, { children: jsx("div", { className: cvaSelectIcon(), children: dropdownIcon ? dropdownIcon : icon }) })));
1818
+ return props.selectProps.isLoading || props.selectProps.isDisabled || readOnly ? null : (jsx(components.DropdownIndicator, Object.assign({}, props, { children: jsx("div", { className: cvaSelectIcon(), children: dropdownIcon !== null && dropdownIcon !== void 0 ? dropdownIcon : icon }) })));
1805
1819
  }, IndicatorSeparator: () => null, ClearIndicator: props => {
1806
1820
  if (disabled) {
1807
1821
  return null;
@@ -1849,7 +1863,7 @@ const useCustomComponents = (componentsProps, disabled, menuIsOpen, refMenuIsEna
1849
1863
  * @param {StylesConfig<Option, IsMulti, Group> | undefined} styles a optional object to override styles of react-select
1850
1864
  * @returns {StylesConfig<Option, boolean>} styles to override in select
1851
1865
  */
1852
- const useCustomStyles = (refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled) => {
1866
+ const useCustomStyles = ({ refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled, }) => {
1853
1867
  const customStyles = React.useMemo(() => {
1854
1868
  return Object.assign({ control: base => {
1855
1869
  return Object.assign(Object.assign({}, base), { borderRadius: "var(--border-radius-lg)", backgroundColor: "" });
@@ -1857,7 +1871,7 @@ const useCustomStyles = (refContainer, refPrefix, maxSelectedDisplayCount, style
1857
1871
  width: "0px",
1858
1872
  }), menu: base => {
1859
1873
  return Object.assign(Object.assign({}, base), { width: "100%", marginTop: "4px", marginBottom: "18px", transition: "all 1s ease-in-out" });
1860
- }, input: base => (Object.assign(Object.assign({}, base), { marginLeft: "0px" })), placeholder: base => (Object.assign({}, base)), option: () => ({}), menuPortal: base => (Object.assign(Object.assign({}, base), { width: refContainer.current ? `${refContainer.current.clientWidth}px` : base.width, transform: "translate(0px, 0px)", backgroundColor: "#ffffff", borderRadius: "var(--border-radius-lg)", zIndex: 20, borderColor: "rgb(var(--color-slate-300))", boxShadow: "var(--tw-ring-inset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)" })), menuList: base => {
1874
+ }, input: base => (Object.assign(Object.assign({}, base), { marginLeft: "0px" })), placeholder: base => (Object.assign({}, base)), option: () => ({}), menuPortal: base => (Object.assign(Object.assign({}, base), { width: refContainer.current ? `${refContainer.current.clientWidth}px` : base.width, backgroundColor: "#ffffff", borderRadius: "var(--border-radius-lg)", zIndex: 20, borderColor: "rgb(var(--color-slate-300))", boxShadow: "var(--tw-ring-inset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)" })), menuList: base => {
1861
1875
  return Object.assign(Object.assign({}, base), { position: "relative", padding: "var(--spacing-1)", display: "grid", gap: "var(--spacing-1)", width: "100%", borderRadius: "0px", boxShadow: "none", paddingTop: "0px" });
1862
1876
  }, valueContainer: base => {
1863
1877
  return Object.assign(Object.assign({}, base), { flexWrap: maxSelectedDisplayCount !== undefined ? "wrap" : "nowrap", gap: "0.25rem" });
@@ -1873,20 +1887,36 @@ const useCustomStyles = (refContainer, refPrefix, maxSelectedDisplayCount, style
1873
1887
  * A hook used by selects to share the common code
1874
1888
  *
1875
1889
  * @param {SelectProps} props - The props for the Select component
1876
- * @returns {IUseSelect} Select component
1890
+ * @returns {UseSelectProps} Select component
1877
1891
  */
1878
1892
  const useSelect = (_a) => {
1879
1893
  var _b;
1880
1894
  var { id, className, dataTestId = "select", prefix, async, dropdownIcon, maxMenuHeight = 200, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix = "", onMenuOpen, onMenuClose, maxSelectedDisplayCount = undefined, isClearable = false, isSearchable = true, onMenuScrollToBottom, styles, filterOption, onInputChange } = _a, props = __rest(_a, ["id", "className", "dataTestId", "prefix", "async", "dropdownIcon", "maxMenuHeight", "label", "hasError", "disabled", "isMulti", "components", "value", "options", "onChange", "isLoading", "classNamePrefix", "onMenuOpen", "onMenuClose", "maxSelectedDisplayCount", "isClearable", "isSearchable", "onMenuScrollToBottom", "styles", "filterOption", "onInputChange"]);
1881
1895
  const refContainer = React__default.useRef(null);
1882
1896
  const refPrefix = React__default.useRef(null);
1883
- const { customStyles } = useCustomStyles(refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled);
1897
+ const { customStyles } = useCustomStyles({
1898
+ refContainer,
1899
+ refPrefix,
1900
+ maxSelectedDisplayCount,
1901
+ styles,
1902
+ disabled: Boolean(disabled),
1903
+ });
1884
1904
  const [menuIsOpen, setMenuIsOpen] = React__default.useState((_b = props.menuIsOpen) !== null && _b !== void 0 ? _b : false);
1885
1905
  const refMenuIsEnabled = React__default.useRef(true);
1886
- const customComponents = useCustomComponents(components, disabled || false, menuIsOpen, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon, prefix, hasError);
1906
+ const customComponents = useCustomComponents({
1907
+ componentsProps: components,
1908
+ disabled: Boolean(disabled),
1909
+ readOnly: Boolean(props.readOnly),
1910
+ refMenuIsEnabled,
1911
+ dataTestId,
1912
+ maxSelectedDisplayCount,
1913
+ dropdownIcon,
1914
+ prefix,
1915
+ hasError,
1916
+ });
1887
1917
  const menuPlacement = "auto";
1888
1918
  const openMenuHandler = () => __awaiter(void 0, void 0, void 0, function* () {
1889
- onMenuOpen && onMenuOpen();
1919
+ onMenuOpen === null || onMenuOpen === void 0 ? void 0 : onMenuOpen();
1890
1920
  if (refMenuIsEnabled.current) {
1891
1921
  setMenuIsOpen(true);
1892
1922
  }
@@ -1925,10 +1955,9 @@ const useSelect = (_a) => {
1925
1955
  * @returns {JSX.Element} CreatableSelect component
1926
1956
  */
1927
1957
  const CreatableSelect = (props) => {
1928
- const { className, placeholder } = props, rest = __rest(props, ["className", "placeholder"]);
1929
- const { id, dataTestId = "creatableSelect", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, value, options, onChange, isLoading, classNamePrefix = dataTestId, onMenuScrollToBottom, filterOption, onInputChange, isSearchable, isClearable = false, readOnly, openMenuOnClick = !disabled, openMenuOnFocus = !disabled, allowCreateWhileLoading, onCreateOption, } = rest;
1958
+ const { id, dataTestId = "creatableSelect", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, value, options, onChange, isLoading, classNamePrefix = "creatableSelect", onMenuScrollToBottom, filterOption, onInputChange, isSearchable, isClearable = false, readOnly, openMenuOnClick = !disabled, openMenuOnFocus = !disabled, allowCreateWhileLoading, onCreateOption, } = props;
1930
1959
  const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
1931
- const creatableSelectProps = {
1960
+ const reactCreatableSelectProps = useMemo(() => ({
1932
1961
  value,
1933
1962
  menuPlacement,
1934
1963
  maxMenuHeight,
@@ -1956,11 +1985,35 @@ const CreatableSelect = (props) => {
1956
1985
  onInputChange,
1957
1986
  allowCreateWhileLoading,
1958
1987
  onCreateOption,
1959
- isDisabled: disabled || props.isDisabled,
1988
+ isDisabled: Boolean(disabled),
1989
+ }), [
1990
+ allowCreateWhileLoading,
1991
+ classNamePrefix,
1992
+ customComponents,
1993
+ customStyles,
1994
+ dataTestId,
1995
+ disabled,
1996
+ id,
1997
+ isClearable,
1998
+ isLoading,
1999
+ isMulti,
2000
+ isSearchable,
2001
+ label,
2002
+ maxMenuHeight,
2003
+ menuIsOpen,
2004
+ menuPlacement,
2005
+ onChange,
2006
+ onCreateOption,
2007
+ onInputChange,
2008
+ onMenuScrollToBottom,
2009
+ openMenuOnClick,
2010
+ openMenuOnFocus,
2011
+ props.menuPortalTarget,
1960
2012
  readOnly,
1961
- };
1962
- const renderAsDisabled = rest.disabled || rest.readOnly || rest.isDisabled; // TODO remove one of the disable props from the type
1963
- return (jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: disabled || readOnly, className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined && (jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: refPrefix, children: prefix })), async ? (jsx(ReactAsyncCreatableSelect, Object.assign({}, rest, creatableSelectProps, async, { onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : placeholder }))) : (jsx(ReactCreatableSelect, Object.assign({}, rest, creatableSelectProps, { hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : options, placeholder: renderAsDisabled ? null : placeholder })))] }));
2013
+ value,
2014
+ ]);
2015
+ const renderAsDisabled = Boolean(props.disabled) || props.readOnly;
2016
+ 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, Object.assign({}, props, reactCreatableSelectProps, async, { onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : props.placeholder }))) : (jsx(ReactCreatableSelect, Object.assign({}, props, reactCreatableSelectProps, { hideSelectedOptions: false, isMulti: isMulti, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : 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, Object.assign({}, props.disabled)) })) : null] }));
1964
2017
  };
1965
2018
  CreatableSelect.displayName = "CreatableSelect";
1966
2019
 
@@ -1971,10 +2024,9 @@ CreatableSelect.displayName = "CreatableSelect";
1971
2024
  * @returns {JSX.Element} Select component
1972
2025
  */
1973
2026
  const Select = (props) => {
1974
- const { className, placeholder } = props, rest = __rest(props, ["className", "placeholder"]);
1975
- const { id, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, menuPosition = "absolute", value, options, onChange, isLoading, classNamePrefix = dataTestId, onMenuScrollToBottom, filterOption, onInputChange, isSearchable, isClearable = false, readOnly, openMenuOnClick = !disabled, openMenuOnFocus = !disabled, hideSelectedOptions = false, } = props;
2027
+ const { id, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, menuPosition = "absolute", value, options, onChange, isLoading, classNamePrefix = "select", onMenuScrollToBottom, filterOption, onInputChange, isSearchable, isClearable = false, readOnly, openMenuOnClick = !disabled, openMenuOnFocus = !disabled, hideSelectedOptions = false, } = props;
1976
2028
  const { refContainer, refPrefix, customStyles, menuIsOpen, customComponents, menuPlacement, openMenuHandler, closeMenuHandler, orderedOptions, } = useSelect(props);
1977
- const selectProps = {
2029
+ const reactSelectProps = useMemo(() => ({
1978
2030
  value,
1979
2031
  menuPlacement,
1980
2032
  maxMenuHeight,
@@ -2001,11 +2053,34 @@ const Select = (props) => {
2001
2053
  onMenuScrollToBottom,
2002
2054
  onInputChange,
2003
2055
  hideSelectedOptions,
2004
- isDisabled: disabled || props.isDisabled,
2056
+ isDisabled: Boolean(disabled),
2057
+ }), [
2058
+ classNamePrefix,
2059
+ customComponents,
2060
+ customStyles,
2061
+ dataTestId,
2062
+ disabled,
2063
+ hideSelectedOptions,
2064
+ id,
2065
+ isClearable,
2066
+ isLoading,
2067
+ isMulti,
2068
+ isSearchable,
2069
+ label,
2070
+ maxMenuHeight,
2071
+ menuIsOpen,
2072
+ menuPlacement,
2073
+ onChange,
2074
+ onInputChange,
2075
+ onMenuScrollToBottom,
2076
+ openMenuOnClick,
2077
+ openMenuOnFocus,
2078
+ props.menuPortalTarget,
2005
2079
  readOnly,
2006
- };
2007
- const renderAsDisabled = rest.disabled || rest.readOnly || rest.isDisabled; // TODO remove one of the disable props from the type
2008
- return (jsxs("div", { className: cvaSelect({ invalid: hasError, disabled: disabled || readOnly, className }), "data-testid": dataTestId, ref: refContainer, children: [prefix !== undefined && (jsx("div", { className: cvaSelectPrefix(), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, ref: refPrefix, children: prefix })), async ? (jsx(ReactAsyncSelect, Object.assign({}, rest, selectProps, async, { menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : placeholder }))) : (jsx(ReactSelect, Object.assign({}, rest, selectProps, { isMulti: isMulti, menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : options, placeholder: renderAsDisabled ? null : placeholder })))] }));
2080
+ value,
2081
+ ]);
2082
+ const renderAsDisabled = Boolean(props.disabled) || props.readOnly;
2083
+ 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, Object.assign({}, props, reactSelectProps, async, { menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, placeholder: renderAsDisabled ? null : props.placeholder }))) : (jsx(ReactSelect, Object.assign({}, props, reactSelectProps, { isMulti: isMulti, menuPosition: menuPosition, onMenuClose: closeMenuHandler, onMenuOpen: openMenuHandler, options: filterOption ? orderedOptions : 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, Object.assign({}, props.disabled)) })) : null] }));
2009
2084
  };
2010
2085
  Select.displayName = "Select";
2011
2086
 
@@ -2048,10 +2123,11 @@ const FormFieldSelectAdapter = forwardRef((_a, ref) => {
2048
2123
  helpText: (renderAsInvalid && errorMessage) || helpText,
2049
2124
  helpAddon,
2050
2125
  tip,
2051
- label,
2052
- disabled, children: [jsx("select", { onChange, ref: innerRef, name, value: innerValue, hidden: true, children: optionsWithCurrentSelectionBackupOption.map(option => {
2126
+ label, children: [jsx("select", { onChange, ref: innerRef, name, value: innerValue, hidden: true, disabled: Boolean(disabled), children: optionsWithCurrentSelectionBackupOption.map(option => {
2053
2127
  return (jsx("option", { value: option.value, children: option.label }, option.value));
2054
- }) }), children(Object.assign(Object.assign({}, rest), { id, isDisabled: disabled, onBlur, options: optionsWithCurrentSelectionBackupOption, onChange: e => {
2128
+ }) }), children(Object.assign(Object.assign({}, rest), { id,
2129
+ disabled,
2130
+ onBlur, options: optionsWithCurrentSelectionBackupOption, onChange: e => {
2055
2131
  // If theres no value, set the inner value to an empty string
2056
2132
  // A native select can not have a null value
2057
2133
  // So even if react-select sends a null value, we need to convert it to an empty string
@@ -2192,10 +2268,10 @@ TextField.displayName = "TextField";
2192
2268
  * @returns {JSX.Element} TimeRangeField component
2193
2269
  */
2194
2270
  const TimeRangeField = (_a) => {
2195
- var { className, dataTestId, onChange, isInvalid, errorMessage, label, tip, disabled, children, helpText, id } = _a, rest = __rest(_a, ["className", "dataTestId", "onChange", "isInvalid", "errorMessage", "label", "tip", "disabled", "children", "helpText", "id"]);
2271
+ var { className, dataTestId, onChange, isInvalid, errorMessage, label, tip, children, helpText, id } = _a, rest = __rest(_a, ["className", "dataTestId", "onChange", "isInvalid", "errorMessage", "label", "tip", "children", "helpText", "id"]);
2196
2272
  const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
2197
2273
  const htmlFor = id ? id : "timeRangeField-" + v4();
2198
- return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: disabled, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(TimeRange, Object.assign({ className: className, dataTestId: dataTestId, disabled: disabled, isInvalid: renderAsInvalid, onChange: onChange }, rest, { children: children })) }));
2274
+ return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(TimeRange, Object.assign({ className: className, dataTestId: dataTestId, isInvalid: renderAsInvalid, onChange: onChange }, rest, { children: children })) }));
2199
2275
  };
2200
2276
 
2201
2277
  const cvaToggleWrapper = cvaMerge(["flex", "gap-2", "items-center"]);
@@ -2349,7 +2425,7 @@ const UrlField = forwardRef((_a, ref) => {
2349
2425
  return typeof inputValue === "string";
2350
2426
  }
2351
2427
  const renderAsInvalid = !!errorMessage || (value && isString(value) && !validateUrlAddress(value)) || isInvalid;
2352
- return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, disabled: rest.disabled, helpAddon: helpAddon, helpText: renderAsInvalid ? errorMessage : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(UrlInput, Object.assign({ "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, ref: ref, value: value || defaultValue }, rest, { className: className, dataTestId: dataTestId })) }));
2428
+ return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpAddon: helpAddon, helpText: renderAsInvalid ? errorMessage : helpText, htmlFor: htmlForId, isInvalid: renderAsInvalid, label: label, required: rest.required, tip: tip, children: jsx(UrlInput, Object.assign({ "aria-labelledby": htmlForId + "-label", id: htmlForId, isInvalid: renderAsInvalid, ref: ref, value: value || defaultValue }, rest, { className: className, dataTestId: dataTestId })) }));
2353
2429
  });
2354
2430
  UrlField.displayName = "UrlField";
2355
2431
 
@@ -2457,4 +2533,4 @@ const useZodValidators = () => {
2457
2533
  */
2458
2534
  setupLibraryTranslations();
2459
2535
 
2460
- export { ActionButton, BaseInput, Checkbox, CheckboxField, ColorField, CreatableSelect, CreatableSelectField, DateField, DateInput, DropZone, 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, cvaSelectPrefix, cvaSelectXIcon, getCountryAbbreviation, getOrderedOptions, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isMultiValue, isValidHEXColor, parseSchedule, serializeSchedule, useCustomComponents, useGetPhoneValidationRules, usePhoneInput, useZodValidators, validateEmailAddress, validatePhoneNumber, weekDay };
2536
+ export { ActionButton, BaseInput, Checkbox, CheckboxField, ColorField, CreatableSelect, CreatableSelectField, DateField, DateInput, DropZone, 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, getOrderedOptions, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isMultiValue, isValidHEXColor, parseSchedule, serializeSchedule, useCustomComponents, useGetPhoneValidationRules, usePhoneInput, useZodValidators, validateEmailAddress, validatePhoneNumber, weekDay };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-form-components",
3
- "version": "0.0.460",
3
+ "version": "0.0.462",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -22,7 +22,6 @@
22
22
  "@trackunit/i18n-library-translation": "*",
23
23
  "zod": "3.22.4",
24
24
  "react-hook-form": "7.40.0",
25
- "rxjs": "7.8.1",
26
25
  "tailwind-merge": "^2.0.0"
27
26
  },
28
27
  "module": "./index.esm.js",
@@ -1,6 +1,8 @@
1
1
  import { CommonProps } from "@trackunit/react-components";
2
+ import { MappedOmit } from "@trackunit/shared-utils";
2
3
  import * as React from "react";
3
- type FilteredInputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, "prefix" | "suffix">;
4
+ import { DisabledForReasons } from "./DisabledForReasonsTip";
5
+ type FilteredInputProps = MappedOmit<React.InputHTMLAttributes<HTMLInputElement>, "prefix" | "disabled">;
4
6
  type FieldSize = "small" | "medium";
5
7
  export interface BaseInputProps extends FilteredInputProps, CommonProps {
6
8
  /**
@@ -65,6 +67,7 @@ export interface BaseInputProps extends FilteredInputProps, CommonProps {
65
67
  * If true the input is readonly.
66
68
  */
67
69
  readonly?: boolean;
70
+ disabled?: boolean | DisabledForReasons;
68
71
  }
69
72
  /**
70
73
  * A base input component that can be used for text inputs, password inputs, etc.
@@ -0,0 +1,16 @@
1
+ /// <reference types="react" />
2
+ type DisabledKind = "locked" | "disabled";
3
+ export type DisabledForReasons = {
4
+ kind: DisabledKind;
5
+ reasons?: string | string[];
6
+ };
7
+ /**
8
+ * Icon with explanation tooltip for why an input is locked or disabled.
9
+ * If locked, a permission lacks but the input **can** sometimes be edited.
10
+ * If disabled, the input **cannot** be edited and is only ever for displaying information.
11
+ *
12
+ * @param {DisabledForReasons} props - The reasons for the disabled state.
13
+ * @param {DisabledKind} kind - The kind of disabled state. If locked, the input can sometimes be edited. If disabled, the input cannot be edited.
14
+ */
15
+ export declare const DisabledForReasonsTip: ({ reasons, kind }: DisabledForReasons) => JSX.Element;
16
+ export {};
@@ -1,4 +1,4 @@
1
- import { CommonProps, IconProps } from "@trackunit/react-components";
1
+ import { CommonProps } from "@trackunit/react-components";
2
2
  import * as React from "react";
3
3
  export interface FormGroupProps extends CommonProps {
4
4
  /**
@@ -23,15 +23,7 @@ export interface FormGroupProps extends CommonProps {
23
23
  * If true the input is rendered in its invalid state.
24
24
  */
25
25
  isInvalid?: boolean;
26
- /**
27
- * If true interactions are disabled
28
- */
29
- disabled?: boolean;
30
26
  children?: React.ReactNode;
31
- /**
32
- * The props for setting the icon on tip.
33
- */
34
- tipIconProps?: IconProps;
35
27
  name?: string;
36
28
  /**
37
29
  * If true the input is required with an asterisk prepended to the label.
@@ -45,4 +37,4 @@ export interface FormGroupProps extends CommonProps {
45
37
  * @param {FormGroupProps} props - The props for the FormGroup component
46
38
  * @returns {JSX.Element} FormGroup component
47
39
  */
48
- export declare const FormGroup: ({ isInvalid, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, tipIconProps, disabled, required, }: FormGroupProps) => JSX.Element;
40
+ export declare const FormGroup: ({ isInvalid, helpText, helpAddon, tip, className, dataTestId, label, htmlFor, children, required, }: FormGroupProps) => JSX.Element;
@@ -1,6 +1,4 @@
1
- export declare const cvaFormGroup: (props?: ({
2
- disabled?: boolean | null | undefined;
3
- } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
1
+ export declare const cvaFormGroup: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
4
2
  export declare const cvaFormGroupContainerBefore: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
5
3
  export declare const cvaFormGroupContainerAfter: (props?: ({
6
4
  invalid?: boolean | null | undefined;
@@ -17,6 +17,6 @@ export type CreatableSelectProps = {
17
17
  * @returns {JSX.Element} CreatableSelect component
18
18
  */
19
19
  export declare const CreatableSelect: {
20
- <TOption, TIsAsync extends boolean = false, TIsMulti extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>>(props: SelectProps<TOption, TIsAsync, TIsMulti, TGroup> & CreatableSelectProps): JSX.Element;
20
+ <Option, IsAsync extends boolean = false, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>(props: SelectProps<Option, IsAsync, IsMulti, Group> & CreatableSelectProps): JSX.Element;
21
21
  displayName: string;
22
22
  };
@@ -13,6 +13,6 @@ export interface SelectOption<TValue extends string> {
13
13
  * @returns {JSX.Element} Select component
14
14
  */
15
15
  export declare const Select: {
16
- <TOption, TIsAsync extends boolean = false, TIsMulti extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>>(props: SelectProps<TOption, TIsAsync, TIsMulti, TGroup>): JSX.Element;
16
+ <Option, IsAsync extends boolean = false, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>(props: SelectProps<Option, IsAsync, IsMulti, Group>): JSX.Element;
17
17
  displayName: string;
18
18
  };
@@ -8,7 +8,9 @@ export declare const cvaSelectControl: (props?: ({
8
8
  invalid?: boolean | null | undefined;
9
9
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
10
10
  export declare const cvaSelectIcon: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
11
- export declare const cvaSelectPrefix: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
11
+ export declare const cvaSelectPrefixSuffix: (props?: ({
12
+ kind?: "prefix" | "suffix" | null | undefined;
13
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
12
14
  export declare const cvaSelectXIcon: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
13
15
  export declare const cvaSelectMenuList: (props?: ({
14
16
  menuIsOpen?: boolean | null | undefined;
@@ -13,7 +13,19 @@ import { SelectComponents } from "react-select/dist/declarations/src/components"
13
13
  * @param {React.MutableRefObject<boolean>} refMenuIsEnabled a flag to block menu from open
14
14
  * @param {string} dataTestId a test id
15
15
  * @param {number} maxSelectedDisplayCount a number of max display count
16
- * @param {JSX.Element} dropdownIcon an custom dropdown icon
16
+ * @param {JSX.Element} dropdownIcon an custom dropdown icon
17
+ * @param {boolean} hasError decide to override hasError variant
18
+ * @param {JSX.Element} prefix a prefix element
17
19
  * @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
18
20
  */
19
- export declare const useCustomComponents: <TOption, TIsMulti extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>>(componentsProps: Partial<SelectComponents<TOption, TIsMulti, TGroup>> | undefined, disabled: boolean, menuIsOpen: boolean, refMenuIsEnabled: React.MutableRefObject<boolean>, dataTestId: string, maxSelectedDisplayCount: number | undefined, dropdownIcon?: JSX.Element, prefix?: JSX.Element, hasError?: boolean) => Partial<SelectComponents<TOption, TIsMulti, TGroup>>;
21
+ export declare const useCustomComponents: <Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>({ componentsProps, disabled, readOnly, refMenuIsEnabled, dataTestId, maxSelectedDisplayCount, dropdownIcon, prefix, hasError, }: {
22
+ componentsProps: Partial<SelectComponents<Option, IsMulti, Group>> | undefined;
23
+ disabled: boolean;
24
+ readOnly: boolean;
25
+ refMenuIsEnabled: React.MutableRefObject<boolean>;
26
+ dataTestId: string;
27
+ maxSelectedDisplayCount: number | undefined;
28
+ dropdownIcon?: JSX.Element;
29
+ prefix?: JSX.Element;
30
+ hasError?: boolean;
31
+ }) => Partial<SelectComponents<Option, IsMulti, Group>>;
@@ -9,6 +9,12 @@ import { GroupBase, StylesConfig } from "react-select";
9
9
  * @param {StylesConfig<Option, IsMulti, Group> | undefined} styles a optional object to override styles of react-select
10
10
  * @returns {StylesConfig<Option, boolean>} styles to override in select
11
11
  */
12
- export declare const useCustomStyles: <Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>(refContainer: React.RefObject<HTMLDivElement>, refPrefix: React.RefObject<HTMLDivElement>, maxSelectedDisplayCount: number | undefined, styles: StylesConfig<Option, IsMulti, Group> | undefined, disabled: boolean | undefined) => {
12
+ export declare const useCustomStyles: <Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>({ refContainer, refPrefix, maxSelectedDisplayCount, styles, disabled, }: {
13
+ refContainer: React.RefObject<HTMLDivElement>;
14
+ refPrefix: React.RefObject<HTMLDivElement>;
15
+ maxSelectedDisplayCount: number | undefined;
16
+ styles: StylesConfig<Option, IsMulti, Group> | undefined;
17
+ disabled: boolean | undefined;
18
+ }) => {
13
19
  customStyles: StylesConfig<Option, IsMulti, Group>;
14
20
  };
@@ -1,13 +1,15 @@
1
1
  import { CommonProps } from "@trackunit/react-components";
2
+ import { MappedOmit } from "@trackunit/shared-utils";
2
3
  import React from "react";
3
4
  import { GroupBase, MenuPlacement, OptionsOrGroups, Props, StylesConfig } from "react-select";
4
5
  import { SelectComponents } from "react-select/dist/declarations/src/components";
6
+ import { DisabledForReasons } from "../BaseInput/DisabledForReasonsTip";
5
7
  export interface AsyncSelect<Option, Group extends GroupBase<Option> = GroupBase<Option>> {
6
8
  loadOptions: (input: string) => void | Promise<OptionsOrGroups<Option, Group>>;
7
9
  defaultOptions: OptionsOrGroups<Option, Group> | undefined;
8
10
  cacheOptions: boolean;
9
11
  }
10
- export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean, GroupType extends GroupBase<Option>> = CommonProps & Props<Option, IsMulti, GroupType> & {
12
+ export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean, GroupType extends GroupBase<Option>> = CommonProps & MappedOmit<Props<Option, IsMulti, GroupType>, "isDisabled"> & {
11
13
  /**
12
14
  * An React element to render before the text in the select.
13
15
  * This is typically used to render an icon.
@@ -27,7 +29,7 @@ export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean
27
29
  *
28
30
  * @memberof SelectProps
29
31
  */
30
- disabled?: boolean;
32
+ disabled?: boolean | DisabledForReasons;
31
33
  /**
32
34
  * An boolean flag to make the field readonly
33
35
  *
@@ -121,7 +123,7 @@ export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean
121
123
  */
122
124
  hideSelectedOptions?: boolean;
123
125
  };
124
- interface IUseSelect<Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>> {
126
+ interface UseSelectProps<Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>> {
125
127
  customStyles: StylesConfig<Option, IsMulti, Group>;
126
128
  customComponents: Partial<SelectComponents<Option, IsMulti, Group>>;
127
129
  refContainer: React.RefObject<HTMLDivElement>;
@@ -136,7 +138,7 @@ interface IUseSelect<Option, IsMulti extends boolean = false, Group extends Grou
136
138
  * A hook used by selects to share the common code
137
139
  *
138
140
  * @param {SelectProps} props - The props for the Select component
139
- * @returns {IUseSelect} Select component
141
+ * @returns {UseSelectProps} Select component
140
142
  */
141
- export declare const useSelect: <Option, IsAsync extends boolean = false, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>({ id, className, dataTestId, prefix, async, dropdownIcon, maxMenuHeight, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix, onMenuOpen, onMenuClose, maxSelectedDisplayCount, isClearable, isSearchable, onMenuScrollToBottom, styles, filterOption, onInputChange, ...props }: SelectProps<Option, IsAsync, IsMulti, Group>) => IUseSelect<Option, IsMulti, Group>;
143
+ export declare const useSelect: <Option, IsAsync extends boolean = false, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>({ id, className, dataTestId, prefix, async, dropdownIcon, maxMenuHeight, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix, onMenuOpen, onMenuClose, maxSelectedDisplayCount, isClearable, isSearchable, onMenuScrollToBottom, styles, filterOption, onInputChange, ...props }: SelectProps<Option, IsAsync, IsMulti, Group>) => UseSelectProps<Option, IsMulti, Group>;
142
144
  export {};
@@ -14,5 +14,5 @@ export interface TimeRangeFieldProps extends TimeRangeProps, FormGroupExposedPro
14
14
  * @param {TimeRangeFieldProps} props - The props for the TimeRangeField component
15
15
  * @returns {JSX.Element} TimeRangeField component
16
16
  */
17
- export declare const TimeRangeField: ({ className, dataTestId, onChange, isInvalid, errorMessage, label, tip, disabled, children, helpText, id, ...rest }: TimeRangeFieldProps) => JSX.Element;
17
+ export declare const TimeRangeField: ({ className, dataTestId, onChange, isInvalid, errorMessage, label, tip, children, helpText, id, ...rest }: TimeRangeFieldProps) => JSX.Element;
18
18
  export {};
@@ -15,8 +15,8 @@ export declare const translations: TranslationResource<TranslationKeys>;
15
15
  /**
16
16
  * Local useTranslation for this specific library
17
17
  */
18
- export declare const useTranslation: () => [TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "dropzone.input.title" | "dropzone.label.default" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined">, import("i18next").i18n, boolean] & {
19
- t: TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "dropzone.input.title" | "dropzone.label.default" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined">;
18
+ export declare const useTranslation: () => [TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "dropzone.input.title" | "dropzone.label.default" | "field.notEditable.tooltip" | "field.required.asterisk.tooltip" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined">, import("i18next").i18n, boolean] & {
19
+ t: TransForLibs<"clearIndicator.icon.tooltip.clearAll" | "dropzone.input.title" | "dropzone.label.default" | "field.notEditable.tooltip" | "field.required.asterisk.tooltip" | "phoneField.error.INVALID_COUNTRY" | "phoneField.error.INVALID_LENGTH" | "phoneField.error.INVALID_NUMBER" | "phoneField.error.NOT_A_NUMBER" | "phoneField.error.REQUIRED" | "phoneField.error.REQUIRED_COUNTRY" | "phoneField.error.TOO_LONG" | "phoneField.error.TOO_SHORT" | "phoneField.error.undefined">;
20
20
  i18n: import("i18next").i18n;
21
21
  ready: boolean;
22
22
  };