@simplybusiness/mobius 5.11.0 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/components/AddressLookup/AddressLookup.js +11 -3
  3. package/dist/cjs/components/AddressLookup/AddressLookup.js.map +1 -1
  4. package/dist/cjs/components/Combobox/Combobox.js +30 -6
  5. package/dist/cjs/components/Combobox/Combobox.js.map +1 -1
  6. package/dist/cjs/components/Combobox/Listbox.js +8 -5
  7. package/dist/cjs/components/Combobox/Listbox.js.map +1 -1
  8. package/dist/cjs/components/Combobox/Option.js +2 -2
  9. package/dist/cjs/components/Combobox/Option.js.map +1 -1
  10. package/dist/cjs/components/Combobox/useComboboxOptions.js +10 -4
  11. package/dist/cjs/components/Combobox/useComboboxOptions.js.map +1 -1
  12. package/dist/cjs/components/Combobox/utils.js.map +1 -1
  13. package/dist/cjs/components/TextField/TextField.js +4 -4
  14. package/dist/cjs/components/TextField/TextField.js.map +1 -1
  15. package/dist/cjs/components/TextField/adornmentWithClassName.js +2 -2
  16. package/dist/cjs/components/TextField/adornmentWithClassName.js.map +1 -1
  17. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  18. package/dist/esm/components/AddressLookup/AddressLookup.js +12 -4
  19. package/dist/esm/components/AddressLookup/AddressLookup.js.map +1 -1
  20. package/dist/esm/components/AddressLookup/types.js.map +1 -1
  21. package/dist/esm/components/Combobox/Combobox.js +30 -6
  22. package/dist/esm/components/Combobox/Combobox.js.map +1 -1
  23. package/dist/esm/components/Combobox/Listbox.js +8 -5
  24. package/dist/esm/components/Combobox/Listbox.js.map +1 -1
  25. package/dist/esm/components/Combobox/Option.js +2 -2
  26. package/dist/esm/components/Combobox/Option.js.map +1 -1
  27. package/dist/esm/components/Combobox/types.js.map +1 -1
  28. package/dist/esm/components/Combobox/useComboboxOptions.js +10 -4
  29. package/dist/esm/components/Combobox/useComboboxOptions.js.map +1 -1
  30. package/dist/esm/components/Combobox/utils.js.map +1 -1
  31. package/dist/esm/components/TextField/TextField.js +4 -4
  32. package/dist/esm/components/TextField/TextField.js.map +1 -1
  33. package/dist/esm/components/TextField/adornmentWithClassName.js +2 -2
  34. package/dist/esm/components/TextField/adornmentWithClassName.js.map +1 -1
  35. package/dist/types/components/AddressLookup/AddressLookup.d.ts +3 -1
  36. package/dist/types/components/AddressLookup/types.d.ts +2 -1
  37. package/dist/types/components/Combobox/Combobox.d.ts +4 -3
  38. package/dist/types/components/Combobox/Combobox.stories.d.ts +82 -9
  39. package/dist/types/components/Combobox/Listbox.d.ts +4 -4
  40. package/dist/types/components/Combobox/Option.d.ts +2 -2
  41. package/dist/types/components/Combobox/types.d.ts +19 -20
  42. package/dist/types/components/Combobox/useComboboxOptions.d.ts +6 -5
  43. package/dist/types/components/Combobox/utils.d.ts +2 -2
  44. package/dist/types/components/TextField/adornmentWithClassName.d.ts +1 -1
  45. package/package.json +15 -15
  46. package/src/components/AddressLookup/AddressLookup.test.tsx +106 -0
  47. package/src/components/AddressLookup/AddressLookup.tsx +61 -40
  48. package/src/components/AddressLookup/__mocks__/LoqateAddressLookupService.tsx +0 -2
  49. package/src/components/AddressLookup/types.tsx +2 -1
  50. package/src/components/Combobox/Combobox.css +6 -2
  51. package/src/components/Combobox/Combobox.stories.tsx +38 -16
  52. package/src/components/Combobox/Combobox.test.tsx +10 -5
  53. package/src/components/Combobox/Combobox.tsx +225 -202
  54. package/src/components/Combobox/Listbox.tsx +24 -10
  55. package/src/components/Combobox/Option.tsx +4 -6
  56. package/src/components/Combobox/types.tsx +49 -42
  57. package/src/components/Combobox/useComboboxOptions.test.ts +4 -5
  58. package/src/components/Combobox/useComboboxOptions.ts +26 -10
  59. package/src/components/Combobox/utils.test.tsx +10 -12
  60. package/src/components/Combobox/utils.tsx +6 -6
  61. package/src/components/TextField/TextField.css +4 -1
  62. package/src/components/TextField/TextField.stories.tsx +2 -0
  63. package/src/components/TextField/TextField.tsx +4 -0
  64. package/src/components/TextField/adornmentWithClassName.ts +6 -1
  65. package/src/public-whitelist.test.ts +3 -1
  66. package/src/yarnpath.test.ts +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 9f9cbc5: Save Address selected into state (Questionnaire)
8
+
9
+ ### Patch Changes
10
+
11
+ - 4984b57: Add error handling for `AddressLookup` component
12
+ - 1fa9b7e: Package upgrades
13
+ - b3b961b: Fix icon colour in TextField
14
+
15
+ ## 5.11.1
16
+
17
+ ### Patch Changes
18
+
19
+ - 902cee3: Combobox and AddressLookup behaviour improvements
20
+
3
21
  ## 5.11.0
4
22
 
5
23
  ### Minor Changes
@@ -32,11 +32,18 @@ function optionsFromResponse({ Items }, addressLookupService) {
32
32
  }
33
33
  }));
34
34
  }
35
- function AddressLookup({ addressLookupService, onAddressSelected, errorMessage, ...otherProps }) {
36
- const [error, setError] = (0, _react.useState)(null);
35
+ const AddressLookup = /*#__PURE__*/ (0, _react.forwardRef)(({ addressLookupService, onAddressSelected, onError, errorMessage, ...otherProps }, ref)=>{
36
+ const [error, _setError] = (0, _react.useState)(null);
37
+ const setError = (0, _react.useCallback)((newError)=>{
38
+ if (newError != null) onError === null || onError === void 0 ? void 0 : onError(newError);
39
+ _setError(newError);
40
+ }, [
41
+ onError
42
+ ]);
37
43
  const asyncOptions = (0, _react.useCallback)(async (searchTerm)=>{
38
44
  try {
39
45
  const response = await addressLookupService.search(searchTerm);
46
+ setError(null);
40
47
  return optionsFromResponse(response, addressLookupService);
41
48
  } catch (e) {
42
49
  setError(e);
@@ -54,6 +61,7 @@ function AddressLookup({ addressLookupService, onAddressSelected, errorMessage,
54
61
  const realErrorMessage = error && "An error occurred" || errorMessage;
55
62
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_Combobox.Combobox, {
56
63
  ...otherProps,
64
+ ref: ref,
57
65
  onSelected: handleSelected,
58
66
  asyncOptions: asyncOptions,
59
67
  errorMessage: realErrorMessage,
@@ -61,6 +69,6 @@ function AddressLookup({ addressLookupService, onAddressSelected, errorMessage,
61
69
  icon: _icons.search
62
70
  })
63
71
  });
64
- }
72
+ });
65
73
 
66
74
  //# sourceMappingURL=AddressLookup.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/AddressLookup/AddressLookup.tsx"],"sourcesContent":["import { search } from \"@simplybusiness/icons\";\nimport { useCallback, useState } from \"react\";\nimport { Combobox } from \"../Combobox\";\nimport { Icon } from \"../Icon\";\nimport { LoqateAddressLookupService } from \"./LoqateAddressLookupService\";\nimport type {\n AddressError,\n AddressLookupProps,\n FindAddressResponse,\n FindAddressResult,\n} from \"./types\";\n\nfunction optionsFromResponse(\n { Items }: FindAddressResponse,\n addressLookupService: LoqateAddressLookupService,\n) {\n if (!Items || !Array.isArray(Items)) {\n throw Error(\"No address found\");\n }\n\n if ((Items[0] as unknown as AddressError).Error) {\n throw Error(Items[0].Description);\n }\n\n return (Items as FindAddressResult[]).map(item => ({\n id: item.Id,\n label: `${item.Text}, ${item.Description}`,\n value: item.Text,\n // Add a callback to trigger secondary search\n // if the address type is not \"Address\"\n callback:\n item.Type === \"Address\"\n ? undefined\n : async () => {\n const result = await addressLookupService.findById(item.Id);\n return optionsFromResponse(result, addressLookupService);\n },\n }));\n}\n\nexport function AddressLookup({\n addressLookupService,\n onAddressSelected,\n errorMessage,\n ...otherProps\n}: AddressLookupProps) {\n const [error, setError] = useState<Error | null>(null);\n\n const asyncOptions = useCallback(\n async (searchTerm: string) => {\n try {\n const response = await addressLookupService.search(searchTerm);\n return optionsFromResponse(response, addressLookupService);\n } catch (e) {\n setError(e as Error);\n return [];\n }\n },\n [addressLookupService, setError],\n );\n\n const handleSelected = (selected: unknown) => {\n setError(null);\n return (\n addressLookupService\n // @ts-expect-error - Fix types\n .get(selected.id)\n .then(onAddressSelected)\n .catch(setError)\n );\n };\n\n const realErrorMessage = (error && \"An error occurred\") || errorMessage;\n\n return (\n <Combobox\n {...otherProps}\n onSelected={handleSelected}\n asyncOptions={asyncOptions}\n errorMessage={realErrorMessage}\n icon={<Icon icon={search} />}\n />\n );\n}\n"],"names":["AddressLookup","optionsFromResponse","Items","addressLookupService","Array","isArray","Error","Description","map","item","id","Id","label","Text","value","callback","Type","undefined","result","findById","onAddressSelected","errorMessage","otherProps","error","setError","useState","asyncOptions","useCallback","searchTerm","response","search","e","handleSelected","selected","get","then","catch","realErrorMessage","Combobox","onSelected","icon","Icon"],"mappings":";;;;+BAwCgBA;;;eAAAA;;;;uBAxCO;uBACe;0BACb;sBACJ;AASrB,SAASC,oBACP,EAAEC,KAAK,EAAuB,EAC9BC,oBAAgD;IAEhD,IAAI,CAACD,SAAS,CAACE,MAAMC,OAAO,CAACH,QAAQ;QACnC,MAAMI,MAAM;IACd;IAEA,IAAI,AAACJ,KAAK,CAAC,EAAE,CAA6BI,KAAK,EAAE;QAC/C,MAAMA,MAAMJ,KAAK,CAAC,EAAE,CAACK,WAAW;IAClC;IAEA,OAAO,AAACL,MAA8BM,GAAG,CAACC,CAAAA,OAAS,CAAA;YACjDC,IAAID,KAAKE,EAAE;YACXC,OAAO,GAAGH,KAAKI,IAAI,CAAC,EAAE,EAAEJ,KAAKF,WAAW,EAAE;YAC1CO,OAAOL,KAAKI,IAAI;YAChB,6CAA6C;YAC7C,uCAAuC;YACvCE,UACEN,KAAKO,IAAI,KAAK,YACVC,YACA;gBACE,MAAMC,SAAS,MAAMf,qBAAqBgB,QAAQ,CAACV,KAAKE,EAAE;gBAC1D,OAAOV,oBAAoBiB,QAAQf;YACrC;QACR,CAAA;AACF;AAEO,SAASH,cAAc,EAC5BG,oBAAoB,EACpBiB,iBAAiB,EACjBC,YAAY,EACZ,GAAGC,YACgB;IACnB,MAAM,CAACC,OAAOC,SAAS,GAAGC,IAAAA,eAAQ,EAAe;IAEjD,MAAMC,eAAeC,IAAAA,kBAAW,EAC9B,OAAOC;QACL,IAAI;YACF,MAAMC,WAAW,MAAM1B,qBAAqB2B,MAAM,CAACF;YACnD,OAAO3B,oBAAoB4B,UAAU1B;QACvC,EAAE,OAAO4B,GAAG;YACVP,SAASO;YACT,OAAO,EAAE;QACX;IACF,GACA;QAAC5B;QAAsBqB;KAAS;IAGlC,MAAMQ,iBAAiB,CAACC;QACtBT,SAAS;QACT,OACErB,oBACE,+BAA+B;SAC9B+B,GAAG,CAACD,SAASvB,EAAE,EACfyB,IAAI,CAACf,mBACLgB,KAAK,CAACZ;IAEb;IAEA,MAAMa,mBAAmB,AAACd,SAAS,uBAAwBF;IAE3D,qBACE,qBAACiB,kBAAQ;QACN,GAAGhB,UAAU;QACdiB,YAAYP;QACZN,cAAcA;QACdL,cAAcgB;QACdG,oBAAM,qBAACC,UAAI;YAACD,MAAMV,aAAM;;;AAG9B"}
1
+ {"version":3,"sources":["../../../../src/components/AddressLookup/AddressLookup.tsx"],"sourcesContent":["import { search } from \"@simplybusiness/icons\";\nimport { forwardRef, useCallback, useState } from \"react\";\nimport { Combobox } from \"../Combobox\";\nimport type { ComboboxRef, ComboboxElementType } from \"../Combobox\";\nimport { Icon } from \"../Icon\";\nimport { LoqateAddressLookupService } from \"./LoqateAddressLookupService\";\nimport type { ForwardedRefComponent } from \"../../types\";\nimport type {\n AddressError,\n AddressLookupProps,\n FindAddressResponse,\n FindAddressResult,\n} from \"./types\";\n\nfunction optionsFromResponse(\n { Items }: FindAddressResponse,\n addressLookupService: LoqateAddressLookupService,\n) {\n if (!Items || !Array.isArray(Items)) {\n throw Error(\"No address found\");\n }\n\n if ((Items[0] as unknown as AddressError).Error) {\n throw Error(Items[0].Description);\n }\n\n return (Items as FindAddressResult[]).map(item => ({\n id: item.Id,\n label: `${item.Text}, ${item.Description}`,\n value: item.Text,\n // Add a callback to trigger secondary search\n // if the address type is not \"Address\"\n callback:\n item.Type === \"Address\"\n ? undefined\n : async () => {\n const result = await addressLookupService.findById(item.Id);\n return optionsFromResponse(result, addressLookupService);\n },\n }));\n}\n\nexport const AddressLookup: ForwardedRefComponent<\n AddressLookupProps,\n ComboboxElementType\n> = forwardRef(\n (\n {\n addressLookupService,\n onAddressSelected,\n onError,\n errorMessage,\n ...otherProps\n }: AddressLookupProps,\n ref: ComboboxRef,\n ) => {\n const [error, _setError] = useState<Error | null>(null);\n\n const setError = useCallback(\n (newError: Error | null) => {\n if (newError != null) onError?.(newError);\n _setError(newError);\n },\n [onError],\n );\n\n const asyncOptions = useCallback(\n async (searchTerm: string) => {\n try {\n const response = await addressLookupService.search(searchTerm);\n setError(null);\n return optionsFromResponse(response, addressLookupService);\n } catch (e) {\n setError(e as Error);\n return [];\n }\n },\n [addressLookupService, setError],\n );\n\n const handleSelected = (selected: unknown) => {\n setError(null);\n return (\n addressLookupService\n // @ts-expect-error - Fix types\n .get(selected.id)\n .then(onAddressSelected)\n .catch(setError)\n );\n };\n\n const realErrorMessage = (error && \"An error occurred\") || errorMessage;\n\n return (\n <Combobox\n {...otherProps}\n ref={ref}\n onSelected={handleSelected}\n asyncOptions={asyncOptions}\n errorMessage={realErrorMessage}\n icon={<Icon icon={search} />}\n />\n );\n },\n);\n"],"names":["AddressLookup","optionsFromResponse","Items","addressLookupService","Array","isArray","Error","Description","map","item","id","Id","label","Text","value","callback","Type","undefined","result","findById","forwardRef","onAddressSelected","onError","errorMessage","otherProps","ref","error","_setError","useState","setError","useCallback","newError","asyncOptions","searchTerm","response","search","e","handleSelected","selected","get","then","catch","realErrorMessage","Combobox","onSelected","icon","Icon"],"mappings":";;;;+BA0CaA;;;eAAAA;;;;uBA1CU;uBAC2B;0BACzB;sBAEJ;AAUrB,SAASC,oBACP,EAAEC,KAAK,EAAuB,EAC9BC,oBAAgD;IAEhD,IAAI,CAACD,SAAS,CAACE,MAAMC,OAAO,CAACH,QAAQ;QACnC,MAAMI,MAAM;IACd;IAEA,IAAI,AAACJ,KAAK,CAAC,EAAE,CAA6BI,KAAK,EAAE;QAC/C,MAAMA,MAAMJ,KAAK,CAAC,EAAE,CAACK,WAAW;IAClC;IAEA,OAAO,AAACL,MAA8BM,GAAG,CAACC,CAAAA,OAAS,CAAA;YACjDC,IAAID,KAAKE,EAAE;YACXC,OAAO,GAAGH,KAAKI,IAAI,CAAC,EAAE,EAAEJ,KAAKF,WAAW,EAAE;YAC1CO,OAAOL,KAAKI,IAAI;YAChB,6CAA6C;YAC7C,uCAAuC;YACvCE,UACEN,KAAKO,IAAI,KAAK,YACVC,YACA;gBACE,MAAMC,SAAS,MAAMf,qBAAqBgB,QAAQ,CAACV,KAAKE,EAAE;gBAC1D,OAAOV,oBAAoBiB,QAAQf;YACrC;QACR,CAAA;AACF;AAEO,MAAMH,8BAGToB,IAAAA,iBAAU,EACZ,CACE,EACEjB,oBAAoB,EACpBkB,iBAAiB,EACjBC,OAAO,EACPC,YAAY,EACZ,GAAGC,YACgB,EACrBC;IAEA,MAAM,CAACC,OAAOC,UAAU,GAAGC,IAAAA,eAAQ,EAAe;IAElD,MAAMC,WAAWC,IAAAA,kBAAW,EAC1B,CAACC;QACC,IAAIA,YAAY,MAAMT,oBAAAA,8BAAAA,QAAUS;QAChCJ,UAAUI;IACZ,GACA;QAACT;KAAQ;IAGX,MAAMU,eAAeF,IAAAA,kBAAW,EAC9B,OAAOG;QACL,IAAI;YACF,MAAMC,WAAW,MAAM/B,qBAAqBgC,MAAM,CAACF;YACnDJ,SAAS;YACT,OAAO5B,oBAAoBiC,UAAU/B;QACvC,EAAE,OAAOiC,GAAG;YACVP,SAASO;YACT,OAAO,EAAE;QACX;IACF,GACA;QAACjC;QAAsB0B;KAAS;IAGlC,MAAMQ,iBAAiB,CAACC;QACtBT,SAAS;QACT,OACE1B,oBACE,+BAA+B;SAC9BoC,GAAG,CAACD,SAAS5B,EAAE,EACf8B,IAAI,CAACnB,mBACLoB,KAAK,CAACZ;IAEb;IAEA,MAAMa,mBAAmB,AAAChB,SAAS,uBAAwBH;IAE3D,qBACE,qBAACoB,kBAAQ;QACN,GAAGnB,UAAU;QACdC,KAAKA;QACLmB,YAAYP;QACZL,cAAcA;QACdT,cAAcmB;QACdG,oBAAM,qBAACC,UAAI;YAACD,MAAMV,aAAM;;;AAG9B"}
@@ -23,8 +23,10 @@ function _interop_require_default(obj) {
23
23
  default: obj
24
24
  };
25
25
  }
26
- const Combobox = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
26
+ const ComboboxInner = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
27
27
  const { id, defaultValue, options, asyncOptions, delay, minLength, onSelected, className, placeholder, icon, ...otherProps } = props;
28
+ // Avoid re-fetching after selecting an option
29
+ const skipNextDebounceRef = (0, _react.useRef)(false);
28
30
  const fallbackRef = (0, _react.useRef)(null);
29
31
  const [inputValue, setInputValue] = (0, _react.useState)(defaultValue || "");
30
32
  const [isOpen, setIsOpen] = (0, _react.useState)(false);
@@ -33,7 +35,8 @@ const Combobox = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
33
35
  asyncOptions,
34
36
  inputValue,
35
37
  delay,
36
- minLength
38
+ minLength,
39
+ skipNextDebounceRef
37
40
  });
38
41
  const { highlightedIndex, highlightedGroupIndex, highlightNextOption, highlightPreviousOption, highlightFirstOption, highlightLastOption, clearHighlight } = (0, _useComboboxHighlight.useComboboxHighlight)(filteredOptions);
39
42
  const inputRef = ref || fallbackRef;
@@ -75,18 +78,35 @@ const Combobox = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
75
78
  updateFilteredOptions(option.callback());
76
79
  return;
77
80
  }
81
+ // Prevent re-fetching options after selecting an option
82
+ skipNextDebounceRef.current = true;
78
83
  setIsOpen(false);
79
84
  setInputValue(value);
80
85
  onSelected === null || onSelected === void 0 ? void 0 : onSelected(option);
81
86
  };
82
- function getHighlightedOption() {
87
+ const getFirstOption = ()=>{
88
+ if ((0, _utils.isOptionGroup)(filteredOptions)) {
89
+ var _filteredOptions_;
90
+ return (_filteredOptions_ = filteredOptions[0]) === null || _filteredOptions_ === void 0 ? void 0 : _filteredOptions_.options[0];
91
+ }
92
+ return filteredOptions[0];
93
+ };
94
+ const getHighlightedOption = ()=>{
83
95
  if (highlightedIndex === -1) return undefined;
84
96
  if ((0, _utils.isOptionGroup)(filteredOptions)) {
85
97
  const group = filteredOptions[highlightedGroupIndex];
86
98
  return group === null || group === void 0 ? void 0 : group.options[highlightedIndex];
87
99
  }
88
100
  return filteredOptions[highlightedIndex];
89
- }
101
+ };
102
+ const getHighlightedOptionId = ()=>{
103
+ const option = getHighlightedOption();
104
+ if (!option) return undefined;
105
+ if ((0, _utils.isOptionGroup)(filteredOptions)) {
106
+ return `${listboxId}-option-${highlightedGroupIndex}-${highlightedIndex}`;
107
+ }
108
+ return `${listboxId}-option-${highlightedIndex}`;
109
+ };
90
110
  const handleKeyDown = (e)=>{
91
111
  switch(e.key){
92
112
  case "ArrowDown":
@@ -112,7 +132,10 @@ const Combobox = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
112
132
  case "Enter":
113
133
  e.preventDefault();
114
134
  if (isOpen) {
115
- handleOptionSelect(getHighlightedOption());
135
+ const selectedOption = getHighlightedOption() || getFirstOption();
136
+ if (selectedOption) {
137
+ handleOptionSelect(selectedOption);
138
+ }
116
139
  }
117
140
  break;
118
141
  case "Escape":
@@ -156,7 +179,7 @@ const Combobox = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
156
179
  "aria-haspopup": "listbox",
157
180
  "aria-controls": listboxId,
158
181
  "aria-expanded": isOpen,
159
- "aria-activedescendant": highlightedIndex === -1 ? undefined : `${listboxId}-option-${highlightedGroupIndex}-${highlightedIndex}`,
182
+ "aria-activedescendant": highlightedIndex === -1 ? undefined : getHighlightedOptionId(),
160
183
  prefixInside: icon,
161
184
  ref: inputRef
162
185
  }),
@@ -170,5 +193,6 @@ const Combobox = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
170
193
  ]
171
194
  });
172
195
  });
196
+ const Combobox = ComboboxInner;
173
197
 
174
198
  //# sourceMappingURL=Combobox.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/Combobox/Combobox.tsx"],"sourcesContent":["import classNames from \"classnames/dedupe\";\nimport { forwardRef, useId, useRef, useState } from \"react\";\nimport { useOnUnmount } from \"../../hooks\";\nimport type { ForwardedRefComponent } from \"../../types\";\nimport { TextField } from \"../TextField\";\nimport { VisuallyHidden } from \"../VisuallyHidden\";\nimport { Listbox } from \"./Listbox\"; // Import Listbox component\nimport type {\n ComboboxElementType,\n ComboboxOption,\n ComboboxProps,\n ComboboxRef,\n} from \"./types\";\nimport { useComboboxHighlight } from \"./useComboboxHighlight\";\nimport { useComboboxOptions } from \"./useComboboxOptions\";\nimport { getOptionValue, isOptionGroup } from \"./utils\";\n\nexport const Combobox: ForwardedRefComponent<\n ComboboxProps,\n ComboboxElementType\n> = forwardRef((props: ComboboxProps, ref: ComboboxRef) => {\n const {\n id,\n defaultValue,\n options,\n asyncOptions,\n delay,\n minLength,\n onSelected,\n className,\n placeholder,\n icon,\n ...otherProps\n } = props;\n\n const fallbackRef = useRef<HTMLInputElement>(null);\n const [inputValue, setInputValue] = useState(defaultValue || \"\");\n const [isOpen, setIsOpen] = useState(false);\n const { filteredOptions, updateFilteredOptions, isLoading } =\n useComboboxOptions({\n options,\n asyncOptions,\n inputValue,\n delay,\n minLength,\n });\n const {\n highlightedIndex,\n highlightedGroupIndex,\n highlightNextOption,\n highlightPreviousOption,\n highlightFirstOption,\n highlightLastOption,\n clearHighlight,\n } = useComboboxHighlight(filteredOptions);\n\n const inputRef = ref || fallbackRef;\n const listboxId = useId();\n const statusId = useId();\n const blurTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const showListbox = isOpen && filteredOptions.length > 0;\n\n const handleFocus = () => {\n if (filteredOptions.length === 0) return;\n if (blurTimeoutRef.current) {\n clearTimeout(blurTimeoutRef.current);\n blurTimeoutRef.current = null;\n }\n setIsOpen(true);\n };\n\n const handleBlur = () => {\n blurTimeoutRef.current = setTimeout(() => {\n setIsOpen(false);\n }, 150);\n };\n\n useOnUnmount(() => {\n if (blurTimeoutRef.current) {\n clearTimeout(blurTimeoutRef.current);\n }\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n setInputValue(newValue);\n setIsOpen(true);\n clearHighlight();\n };\n\n const handleOptionSelect = (option: ComboboxOption) => {\n const value = getOptionValue(option);\n if (!value) return;\n\n // TODO: Declare this in the types\n if (\n typeof option === \"object\" &&\n \"callback\" in option &&\n option.callback &&\n typeof option.callback === \"function\"\n ) {\n // @ts-expect-error ref types are hard\n setTimeout(() => inputRef.current.focus(), 0);\n updateFilteredOptions(option.callback());\n return;\n }\n\n setIsOpen(false);\n setInputValue(value);\n onSelected?.(option);\n };\n\n function getHighlightedOption() {\n if (highlightedIndex === -1) return undefined;\n\n if (isOptionGroup(filteredOptions)) {\n const group = filteredOptions[highlightedGroupIndex];\n return group?.options[highlightedIndex];\n }\n\n return filteredOptions[highlightedIndex];\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n setIsOpen(true);\n highlightNextOption();\n break;\n case \"ArrowUp\":\n e.preventDefault();\n setIsOpen(true);\n highlightPreviousOption();\n break;\n case \"Home\":\n e.preventDefault();\n setIsOpen(true);\n highlightFirstOption();\n break;\n case \"End\":\n e.preventDefault();\n setIsOpen(true);\n highlightLastOption();\n break;\n case \"Enter\":\n e.preventDefault();\n if (isOpen) {\n handleOptionSelect(getHighlightedOption()!);\n }\n break;\n case \"Escape\":\n e.preventDefault();\n setIsOpen(false);\n clearHighlight();\n break;\n default:\n // Do nothing\n }\n };\n\n const classes = classNames(\n \"mobius mobius-combobox\",\n {\n \"mobius-combobox--is-expanded\": isOpen,\n \"mobius-combobox--is-loading\": isLoading,\n },\n className,\n );\n\n return (\n <div id={id} data-testid=\"mobius-combobox__wrapper\" className={classes}>\n {isLoading && (\n <VisuallyHidden\n role=\"status\"\n aria-live=\"polite\"\n id={statusId}\n elementType=\"div\"\n className=\"mobius-combobox__status\"\n >\n Loading options\n </VisuallyHidden>\n )}\n <TextField\n {...otherProps}\n className=\"mobius-combobox__input\"\n role=\"combobox\"\n value={inputValue}\n placeholder={placeholder}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onChange={handleInputChange}\n autoComplete=\"off\"\n aria-describedby={isLoading ? statusId : undefined}\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n aria-controls={listboxId}\n aria-expanded={isOpen}\n aria-activedescendant={\n highlightedIndex === -1\n ? undefined\n : `${listboxId}-option-${highlightedGroupIndex}-${highlightedIndex}`\n }\n prefixInside={icon}\n ref={inputRef}\n />\n {showListbox && (\n <Listbox\n id={listboxId}\n options={filteredOptions}\n highlightedIndex={highlightedIndex}\n highlightedGroupIndex={highlightedGroupIndex}\n onOptionSelect={handleOptionSelect}\n />\n )}\n </div>\n );\n});\n"],"names":["Combobox","forwardRef","props","ref","id","defaultValue","options","asyncOptions","delay","minLength","onSelected","className","placeholder","icon","otherProps","fallbackRef","useRef","inputValue","setInputValue","useState","isOpen","setIsOpen","filteredOptions","updateFilteredOptions","isLoading","useComboboxOptions","highlightedIndex","highlightedGroupIndex","highlightNextOption","highlightPreviousOption","highlightFirstOption","highlightLastOption","clearHighlight","useComboboxHighlight","inputRef","listboxId","useId","statusId","blurTimeoutRef","showListbox","length","handleFocus","current","clearTimeout","handleBlur","setTimeout","useOnUnmount","handleInputChange","e","newValue","target","value","handleOptionSelect","option","getOptionValue","callback","focus","getHighlightedOption","undefined","isOptionGroup","group","handleKeyDown","key","preventDefault","classes","classNames","div","data-testid","VisuallyHidden","role","aria-live","elementType","TextField","onFocus","onBlur","onKeyDown","onChange","autoComplete","aria-describedby","aria-autocomplete","aria-haspopup","aria-controls","aria-expanded","aria-activedescendant","prefixInside","Listbox","onOptionSelect"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/components/Combobox/Combobox.tsx"],"sourcesContent":["import classNames from \"classnames/dedupe\";\nimport { forwardRef, useId, useRef, useState } from \"react\";\nimport { useOnUnmount } from \"../../hooks\";\nimport { TextField } from \"../TextField\";\nimport { VisuallyHidden } from \"../VisuallyHidden\";\nimport { Listbox } from \"./Listbox\"; // Import Listbox component\nimport type { ComboboxOption, ComboboxProps, ComboboxRef } from \"./types\";\nimport { useComboboxHighlight } from \"./useComboboxHighlight\";\nimport { useComboboxOptions } from \"./useComboboxOptions\";\nimport { getOptionValue, isOptionGroup } from \"./utils\";\n\nconst ComboboxInner = forwardRef(\n <T extends ComboboxOption>(props: ComboboxProps<T>, ref: ComboboxRef) => {\n const {\n id,\n defaultValue,\n options,\n asyncOptions,\n delay,\n minLength,\n onSelected,\n className,\n placeholder,\n icon,\n ...otherProps\n } = props;\n\n // Avoid re-fetching after selecting an option\n const skipNextDebounceRef = useRef(false);\n const fallbackRef = useRef<HTMLInputElement>(null);\n const [inputValue, setInputValue] = useState(defaultValue || \"\");\n const [isOpen, setIsOpen] = useState(false);\n const { filteredOptions, updateFilteredOptions, isLoading } =\n useComboboxOptions({\n options,\n asyncOptions,\n inputValue,\n delay,\n minLength,\n skipNextDebounceRef,\n });\n const {\n highlightedIndex,\n highlightedGroupIndex,\n highlightNextOption,\n highlightPreviousOption,\n highlightFirstOption,\n highlightLastOption,\n clearHighlight,\n } = useComboboxHighlight(filteredOptions);\n\n const inputRef = ref || fallbackRef;\n const listboxId = useId();\n const statusId = useId();\n const blurTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const showListbox = isOpen && filteredOptions.length > 0;\n\n const handleFocus = () => {\n if (filteredOptions.length === 0) return;\n if (blurTimeoutRef.current) {\n clearTimeout(blurTimeoutRef.current);\n blurTimeoutRef.current = null;\n }\n setIsOpen(true);\n };\n\n const handleBlur = () => {\n blurTimeoutRef.current = setTimeout(() => {\n setIsOpen(false);\n }, 150);\n };\n\n useOnUnmount(() => {\n if (blurTimeoutRef.current) {\n clearTimeout(blurTimeoutRef.current);\n }\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n setInputValue(newValue);\n setIsOpen(true);\n clearHighlight();\n };\n\n const handleOptionSelect = (option: T) => {\n const value = getOptionValue(option);\n if (!value) return;\n\n // TODO: Declare this in the types\n if (\n typeof option === \"object\" &&\n \"callback\" in option &&\n option.callback &&\n typeof option.callback === \"function\"\n ) {\n // @ts-expect-error ref types are hard\n setTimeout(() => inputRef.current.focus(), 0);\n updateFilteredOptions(option.callback());\n return;\n }\n\n // Prevent re-fetching options after selecting an option\n skipNextDebounceRef.current = true;\n\n setIsOpen(false);\n setInputValue(value);\n onSelected?.(option as T);\n };\n\n const getFirstOption = () => {\n if (isOptionGroup(filteredOptions)) {\n return filteredOptions[0]?.options[0];\n }\n\n return filteredOptions[0];\n };\n\n const getHighlightedOption = () => {\n if (highlightedIndex === -1) return undefined;\n\n if (isOptionGroup(filteredOptions)) {\n const group = filteredOptions[highlightedGroupIndex];\n return group?.options[highlightedIndex];\n }\n\n return filteredOptions[highlightedIndex];\n };\n\n const getHighlightedOptionId = () => {\n const option = getHighlightedOption();\n if (!option) return undefined;\n\n if (isOptionGroup(filteredOptions)) {\n return `${listboxId}-option-${highlightedGroupIndex}-${highlightedIndex}`;\n }\n\n return `${listboxId}-option-${highlightedIndex}`;\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n setIsOpen(true);\n highlightNextOption();\n break;\n case \"ArrowUp\":\n e.preventDefault();\n setIsOpen(true);\n highlightPreviousOption();\n break;\n case \"Home\":\n e.preventDefault();\n setIsOpen(true);\n highlightFirstOption();\n break;\n case \"End\":\n e.preventDefault();\n setIsOpen(true);\n highlightLastOption();\n break;\n case \"Enter\":\n e.preventDefault();\n if (isOpen) {\n const selectedOption = getHighlightedOption() || getFirstOption();\n if (selectedOption) {\n handleOptionSelect(selectedOption);\n }\n }\n break;\n case \"Escape\":\n e.preventDefault();\n setIsOpen(false);\n clearHighlight();\n break;\n default:\n // Do nothing\n }\n };\n\n const classes = classNames(\n \"mobius mobius-combobox\",\n {\n \"mobius-combobox--is-expanded\": isOpen,\n \"mobius-combobox--is-loading\": isLoading,\n },\n className,\n );\n\n return (\n <div id={id} data-testid=\"mobius-combobox__wrapper\" className={classes}>\n {isLoading && (\n <VisuallyHidden\n role=\"status\"\n aria-live=\"polite\"\n id={statusId}\n elementType=\"div\"\n className=\"mobius-combobox__status\"\n >\n Loading options\n </VisuallyHidden>\n )}\n <TextField\n {...otherProps}\n className=\"mobius-combobox__input\"\n role=\"combobox\"\n value={inputValue}\n placeholder={placeholder}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onChange={handleInputChange}\n autoComplete=\"off\"\n aria-describedby={isLoading ? statusId : undefined}\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n aria-controls={listboxId}\n aria-expanded={isOpen}\n aria-activedescendant={\n highlightedIndex === -1 ? undefined : getHighlightedOptionId()\n }\n prefixInside={icon}\n ref={inputRef}\n />\n {showListbox && (\n <Listbox\n id={listboxId}\n options={filteredOptions}\n highlightedIndex={highlightedIndex}\n highlightedGroupIndex={highlightedGroupIndex}\n onOptionSelect={handleOptionSelect}\n />\n )}\n </div>\n );\n },\n);\n\nexport const Combobox = ComboboxInner as <T extends ComboboxOption>(\n props: ComboboxProps<T> & { ref?: ComboboxRef },\n) => JSX.Element;\n"],"names":["Combobox","ComboboxInner","forwardRef","props","ref","id","defaultValue","options","asyncOptions","delay","minLength","onSelected","className","placeholder","icon","otherProps","skipNextDebounceRef","useRef","fallbackRef","inputValue","setInputValue","useState","isOpen","setIsOpen","filteredOptions","updateFilteredOptions","isLoading","useComboboxOptions","highlightedIndex","highlightedGroupIndex","highlightNextOption","highlightPreviousOption","highlightFirstOption","highlightLastOption","clearHighlight","useComboboxHighlight","inputRef","listboxId","useId","statusId","blurTimeoutRef","showListbox","length","handleFocus","current","clearTimeout","handleBlur","setTimeout","useOnUnmount","handleInputChange","e","newValue","target","value","handleOptionSelect","option","getOptionValue","callback","focus","getFirstOption","isOptionGroup","getHighlightedOption","undefined","group","getHighlightedOptionId","handleKeyDown","key","preventDefault","selectedOption","classes","classNames","div","data-testid","VisuallyHidden","role","aria-live","elementType","TextField","onFocus","onBlur","onKeyDown","onChange","autoComplete","aria-describedby","aria-autocomplete","aria-haspopup","aria-controls","aria-expanded","aria-activedescendant","prefixInside","Listbox","onOptionSelect"],"mappings":"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"}
@@ -19,6 +19,12 @@ function _interop_require_default(obj) {
19
19
  }
20
20
  const Listbox = ({ id, options, highlightedIndex, highlightedGroupIndex, onOptionSelect })=>{
21
21
  const classes = (0, _classnames.default)("mobius-combobox__list");
22
+ function getOptionId(option, groupIndex, index) {
23
+ if (typeof option === "object" && "id" in option && typeof option.id === "string") {
24
+ return option.id;
25
+ }
26
+ return (0, _utils.isOptionGroup)(options) ? `${id}-option-${groupIndex}-${index}` : `${id}-option-${index}`;
27
+ }
22
28
  return /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
23
29
  role: "listbox",
24
30
  id: id,
@@ -36,19 +42,16 @@ const Listbox = ({ id, options, highlightedIndex, highlightedGroupIndex, onOptio
36
42
  }),
37
43
  option.options.map((groupOption, index)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_Option.Option, {
38
44
  option: groupOption,
39
- index: index,
40
- groupIndex: groupIndex,
41
45
  isHighlighted: highlightedIndex === index && highlightedGroupIndex === groupIndex,
42
46
  onOptionSelect: onOptionSelect,
43
- id: id
47
+ id: getOptionId(groupOption, groupIndex, index)
44
48
  }, `${id}-option-${groupIndex}-${index}`))
45
49
  ]
46
50
  }, option.heading)) : options.map((option, index)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_Option.Option, {
47
51
  option: option,
48
- index: index,
49
52
  isHighlighted: highlightedIndex === index,
50
53
  onOptionSelect: onOptionSelect,
51
- id: id
54
+ id: getOptionId(option, 0, index)
52
55
  }, index))
53
56
  });
54
57
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/Combobox/Listbox.tsx"],"sourcesContent":["import classNames from \"classnames\";\nimport { Option } from \"./Option\";\nimport type { ComboboxOption, ComboboxOptions } from \"./types\";\nimport { isOptionGroup } from \"./utils\";\n\nexport type ListboxProps = {\n id: string;\n options: ComboboxOptions;\n highlightedIndex: number;\n highlightedGroupIndex: number;\n onOptionSelect: (option: ComboboxOption) => void;\n};\n\nexport const Listbox = ({\n id,\n options,\n highlightedIndex,\n highlightedGroupIndex,\n onOptionSelect,\n}: ListboxProps) => {\n const classes = classNames(\"mobius-combobox__list\");\n\n return (\n <div role=\"listbox\" id={id} className={classes}>\n {isOptionGroup(options)\n ? options.map((option, groupIndex) => (\n <ul\n role=\"group\"\n key={option.heading}\n aria-labelledby={`${id}-group-${groupIndex}`}\n className=\"mobius-combobox__group\"\n >\n <li\n role=\"presentation\"\n id={`${id}-group-${groupIndex}`}\n className=\"mobius-combobox__group-label\"\n >\n {option.heading}\n </li>\n {option.options.map((groupOption, index) => (\n <Option\n // eslint-disable-next-line react/no-array-index-key\n key={`${id}-option-${groupIndex}-${index}`}\n option={groupOption}\n index={index}\n groupIndex={groupIndex}\n isHighlighted={\n highlightedIndex === index &&\n highlightedGroupIndex === groupIndex\n }\n onOptionSelect={onOptionSelect}\n id={id}\n />\n ))}\n </ul>\n ))\n : options.map((option, index) => (\n <Option\n // eslint-disable-next-line react/no-array-index-key\n key={index}\n option={option}\n index={index}\n isHighlighted={highlightedIndex === index}\n onOptionSelect={onOptionSelect}\n id={id}\n />\n ))}\n </div>\n );\n};\n"],"names":["Listbox","id","options","highlightedIndex","highlightedGroupIndex","onOptionSelect","classes","classNames","div","role","className","isOptionGroup","map","option","groupIndex","ul","aria-labelledby","li","heading","groupOption","index","Option","isHighlighted"],"mappings":";;;;+BAaaA;;;eAAAA;;;;mEAbU;wBACA;uBAEO;;;;;;AAUvB,MAAMA,UAAU,CAAC,EACtBC,EAAE,EACFC,OAAO,EACPC,gBAAgB,EAChBC,qBAAqB,EACrBC,cAAc,EACD;IACb,MAAMC,UAAUC,IAAAA,mBAAU,EAAC;IAE3B,qBACE,qBAACC;QAAIC,MAAK;QAAUR,IAAIA;QAAIS,WAAWJ;kBACpCK,IAAAA,oBAAa,EAACT,WACXA,QAAQU,GAAG,CAAC,CAACC,QAAQC,2BACnB,sBAACC;gBACCN,MAAK;gBAELO,mBAAiB,GAAGf,GAAG,OAAO,EAAEa,YAAY;gBAC5CJ,WAAU;;kCAEV,qBAACO;wBACCR,MAAK;wBACLR,IAAI,GAAGA,GAAG,OAAO,EAAEa,YAAY;wBAC/BJ,WAAU;kCAETG,OAAOK,OAAO;;oBAEhBL,OAAOX,OAAO,CAACU,GAAG,CAAC,CAACO,aAAaC,sBAChC,qBAACC,cAAM;4BAGLR,QAAQM;4BACRC,OAAOA;4BACPN,YAAYA;4BACZQ,eACEnB,qBAAqBiB,SACrBhB,0BAA0BU;4BAE5BT,gBAAgBA;4BAChBJ,IAAIA;2BATC,GAAGA,GAAG,QAAQ,EAAEa,WAAW,CAAC,EAAEM,OAAO;;eAdzCP,OAAOK,OAAO,KA4BvBhB,QAAQU,GAAG,CAAC,CAACC,QAAQO,sBACnB,qBAACC,cAAM;gBAGLR,QAAQA;gBACRO,OAAOA;gBACPE,eAAenB,qBAAqBiB;gBACpCf,gBAAgBA;gBAChBJ,IAAIA;eALCmB;;AAUnB"}
1
+ {"version":3,"sources":["../../../../src/components/Combobox/Listbox.tsx"],"sourcesContent":["import classNames from \"classnames\";\nimport { Option } from \"./Option\";\nimport type { ComboboxOption, ComboboxOptions } from \"./types\";\nimport { isOptionGroup } from \"./utils\";\n\nexport type ListboxProps<T extends ComboboxOption> = {\n id: string;\n options: ComboboxOptions<T>;\n highlightedIndex: number;\n highlightedGroupIndex: number;\n onOptionSelect: (option: T) => void;\n};\n\nexport const Listbox = <T extends ComboboxOption>({\n id,\n options,\n highlightedIndex,\n highlightedGroupIndex,\n onOptionSelect,\n}: ListboxProps<T>) => {\n const classes = classNames(\"mobius-combobox__list\");\n\n function getOptionId(\n option: ComboboxOption,\n groupIndex: number,\n index: number,\n ) {\n if (\n typeof option === \"object\" &&\n \"id\" in option &&\n typeof option.id === \"string\"\n ) {\n return option.id;\n }\n return isOptionGroup(options)\n ? `${id}-option-${groupIndex}-${index}`\n : `${id}-option-${index}`;\n }\n\n return (\n <div role=\"listbox\" id={id} className={classes}>\n {isOptionGroup(options)\n ? options.map((option, groupIndex) => (\n <ul\n role=\"group\"\n key={option.heading}\n aria-labelledby={`${id}-group-${groupIndex}`}\n className=\"mobius-combobox__group\"\n >\n <li\n role=\"presentation\"\n id={`${id}-group-${groupIndex}`}\n className=\"mobius-combobox__group-label\"\n >\n {option.heading}\n </li>\n {option.options.map((groupOption, index) => (\n <Option\n // eslint-disable-next-line react/no-array-index-key\n key={`${id}-option-${groupIndex}-${index}`}\n option={groupOption}\n isHighlighted={\n highlightedIndex === index &&\n highlightedGroupIndex === groupIndex\n }\n onOptionSelect={onOptionSelect}\n id={getOptionId(groupOption, groupIndex, index)}\n />\n ))}\n </ul>\n ))\n : options.map((option, index) => (\n <Option\n // eslint-disable-next-line react/no-array-index-key\n key={index}\n option={option}\n isHighlighted={highlightedIndex === index}\n onOptionSelect={onOptionSelect}\n id={getOptionId(option, 0, index)}\n />\n ))}\n </div>\n );\n};\n"],"names":["Listbox","id","options","highlightedIndex","highlightedGroupIndex","onOptionSelect","classes","classNames","getOptionId","option","groupIndex","index","isOptionGroup","div","role","className","map","ul","aria-labelledby","li","heading","groupOption","Option","isHighlighted"],"mappings":";;;;+BAaaA;;;eAAAA;;;;mEAbU;wBACA;uBAEO;;;;;;AAUvB,MAAMA,UAAU,CAA2B,EAChDC,EAAE,EACFC,OAAO,EACPC,gBAAgB,EAChBC,qBAAqB,EACrBC,cAAc,EACE;IAChB,MAAMC,UAAUC,IAAAA,mBAAU,EAAC;IAE3B,SAASC,YACPC,MAAsB,EACtBC,UAAkB,EAClBC,KAAa;QAEb,IACE,OAAOF,WAAW,YAClB,QAAQA,UACR,OAAOA,OAAOR,EAAE,KAAK,UACrB;YACA,OAAOQ,OAAOR,EAAE;QAClB;QACA,OAAOW,IAAAA,oBAAa,EAACV,WACjB,GAAGD,GAAG,QAAQ,EAAES,WAAW,CAAC,EAAEC,OAAO,GACrC,GAAGV,GAAG,QAAQ,EAAEU,OAAO;IAC7B;IAEA,qBACE,qBAACE;QAAIC,MAAK;QAAUb,IAAIA;QAAIc,WAAWT;kBACpCM,IAAAA,oBAAa,EAACV,WACXA,QAAQc,GAAG,CAAC,CAACP,QAAQC,2BACnB,sBAACO;gBACCH,MAAK;gBAELI,mBAAiB,GAAGjB,GAAG,OAAO,EAAES,YAAY;gBAC5CK,WAAU;;kCAEV,qBAACI;wBACCL,MAAK;wBACLb,IAAI,GAAGA,GAAG,OAAO,EAAES,YAAY;wBAC/BK,WAAU;kCAETN,OAAOW,OAAO;;oBAEhBX,OAAOP,OAAO,CAACc,GAAG,CAAC,CAACK,aAAaV,sBAChC,qBAACW,cAAM;4BAGLb,QAAQY;4BACRE,eACEpB,qBAAqBQ,SACrBP,0BAA0BM;4BAE5BL,gBAAgBA;4BAChBJ,IAAIO,YAAYa,aAAaX,YAAYC;2BAPpC,GAAGV,GAAG,QAAQ,EAAES,WAAW,CAAC,EAAEC,OAAO;;eAdzCF,OAAOW,OAAO,KA0BvBlB,QAAQc,GAAG,CAAC,CAACP,QAAQE,sBACnB,qBAACW,cAAM;gBAGLb,QAAQA;gBACRc,eAAepB,qBAAqBQ;gBACpCN,gBAAgBA;gBAChBJ,IAAIO,YAAYC,QAAQ,GAAGE;eAJtBA;;AASnB"}
@@ -17,7 +17,7 @@ function _interop_require_default(obj) {
17
17
  default: obj
18
18
  };
19
19
  }
20
- const Option = ({ option, index, groupIndex = 0, isHighlighted, onOptionSelect, id })=>{
20
+ const Option = ({ option, isHighlighted, onOptionSelect, id })=>{
21
21
  const optionRef = (0, _react.useRef)(null);
22
22
  (0, _react.useEffect)(()=>{
23
23
  if (isHighlighted && optionRef.current && optionRef.current.scrollIntoView) {
@@ -31,7 +31,7 @@ const Option = ({ option, index, groupIndex = 0, isHighlighted, onOptionSelect,
31
31
  return /*#__PURE__*/ (0, _jsxruntime.jsx)("li", {
32
32
  ref: optionRef,
33
33
  role: "option",
34
- id: `${id}-option-${groupIndex}-${index}`,
34
+ id: id,
35
35
  "aria-selected": isHighlighted,
36
36
  onMouseDown: ()=>onOptionSelect(option),
37
37
  className: (0, _dedupe.default)("mobius-combobox__option", {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/Combobox/Option.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport { getOptionValue, getOptionLabel } from \"./utils\";\nimport type { ComboboxOptionProps } from \"./types\";\n\nexport const Option = ({\n option,\n index,\n groupIndex = 0,\n isHighlighted,\n onOptionSelect,\n id,\n}: ComboboxOptionProps) => {\n const optionRef = useRef<HTMLLIElement>(null);\n\n useEffect(() => {\n if (\n isHighlighted &&\n optionRef.current &&\n optionRef.current.scrollIntoView\n ) {\n optionRef.current.scrollIntoView({ block: \"nearest\" });\n }\n }, [isHighlighted]);\n\n return (\n <li\n ref={optionRef}\n role=\"option\"\n key={getOptionValue(option)}\n id={`${id}-option-${groupIndex}-${index}`}\n aria-selected={isHighlighted}\n onMouseDown={() => onOptionSelect(option)}\n className={classNames(\"mobius-combobox__option\", {\n \"mobius-combobox__option--is-highlighted\": isHighlighted,\n })}\n >\n {getOptionLabel(option)}\n </li>\n );\n};\n"],"names":["Option","option","index","groupIndex","isHighlighted","onOptionSelect","id","optionRef","useRef","useEffect","current","scrollIntoView","block","li","ref","role","aria-selected","onMouseDown","className","classNames","getOptionLabel","getOptionValue"],"mappings":";;;;+BAKaA;;;eAAAA;;;;uBALqB;+DACX;uBACwB;;;;;;AAGxC,MAAMA,SAAS,CAAC,EACrBC,MAAM,EACNC,KAAK,EACLC,aAAa,CAAC,EACdC,aAAa,EACbC,cAAc,EACdC,EAAE,EACkB;IACpB,MAAMC,YAAYC,IAAAA,aAAM,EAAgB;IAExCC,IAAAA,gBAAS,EAAC;QACR,IACEL,iBACAG,UAAUG,OAAO,IACjBH,UAAUG,OAAO,CAACC,cAAc,EAChC;YACAJ,UAAUG,OAAO,CAACC,cAAc,CAAC;gBAAEC,OAAO;YAAU;QACtD;IACF,GAAG;QAACR;KAAc;IAElB,qBACE,qBAACS;QACCC,KAAKP;QACLQ,MAAK;QAELT,IAAI,GAAGA,GAAG,QAAQ,EAAEH,WAAW,CAAC,EAAED,OAAO;QACzCc,iBAAeZ;QACfa,aAAa,IAAMZ,eAAeJ;QAClCiB,WAAWC,IAAAA,eAAU,EAAC,2BAA2B;YAC/C,2CAA2Cf;QAC7C;kBAECgB,IAAAA,qBAAc,EAACnB;OARXoB,IAAAA,qBAAc,EAACpB;AAW1B"}
1
+ {"version":3,"sources":["../../../../src/components/Combobox/Option.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport classNames from \"classnames/dedupe\";\nimport { getOptionValue, getOptionLabel } from \"./utils\";\nimport type { ComboboxOption, ComboboxOptionProps } from \"./types\";\n\nexport const Option = <T extends ComboboxOption>({\n option,\n isHighlighted,\n onOptionSelect,\n id,\n}: ComboboxOptionProps<T>) => {\n const optionRef = useRef<HTMLLIElement>(null);\n\n useEffect(() => {\n if (\n isHighlighted &&\n optionRef.current &&\n optionRef.current.scrollIntoView\n ) {\n optionRef.current.scrollIntoView({ block: \"nearest\" });\n }\n }, [isHighlighted]);\n\n return (\n <li\n ref={optionRef}\n role=\"option\"\n key={getOptionValue(option)}\n id={id}\n aria-selected={isHighlighted}\n onMouseDown={() => onOptionSelect(option)}\n className={classNames(\"mobius-combobox__option\", {\n \"mobius-combobox__option--is-highlighted\": isHighlighted,\n })}\n >\n {getOptionLabel(option)}\n </li>\n );\n};\n"],"names":["Option","option","isHighlighted","onOptionSelect","id","optionRef","useRef","useEffect","current","scrollIntoView","block","li","ref","role","aria-selected","onMouseDown","className","classNames","getOptionLabel","getOptionValue"],"mappings":";;;;+BAKaA;;;eAAAA;;;;uBALqB;+DACX;uBACwB;;;;;;AAGxC,MAAMA,SAAS,CAA2B,EAC/CC,MAAM,EACNC,aAAa,EACbC,cAAc,EACdC,EAAE,EACqB;IACvB,MAAMC,YAAYC,IAAAA,aAAM,EAAgB;IAExCC,IAAAA,gBAAS,EAAC;QACR,IACEL,iBACAG,UAAUG,OAAO,IACjBH,UAAUG,OAAO,CAACC,cAAc,EAChC;YACAJ,UAAUG,OAAO,CAACC,cAAc,CAAC;gBAAEC,OAAO;YAAU;QACtD;IACF,GAAG;QAACR;KAAc;IAElB,qBACE,qBAACS;QACCC,KAAKP;QACLQ,MAAK;QAELT,IAAIA;QACJU,iBAAeZ;QACfa,aAAa,IAAMZ,eAAeF;QAClCe,WAAWC,IAAAA,eAAU,EAAC,2BAA2B;YAC/C,2CAA2Cf;QAC7C;kBAECgB,IAAAA,qBAAc,EAACjB;OARXkB,IAAAA,qBAAc,EAAClB;AAW1B"}
@@ -11,7 +11,7 @@ Object.defineProperty(exports, "useComboboxOptions", {
11
11
  const _react = require("react");
12
12
  const _utils = require("./utils");
13
13
  const _hooks = require("../../hooks");
14
- function useComboboxOptions({ options, asyncOptions, delay = 300, minLength = 3, inputValue = "" }) {
14
+ function useComboboxOptions({ options, asyncOptions, delay = 300, minLength = 3, inputValue = "", skipNextDebounceRef }) {
15
15
  const [filteredOptions, setFilteredOptions] = (0, _react.useState)([]);
16
16
  const debouncedInputValue = (0, _hooks.useDebouncedValue)(inputValue, // Don't debounce synchronous options
17
17
  options ? 0 : delay);
@@ -34,7 +34,7 @@ function useComboboxOptions({ options, asyncOptions, delay = 300, minLength = 3,
34
34
  });
35
35
  setFilteredOptions(result);
36
36
  } else {
37
- // @ts-expect-error options will always be set here, fix the types
37
+ // @ts-expect-error options is erroneously typed as possibly undefined
38
38
  setFilteredOptions((0, _utils.filterOptions)(options, debouncedInputValue));
39
39
  }
40
40
  } catch (e) {
@@ -47,7 +47,12 @@ function useComboboxOptions({ options, asyncOptions, delay = 300, minLength = 3,
47
47
  setIsLoading(false);
48
48
  }
49
49
  };
50
- fetchOptions();
50
+ if (!(skipNextDebounceRef === null || skipNextDebounceRef === void 0 ? void 0 : skipNextDebounceRef.current)) {
51
+ fetchOptions();
52
+ } else {
53
+ // eslint-disable-next-line no-param-reassign
54
+ skipNextDebounceRef.current = false;
55
+ }
51
56
  return ()=>{
52
57
  controller.abort();
53
58
  };
@@ -56,7 +61,8 @@ function useComboboxOptions({ options, asyncOptions, delay = 300, minLength = 3,
56
61
  options,
57
62
  asyncOptions,
58
63
  delay,
59
- minLength
64
+ minLength,
65
+ skipNextDebounceRef
60
66
  ]);
61
67
  function updateFilteredOptions(newOptions) {
62
68
  setIsLoading(true);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/Combobox/useComboboxOptions.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport type { ComboboxOptions, ComboboxProps } from \"./types\";\nimport { filterOptions } from \"./utils\";\nimport { useDebouncedValue } from \"../../hooks\";\n\nexport type UseComboboxOptionsProps = Pick<\n ComboboxProps,\n \"options\" | \"asyncOptions\" | \"delay\" | \"minLength\"\n> & {\n inputValue?: string;\n};\n\nexport function useComboboxOptions({\n options,\n asyncOptions,\n delay = 300,\n minLength = 3,\n inputValue = \"\",\n}: UseComboboxOptionsProps) {\n const [filteredOptions, setFilteredOptions] = useState<ComboboxOptions>([]);\n const debouncedInputValue = useDebouncedValue(\n inputValue,\n // Don't debounce synchronous options\n options ? 0 : delay,\n );\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n const controller = new AbortController();\n const { signal } = controller;\n\n const fetchOptions = async () => {\n setIsLoading(true);\n setError(null);\n try {\n if (asyncOptions) {\n if (debouncedInputValue.length < minLength) {\n setFilteredOptions([]);\n return;\n }\n const result = await asyncOptions(debouncedInputValue, { signal });\n setFilteredOptions(result);\n } else {\n // @ts-expect-error options will always be set here, fix the types\n setFilteredOptions(filterOptions(options, debouncedInputValue));\n }\n } catch (e: unknown) {\n if (e instanceof DOMException && e.name === \"AbortError\") {\n // Ignore abort errors\n return;\n }\n setError(e as Error);\n } finally {\n setIsLoading(false);\n }\n };\n\n fetchOptions();\n\n return () => {\n controller.abort();\n };\n }, [debouncedInputValue, options, asyncOptions, delay, minLength]);\n\n function updateFilteredOptions(newOptions: Promise<ComboboxOptions>) {\n setIsLoading(true);\n return newOptions\n .then(setFilteredOptions)\n .catch(setError)\n .finally(() => setIsLoading(false));\n }\n\n return {\n filteredOptions,\n updateFilteredOptions,\n isLoading,\n error,\n isError: error != null,\n };\n}\n"],"names":["useComboboxOptions","options","asyncOptions","delay","minLength","inputValue","filteredOptions","setFilteredOptions","useState","debouncedInputValue","useDebouncedValue","isLoading","setIsLoading","error","setError","useEffect","controller","AbortController","signal","fetchOptions","length","result","filterOptions","e","DOMException","name","abort","updateFilteredOptions","newOptions","then","catch","finally","isError"],"mappings":";;;;+BAYgBA;;;eAAAA;;;uBAZoB;uBAEN;uBACI;AAS3B,SAASA,mBAAmB,EACjCC,OAAO,EACPC,YAAY,EACZC,QAAQ,GAAG,EACXC,YAAY,CAAC,EACbC,aAAa,EAAE,EACS;IACxB,MAAM,CAACC,iBAAiBC,mBAAmB,GAAGC,IAAAA,eAAQ,EAAkB,EAAE;IAC1E,MAAMC,sBAAsBC,IAAAA,wBAAiB,EAC3CL,YACA,qCAAqC;IACrCJ,UAAU,IAAIE;IAEhB,MAAM,CAACQ,WAAWC,aAAa,GAAGJ,IAAAA,eAAQ,EAAC;IAC3C,MAAM,CAACK,OAAOC,SAAS,GAAGN,IAAAA,eAAQ,EAAe;IAEjDO,IAAAA,gBAAS,EAAC;QACR,MAAMC,aAAa,IAAIC;QACvB,MAAM,EAAEC,MAAM,EAAE,GAAGF;QAEnB,MAAMG,eAAe;YACnBP,aAAa;YACbE,SAAS;YACT,IAAI;gBACF,IAAIZ,cAAc;oBAChB,IAAIO,oBAAoBW,MAAM,GAAGhB,WAAW;wBAC1CG,mBAAmB,EAAE;wBACrB;oBACF;oBACA,MAAMc,SAAS,MAAMnB,aAAaO,qBAAqB;wBAAES;oBAAO;oBAChEX,mBAAmBc;gBACrB,OAAO;oBACL,kEAAkE;oBAClEd,mBAAmBe,IAAAA,oBAAa,EAACrB,SAASQ;gBAC5C;YACF,EAAE,OAAOc,GAAY;gBACnB,IAAIA,aAAaC,gBAAgBD,EAAEE,IAAI,KAAK,cAAc;oBACxD,sBAAsB;oBACtB;gBACF;gBACAX,SAASS;YACX,SAAU;gBACRX,aAAa;YACf;QACF;QAEAO;QAEA,OAAO;YACLH,WAAWU,KAAK;QAClB;IACF,GAAG;QAACjB;QAAqBR;QAASC;QAAcC;QAAOC;KAAU;IAEjE,SAASuB,sBAAsBC,UAAoC;QACjEhB,aAAa;QACb,OAAOgB,WACJC,IAAI,CAACtB,oBACLuB,KAAK,CAAChB,UACNiB,OAAO,CAAC,IAAMnB,aAAa;IAChC;IAEA,OAAO;QACLN;QACAqB;QACAhB;QACAE;QACAmB,SAASnB,SAAS;IACpB;AACF"}
1
+ {"version":3,"sources":["../../../../src/components/Combobox/useComboboxOptions.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport type { ComboboxOption, ComboboxOptions, ComboboxProps } from \"./types\";\nimport { filterOptions } from \"./utils\";\nimport { useDebouncedValue } from \"../../hooks\";\n\nexport type UseComboboxOptionsProps<T extends ComboboxOption> = Pick<\n ComboboxProps<T>,\n \"options\" | \"asyncOptions\" | \"delay\" | \"minLength\"\n> & {\n skipNextDebounceRef?: React.MutableRefObject<boolean>;\n inputValue?: string;\n};\n\nexport function useComboboxOptions<T extends ComboboxOption>({\n options,\n asyncOptions,\n delay = 300,\n minLength = 3,\n inputValue = \"\",\n skipNextDebounceRef,\n}: UseComboboxOptionsProps<T>) {\n const [filteredOptions, setFilteredOptions] = useState<ComboboxOptions<T>>(\n [],\n );\n const debouncedInputValue = useDebouncedValue(\n inputValue,\n // Don't debounce synchronous options\n options ? 0 : delay,\n );\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n const controller = new AbortController();\n const { signal } = controller;\n\n const fetchOptions = async () => {\n setIsLoading(true);\n setError(null);\n try {\n if (asyncOptions) {\n if (debouncedInputValue.length < minLength) {\n setFilteredOptions([]);\n return;\n }\n const result = await asyncOptions(debouncedInputValue, { signal });\n setFilteredOptions(result);\n } else {\n // @ts-expect-error options is erroneously typed as possibly undefined\n setFilteredOptions(filterOptions(options, debouncedInputValue));\n }\n } catch (e: unknown) {\n if (e instanceof DOMException && e.name === \"AbortError\") {\n // Ignore abort errors\n return;\n }\n setError(e as Error);\n } finally {\n setIsLoading(false);\n }\n };\n\n if (!skipNextDebounceRef?.current) {\n fetchOptions();\n } else {\n // eslint-disable-next-line no-param-reassign\n skipNextDebounceRef.current = false;\n }\n\n return () => {\n controller.abort();\n };\n }, [\n debouncedInputValue,\n options,\n asyncOptions,\n delay,\n minLength,\n skipNextDebounceRef,\n ]);\n\n function updateFilteredOptions(newOptions: Promise<ComboboxOptions<T>>) {\n setIsLoading(true);\n return newOptions\n .then(setFilteredOptions)\n .catch(setError)\n .finally(() => setIsLoading(false));\n }\n\n return {\n filteredOptions,\n updateFilteredOptions,\n isLoading,\n error,\n isError: error != null,\n };\n}\n"],"names":["useComboboxOptions","options","asyncOptions","delay","minLength","inputValue","skipNextDebounceRef","filteredOptions","setFilteredOptions","useState","debouncedInputValue","useDebouncedValue","isLoading","setIsLoading","error","setError","useEffect","controller","AbortController","signal","fetchOptions","length","result","filterOptions","e","DOMException","name","current","abort","updateFilteredOptions","newOptions","then","catch","finally","isError"],"mappings":";;;;+BAagBA;;;eAAAA;;;uBAboB;uBAEN;uBACI;AAU3B,SAASA,mBAA6C,EAC3DC,OAAO,EACPC,YAAY,EACZC,QAAQ,GAAG,EACXC,YAAY,CAAC,EACbC,aAAa,EAAE,EACfC,mBAAmB,EACQ;IAC3B,MAAM,CAACC,iBAAiBC,mBAAmB,GAAGC,IAAAA,eAAQ,EACpD,EAAE;IAEJ,MAAMC,sBAAsBC,IAAAA,wBAAiB,EAC3CN,YACA,qCAAqC;IACrCJ,UAAU,IAAIE;IAEhB,MAAM,CAACS,WAAWC,aAAa,GAAGJ,IAAAA,eAAQ,EAAC;IAC3C,MAAM,CAACK,OAAOC,SAAS,GAAGN,IAAAA,eAAQ,EAAe;IAEjDO,IAAAA,gBAAS,EAAC;QACR,MAAMC,aAAa,IAAIC;QACvB,MAAM,EAAEC,MAAM,EAAE,GAAGF;QAEnB,MAAMG,eAAe;YACnBP,aAAa;YACbE,SAAS;YACT,IAAI;gBACF,IAAIb,cAAc;oBAChB,IAAIQ,oBAAoBW,MAAM,GAAGjB,WAAW;wBAC1CI,mBAAmB,EAAE;wBACrB;oBACF;oBACA,MAAMc,SAAS,MAAMpB,aAAaQ,qBAAqB;wBAAES;oBAAO;oBAChEX,mBAAmBc;gBACrB,OAAO;oBACL,sEAAsE;oBACtEd,mBAAmBe,IAAAA,oBAAa,EAACtB,SAASS;gBAC5C;YACF,EAAE,OAAOc,GAAY;gBACnB,IAAIA,aAAaC,gBAAgBD,EAAEE,IAAI,KAAK,cAAc;oBACxD,sBAAsB;oBACtB;gBACF;gBACAX,SAASS;YACX,SAAU;gBACRX,aAAa;YACf;QACF;QAEA,IAAI,EAACP,gCAAAA,0CAAAA,oBAAqBqB,OAAO,GAAE;YACjCP;QACF,OAAO;YACL,6CAA6C;YAC7Cd,oBAAoBqB,OAAO,GAAG;QAChC;QAEA,OAAO;YACLV,WAAWW,KAAK;QAClB;IACF,GAAG;QACDlB;QACAT;QACAC;QACAC;QACAC;QACAE;KACD;IAED,SAASuB,sBAAsBC,UAAuC;QACpEjB,aAAa;QACb,OAAOiB,WACJC,IAAI,CAACvB,oBACLwB,KAAK,CAACjB,UACNkB,OAAO,CAAC,IAAMpB,aAAa;IAChC;IAEA,OAAO;QACLN;QACAsB;QACAjB;QACAE;QACAoB,SAASpB,SAAS;IACpB;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/Combobox/utils.tsx"],"sourcesContent":["import type {\n ComboboxOption,\n ComboboxOptionGroup,\n ComboboxOptions,\n} from \"./types\";\n\n// FIXME: This might be better handled with Zod\nexport function isOptionGroup(\n options: ComboboxOptions,\n): options is ComboboxOptionGroup[] {\n return (\n typeof options[0] === \"object\" &&\n \"options\" in options[0] &&\n options[0].options !== undefined &&\n \"heading\" in options[0] &&\n options[0].heading !== undefined\n );\n}\n\nexport const getOptionValue = (option: ComboboxOption | undefined) =>\n typeof option === \"string\" ? option : option?.value;\n\nexport const getOptionLabel = (option: ComboboxOption | undefined) =>\n typeof option === \"string\" ? option : option?.label;\n\nexport function filterOptions(\n options: ComboboxOptions,\n inputValue: string,\n): ComboboxOptions {\n if (isOptionGroup(options)) {\n return options\n .map(optionGroup => ({\n ...optionGroup,\n options: optionGroup.options.filter(option =>\n getOptionLabel(option)!\n .toLowerCase()\n .includes(inputValue.toLowerCase()),\n ),\n }))\n .filter(optionGroup => optionGroup.options.length > 0);\n }\n\n return options.filter(option =>\n getOptionLabel(option)!.toLowerCase().includes(inputValue.toLowerCase()),\n );\n}\n\nexport function clamp(value: number, min: number, max: number) {\n return Math.min(Math.max(value, min), max);\n}\n"],"names":["clamp","filterOptions","getOptionLabel","getOptionValue","isOptionGroup","options","undefined","heading","option","value","label","inputValue","map","optionGroup","filter","toLowerCase","includes","length","min","max","Math"],"mappings":";;;;;;;;;;;IA+CgBA,KAAK;eAALA;;IAtBAC,aAAa;eAAbA;;IAHHC,cAAc;eAAdA;;IAHAC,cAAc;eAAdA;;IAZGC,aAAa;eAAbA;;;AAAT,SAASA,cACdC,OAAwB;IAExB,OACE,OAAOA,OAAO,CAAC,EAAE,KAAK,YACtB,aAAaA,OAAO,CAAC,EAAE,IACvBA,OAAO,CAAC,EAAE,CAACA,OAAO,KAAKC,aACvB,aAAaD,OAAO,CAAC,EAAE,IACvBA,OAAO,CAAC,EAAE,CAACE,OAAO,KAAKD;AAE3B;AAEO,MAAMH,iBAAiB,CAACK,SAC7B,OAAOA,WAAW,WAAWA,SAASA,mBAAAA,6BAAAA,OAAQC,KAAK;AAE9C,MAAMP,iBAAiB,CAACM,SAC7B,OAAOA,WAAW,WAAWA,SAASA,mBAAAA,6BAAAA,OAAQE,KAAK;AAE9C,SAAST,cACdI,OAAwB,EACxBM,UAAkB;IAElB,IAAIP,cAAcC,UAAU;QAC1B,OAAOA,QACJO,GAAG,CAACC,CAAAA,cAAgB,CAAA;gBACnB,GAAGA,WAAW;gBACdR,SAASQ,YAAYR,OAAO,CAACS,MAAM,CAACN,CAAAA,SAClCN,eAAeM,QACZO,WAAW,GACXC,QAAQ,CAACL,WAAWI,WAAW;YAEtC,CAAA,GACCD,MAAM,CAACD,CAAAA,cAAeA,YAAYR,OAAO,CAACY,MAAM,GAAG;IACxD;IAEA,OAAOZ,QAAQS,MAAM,CAACN,CAAAA,SACpBN,eAAeM,QAASO,WAAW,GAAGC,QAAQ,CAACL,WAAWI,WAAW;AAEzE;AAEO,SAASf,MAAMS,KAAa,EAAES,GAAW,EAAEC,GAAW;IAC3D,OAAOC,KAAKF,GAAG,CAACE,KAAKD,GAAG,CAACV,OAAOS,MAAMC;AACxC"}
1
+ {"version":3,"sources":["../../../../src/components/Combobox/utils.tsx"],"sourcesContent":["import type {\n ComboboxOption,\n ComboboxOptionGroup,\n ComboboxOptions,\n} from \"./types\";\n\n// FIXME: This might be better handled with Zod\nexport function isOptionGroup<T extends ComboboxOption>(\n options: ComboboxOptions<T>,\n): options is ComboboxOptionGroup<T>[] {\n return (\n typeof options[0] === \"object\" &&\n \"options\" in options[0] &&\n options[0].options !== undefined &&\n \"heading\" in options[0] &&\n options[0].heading !== undefined\n );\n}\n\nexport const getOptionValue = (option: ComboboxOption | undefined) =>\n typeof option === \"string\" ? option : option?.value;\n\nexport const getOptionLabel = (option: ComboboxOption | undefined) =>\n typeof option === \"string\" ? option : option?.label;\n\nexport function filterOptions<T extends ComboboxOption>(\n options: ComboboxOptions<T>,\n inputValue: string,\n): ComboboxOptions<T> {\n if (isOptionGroup(options)) {\n return options\n .map(optionGroup => ({\n ...optionGroup,\n options: optionGroup.options.filter(option =>\n getOptionLabel(option)!\n .toLowerCase()\n .includes(inputValue.toLowerCase()),\n ),\n }))\n .filter(optionGroup => optionGroup.options.length > 0);\n }\n\n return options.filter(option =>\n getOptionLabel(option)!.toLowerCase().includes(inputValue.toLowerCase()),\n );\n}\n\nexport function clamp(value: number, min: number, max: number) {\n return Math.min(Math.max(value, min), max);\n}\n"],"names":["clamp","filterOptions","getOptionLabel","getOptionValue","isOptionGroup","options","undefined","heading","option","value","label","inputValue","map","optionGroup","filter","toLowerCase","includes","length","min","max","Math"],"mappings":";;;;;;;;;;;IA+CgBA,KAAK;eAALA;;IAtBAC,aAAa;eAAbA;;IAHHC,cAAc;eAAdA;;IAHAC,cAAc;eAAdA;;IAZGC,aAAa;eAAbA;;;AAAT,SAASA,cACdC,OAA2B;IAE3B,OACE,OAAOA,OAAO,CAAC,EAAE,KAAK,YACtB,aAAaA,OAAO,CAAC,EAAE,IACvBA,OAAO,CAAC,EAAE,CAACA,OAAO,KAAKC,aACvB,aAAaD,OAAO,CAAC,EAAE,IACvBA,OAAO,CAAC,EAAE,CAACE,OAAO,KAAKD;AAE3B;AAEO,MAAMH,iBAAiB,CAACK,SAC7B,OAAOA,WAAW,WAAWA,SAASA,mBAAAA,6BAAAA,OAAQC,KAAK;AAE9C,MAAMP,iBAAiB,CAACM,SAC7B,OAAOA,WAAW,WAAWA,SAASA,mBAAAA,6BAAAA,OAAQE,KAAK;AAE9C,SAAST,cACdI,OAA2B,EAC3BM,UAAkB;IAElB,IAAIP,cAAcC,UAAU;QAC1B,OAAOA,QACJO,GAAG,CAACC,CAAAA,cAAgB,CAAA;gBACnB,GAAGA,WAAW;gBACdR,SAASQ,YAAYR,OAAO,CAACS,MAAM,CAACN,CAAAA,SAClCN,eAAeM,QACZO,WAAW,GACXC,QAAQ,CAACL,WAAWI,WAAW;YAEtC,CAAA,GACCD,MAAM,CAACD,CAAAA,cAAeA,YAAYR,OAAO,CAACY,MAAM,GAAG;IACxD;IAEA,OAAOZ,QAAQS,MAAM,CAACN,CAAAA,SACpBN,eAAeM,QAASO,WAAW,GAAGC,QAAQ,CAACL,WAAWI,WAAW;AAEzE;AAEO,SAASf,MAAMS,KAAa,EAAES,GAAW,EAAEC,GAAW;IAC3D,OAAOC,KAAKF,GAAG,CAACE,KAAKD,GAAG,CAACV,OAAOS,MAAMC;AACxC"}
@@ -59,11 +59,11 @@ const TextField = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
59
59
  /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
60
60
  className: "mobius-text-field__inner-container",
61
61
  children: [
62
- (0, _adornmentWithClassName.adornmentWithClassName)(prefixOutside, "mobius-text-field__prefix-outside"),
62
+ (0, _adornmentWithClassName.adornmentWithClassName)(prefixOutside, labelClasses, "mobius-text-field__prefix-outside"),
63
63
  /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
64
64
  className: inputWrapperClasses,
65
65
  children: [
66
- (0, _adornmentWithClassName.adornmentWithClassName)(prefixInside, "mobius-text-field__prefix-inside"),
66
+ (0, _adornmentWithClassName.adornmentWithClassName)(prefixInside, labelClasses, "mobius-text-field__prefix-inside"),
67
67
  /*#__PURE__*/ (0, _jsxruntime.jsx)("input", {
68
68
  ...otherProps,
69
69
  ...inputProps,
@@ -72,10 +72,10 @@ const TextField = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
72
72
  className: inputClasses,
73
73
  readOnly: isReadOnly
74
74
  }),
75
- (0, _adornmentWithClassName.adornmentWithClassName)(suffixInside, "mobius-text-field__suffix-inside")
75
+ (0, _adornmentWithClassName.adornmentWithClassName)(suffixInside, labelClasses, "mobius-text-field__suffix-inside")
76
76
  ]
77
77
  }),
78
- (0, _adornmentWithClassName.adornmentWithClassName)(suffixOutside, "mobius-text-field__suffix-outside")
78
+ (0, _adornmentWithClassName.adornmentWithClassName)(suffixOutside, labelClasses, "mobius-text-field__suffix-outside")
79
79
  ]
80
80
  }),
81
81
  children && /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/TextField/TextField.tsx"],"sourcesContent":["\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport {\n HTMLInputTypeAttribute,\n ReactElement,\n ReactNode,\n Ref,\n RefAttributes,\n forwardRef,\n} from \"react\";\nimport {\n UseTextFieldProps,\n useTextField,\n useValidationClasses,\n} from \"../../hooks\";\nimport { DOMProps, FocusEvents } from \"../../types\";\nimport { ForwardedRefComponent } from \"../../types/components\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport { Stack } from \"../Stack\";\nimport { adornmentWithClassName } from \"./adornmentWithClassName\";\n\nexport type TextFieldElementType = HTMLInputElement;\nexport interface TextFieldProps\n extends DOMProps,\n FocusEvents,\n UseTextFieldProps,\n RefAttributes<TextFieldElementType> {\n className?: string;\n errorMessage?: string;\n children?: ReactNode;\n label?: string;\n type?: Exclude<\n HTMLInputTypeAttribute,\n | \"button\"\n | \"checkbox\"\n | \"color\"\n | \"date\"\n | \"datetime-local\"\n | \"file\"\n | \"image\"\n | \"month\"\n | \"radio\"\n | \"range\"\n | \"reset\"\n | \"submit\"\n | \"week\"\n >;\n prefixInside?: ReactElement;\n prefixOutside?: ReactElement;\n suffixInside?: ReactElement;\n suffixOutside?: ReactElement;\n}\n\nexport type TextFieldRef = Ref<TextFieldElementType>;\n\nconst TextField: ForwardedRefComponent<TextFieldProps, TextFieldElementType> =\n forwardRef((props: TextFieldProps, ref: TextFieldRef) => {\n const {\n isDisabled,\n isReadOnly,\n type = \"text\",\n validationState,\n isInvalid,\n className,\n label,\n errorMessage,\n children,\n isRequired,\n prefixInside,\n prefixOutside,\n suffixInside,\n suffixOutside,\n ...otherProps\n } = props;\n\n const { inputProps, labelProps, errorMessageProps } = useTextField({\n ...props,\n \"aria-errormessage\": errorMessage,\n });\n\n const hidden = type === \"hidden\";\n\n const validationClasses = useValidationClasses({\n validationState,\n isInvalid,\n });\n\n const textfieldClasses = {\n \"--is-disabled\": isDisabled,\n \"--is-required\": typeof isRequired === \"boolean\" && isRequired,\n \"--is-optional\": typeof isRequired === \"boolean\" && !isRequired,\n \"--is-hidden\": hidden,\n [className || \"\"]: true,\n };\n\n const sharedClasses = classNames(validationClasses, textfieldClasses);\n\n const labelClasses = classNames(\n {\n \"--is-disabled\": isDisabled,\n },\n validationClasses,\n );\n\n const containerClasses = classNames(\n \"mobius\",\n \"mobius-text-field\",\n sharedClasses,\n );\n\n const inputClasses = classNames(\n \"mobius\",\n \"mobius-text-field__input\",\n sharedClasses,\n );\n\n const inputWrapperClasses = classNames(\n \"mobius-text-field__input-wrapper\",\n sharedClasses,\n );\n\n return (\n <Stack gap=\"xs\" className={containerClasses}>\n {label && !hidden && (\n <Label {...labelProps} className={labelClasses}>\n {label}\n </Label>\n )}\n <div className=\"mobius-text-field__inner-container\">\n {adornmentWithClassName(\n prefixOutside,\n \"mobius-text-field__prefix-outside\",\n )}\n <div className={inputWrapperClasses}>\n {adornmentWithClassName(\n prefixInside,\n \"mobius-text-field__prefix-inside\",\n )}\n <input\n {...otherProps}\n {...inputProps}\n ref={ref}\n type={type}\n className={inputClasses}\n readOnly={isReadOnly}\n />\n {adornmentWithClassName(\n suffixInside,\n \"mobius-text-field__suffix-inside\",\n )}\n </div>\n {adornmentWithClassName(\n suffixOutside,\n \"mobius-text-field__suffix-outside\",\n )}\n </div>\n {children && (\n <div className=\"mobius-text-field__children\">{children}</div>\n )}\n\n <ErrorMessage {...errorMessageProps} errorMessage={errorMessage} />\n </Stack>\n );\n });\n\nTextField.displayName = \"TextField\";\nexport { TextField };\n"],"names":["TextField","forwardRef","props","ref","isDisabled","isReadOnly","type","validationState","isInvalid","className","label","errorMessage","children","isRequired","prefixInside","prefixOutside","suffixInside","suffixOutside","otherProps","inputProps","labelProps","errorMessageProps","useTextField","hidden","validationClasses","useValidationClasses","textfieldClasses","sharedClasses","classNames","labelClasses","containerClasses","inputClasses","inputWrapperClasses","Stack","gap","Label","div","adornmentWithClassName","input","readOnly","ErrorMessage","displayName"],"mappings":"AAAA;;;;;+BAwKSA;;;eAAAA;;;;+DAtKc;uBAQhB;uBAKA;8BAGsB;uBACP;uBACA;wCACiB;;;;;;AAoCvC,MAAMA,0BACJC,IAAAA,iBAAU,EAAC,CAACC,OAAuBC;IACjC,MAAM,EACJC,UAAU,EACVC,UAAU,EACVC,OAAO,MAAM,EACbC,eAAe,EACfC,SAAS,EACTC,SAAS,EACTC,KAAK,EACLC,YAAY,EACZC,QAAQ,EACRC,UAAU,EACVC,YAAY,EACZC,aAAa,EACbC,YAAY,EACZC,aAAa,EACb,GAAGC,YACJ,GAAGhB;IAEJ,MAAM,EAAEiB,UAAU,EAAEC,UAAU,EAAEC,iBAAiB,EAAE,GAAGC,IAAAA,mBAAY,EAAC;QACjE,GAAGpB,KAAK;QACR,qBAAqBS;IACvB;IAEA,MAAMY,SAASjB,SAAS;IAExB,MAAMkB,oBAAoBC,IAAAA,2BAAoB,EAAC;QAC7ClB;QACAC;IACF;IAEA,MAAMkB,mBAAmB;QACvB,iBAAiBtB;QACjB,iBAAiB,OAAOS,eAAe,aAAaA;QACpD,iBAAiB,OAAOA,eAAe,aAAa,CAACA;QACrD,eAAeU;QACf,CAACd,aAAa,GAAG,EAAE;IACrB;IAEA,MAAMkB,gBAAgBC,IAAAA,eAAU,EAACJ,mBAAmBE;IAEpD,MAAMG,eAAeD,IAAAA,eAAU,EAC7B;QACE,iBAAiBxB;IACnB,GACAoB;IAGF,MAAMM,mBAAmBF,IAAAA,eAAU,EACjC,UACA,qBACAD;IAGF,MAAMI,eAAeH,IAAAA,eAAU,EAC7B,UACA,4BACAD;IAGF,MAAMK,sBAAsBJ,IAAAA,eAAU,EACpC,oCACAD;IAGF,qBACE,sBAACM,YAAK;QAACC,KAAI;QAAKzB,WAAWqB;;YACxBpB,SAAS,CAACa,wBACT,qBAACY,YAAK;gBAAE,GAAGf,UAAU;gBAAEX,WAAWoB;0BAC/BnB;;0BAGL,sBAAC0B;gBAAI3B,WAAU;;oBACZ4B,IAAAA,8CAAsB,EACrBtB,eACA;kCAEF,sBAACqB;wBAAI3B,WAAWuB;;4BACbK,IAAAA,8CAAsB,EACrBvB,cACA;0CAEF,qBAACwB;gCACE,GAAGpB,UAAU;gCACb,GAAGC,UAAU;gCACdhB,KAAKA;gCACLG,MAAMA;gCACNG,WAAWsB;gCACXQ,UAAUlC;;4BAEXgC,IAAAA,8CAAsB,EACrBrB,cACA;;;oBAGHqB,IAAAA,8CAAsB,EACrBpB,eACA;;;YAGHL,0BACC,qBAACwB;gBAAI3B,WAAU;0BAA+BG;;0BAGhD,qBAAC4B,0BAAY;gBAAE,GAAGnB,iBAAiB;gBAAEV,cAAcA;;;;AAGzD;AAEFX,UAAUyC,WAAW,GAAG"}
1
+ {"version":3,"sources":["../../../../src/components/TextField/TextField.tsx"],"sourcesContent":["\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport {\n HTMLInputTypeAttribute,\n ReactElement,\n ReactNode,\n Ref,\n RefAttributes,\n forwardRef,\n} from \"react\";\nimport {\n UseTextFieldProps,\n useTextField,\n useValidationClasses,\n} from \"../../hooks\";\nimport { DOMProps, FocusEvents } from \"../../types\";\nimport { ForwardedRefComponent } from \"../../types/components\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport { Stack } from \"../Stack\";\nimport { adornmentWithClassName } from \"./adornmentWithClassName\";\n\nexport type TextFieldElementType = HTMLInputElement;\nexport interface TextFieldProps\n extends DOMProps,\n FocusEvents,\n UseTextFieldProps,\n RefAttributes<TextFieldElementType> {\n className?: string;\n errorMessage?: string;\n children?: ReactNode;\n label?: string;\n type?: Exclude<\n HTMLInputTypeAttribute,\n | \"button\"\n | \"checkbox\"\n | \"color\"\n | \"date\"\n | \"datetime-local\"\n | \"file\"\n | \"image\"\n | \"month\"\n | \"radio\"\n | \"range\"\n | \"reset\"\n | \"submit\"\n | \"week\"\n >;\n prefixInside?: ReactElement;\n prefixOutside?: ReactElement;\n suffixInside?: ReactElement;\n suffixOutside?: ReactElement;\n}\n\nexport type TextFieldRef = Ref<TextFieldElementType>;\n\nconst TextField: ForwardedRefComponent<TextFieldProps, TextFieldElementType> =\n forwardRef((props: TextFieldProps, ref: TextFieldRef) => {\n const {\n isDisabled,\n isReadOnly,\n type = \"text\",\n validationState,\n isInvalid,\n className,\n label,\n errorMessage,\n children,\n isRequired,\n prefixInside,\n prefixOutside,\n suffixInside,\n suffixOutside,\n ...otherProps\n } = props;\n\n const { inputProps, labelProps, errorMessageProps } = useTextField({\n ...props,\n \"aria-errormessage\": errorMessage,\n });\n\n const hidden = type === \"hidden\";\n\n const validationClasses = useValidationClasses({\n validationState,\n isInvalid,\n });\n\n const textfieldClasses = {\n \"--is-disabled\": isDisabled,\n \"--is-required\": typeof isRequired === \"boolean\" && isRequired,\n \"--is-optional\": typeof isRequired === \"boolean\" && !isRequired,\n \"--is-hidden\": hidden,\n [className || \"\"]: true,\n };\n\n const sharedClasses = classNames(validationClasses, textfieldClasses);\n\n const labelClasses = classNames(\n {\n \"--is-disabled\": isDisabled,\n },\n validationClasses,\n );\n\n const containerClasses = classNames(\n \"mobius\",\n \"mobius-text-field\",\n sharedClasses,\n );\n\n const inputClasses = classNames(\n \"mobius\",\n \"mobius-text-field__input\",\n sharedClasses,\n );\n\n const inputWrapperClasses = classNames(\n \"mobius-text-field__input-wrapper\",\n sharedClasses,\n );\n\n return (\n <Stack gap=\"xs\" className={containerClasses}>\n {label && !hidden && (\n <Label {...labelProps} className={labelClasses}>\n {label}\n </Label>\n )}\n <div className=\"mobius-text-field__inner-container\">\n {adornmentWithClassName(\n prefixOutside,\n labelClasses,\n \"mobius-text-field__prefix-outside\",\n )}\n <div className={inputWrapperClasses}>\n {adornmentWithClassName(\n prefixInside,\n labelClasses,\n \"mobius-text-field__prefix-inside\",\n )}\n <input\n {...otherProps}\n {...inputProps}\n ref={ref}\n type={type}\n className={inputClasses}\n readOnly={isReadOnly}\n />\n {adornmentWithClassName(\n suffixInside,\n labelClasses,\n \"mobius-text-field__suffix-inside\",\n )}\n </div>\n {adornmentWithClassName(\n suffixOutside,\n labelClasses,\n \"mobius-text-field__suffix-outside\",\n )}\n </div>\n {children && (\n <div className=\"mobius-text-field__children\">{children}</div>\n )}\n\n <ErrorMessage {...errorMessageProps} errorMessage={errorMessage} />\n </Stack>\n );\n });\n\nTextField.displayName = \"TextField\";\nexport { TextField };\n"],"names":["TextField","forwardRef","props","ref","isDisabled","isReadOnly","type","validationState","isInvalid","className","label","errorMessage","children","isRequired","prefixInside","prefixOutside","suffixInside","suffixOutside","otherProps","inputProps","labelProps","errorMessageProps","useTextField","hidden","validationClasses","useValidationClasses","textfieldClasses","sharedClasses","classNames","labelClasses","containerClasses","inputClasses","inputWrapperClasses","Stack","gap","Label","div","adornmentWithClassName","input","readOnly","ErrorMessage","displayName"],"mappings":"AAAA;;;;;+BA4KSA;;;eAAAA;;;;+DA1Kc;uBAQhB;uBAKA;8BAGsB;uBACP;uBACA;wCACiB;;;;;;AAoCvC,MAAMA,0BACJC,IAAAA,iBAAU,EAAC,CAACC,OAAuBC;IACjC,MAAM,EACJC,UAAU,EACVC,UAAU,EACVC,OAAO,MAAM,EACbC,eAAe,EACfC,SAAS,EACTC,SAAS,EACTC,KAAK,EACLC,YAAY,EACZC,QAAQ,EACRC,UAAU,EACVC,YAAY,EACZC,aAAa,EACbC,YAAY,EACZC,aAAa,EACb,GAAGC,YACJ,GAAGhB;IAEJ,MAAM,EAAEiB,UAAU,EAAEC,UAAU,EAAEC,iBAAiB,EAAE,GAAGC,IAAAA,mBAAY,EAAC;QACjE,GAAGpB,KAAK;QACR,qBAAqBS;IACvB;IAEA,MAAMY,SAASjB,SAAS;IAExB,MAAMkB,oBAAoBC,IAAAA,2BAAoB,EAAC;QAC7ClB;QACAC;IACF;IAEA,MAAMkB,mBAAmB;QACvB,iBAAiBtB;QACjB,iBAAiB,OAAOS,eAAe,aAAaA;QACpD,iBAAiB,OAAOA,eAAe,aAAa,CAACA;QACrD,eAAeU;QACf,CAACd,aAAa,GAAG,EAAE;IACrB;IAEA,MAAMkB,gBAAgBC,IAAAA,eAAU,EAACJ,mBAAmBE;IAEpD,MAAMG,eAAeD,IAAAA,eAAU,EAC7B;QACE,iBAAiBxB;IACnB,GACAoB;IAGF,MAAMM,mBAAmBF,IAAAA,eAAU,EACjC,UACA,qBACAD;IAGF,MAAMI,eAAeH,IAAAA,eAAU,EAC7B,UACA,4BACAD;IAGF,MAAMK,sBAAsBJ,IAAAA,eAAU,EACpC,oCACAD;IAGF,qBACE,sBAACM,YAAK;QAACC,KAAI;QAAKzB,WAAWqB;;YACxBpB,SAAS,CAACa,wBACT,qBAACY,YAAK;gBAAE,GAAGf,UAAU;gBAAEX,WAAWoB;0BAC/BnB;;0BAGL,sBAAC0B;gBAAI3B,WAAU;;oBACZ4B,IAAAA,8CAAsB,EACrBtB,eACAc,cACA;kCAEF,sBAACO;wBAAI3B,WAAWuB;;4BACbK,IAAAA,8CAAsB,EACrBvB,cACAe,cACA;0CAEF,qBAACS;gCACE,GAAGpB,UAAU;gCACb,GAAGC,UAAU;gCACdhB,KAAKA;gCACLG,MAAMA;gCACNG,WAAWsB;gCACXQ,UAAUlC;;4BAEXgC,IAAAA,8CAAsB,EACrBrB,cACAa,cACA;;;oBAGHQ,IAAAA,8CAAsB,EACrBpB,eACAY,cACA;;;YAGHjB,0BACC,qBAACwB;gBAAI3B,WAAU;0BAA+BG;;0BAGhD,qBAAC4B,0BAAY;gBAAE,GAAGnB,iBAAiB;gBAAEV,cAAcA;;;;AAGzD;AAEFX,UAAUyC,WAAW,GAAG"}
@@ -15,10 +15,10 @@ function _interop_require_default(obj) {
15
15
  default: obj
16
16
  };
17
17
  }
18
- const adornmentWithClassName = (component, className)=>{
18
+ const adornmentWithClassName = (component, validationClasses, className)=>{
19
19
  if (!component) return null;
20
20
  return (0, _react.cloneElement)(component, {
21
- className: (0, _classnames.default)(component.props.className, className)
21
+ className: (0, _classnames.default)(component.props.className, validationClasses, className)
22
22
  });
23
23
  };
24
24
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/TextField/adornmentWithClassName.ts"],"sourcesContent":["import classNames from \"classnames\";\nimport { ReactElement, cloneElement } from \"react\";\n\nexport const adornmentWithClassName = (\n component?: ReactElement,\n className?: string,\n) => {\n if (!component) return null;\n\n return cloneElement(component, {\n className: classNames(component.props.className, className),\n });\n};\n"],"names":["adornmentWithClassName","component","className","cloneElement","classNames","props"],"mappings":";;;;+BAGaA;;;eAAAA;;;mEAHU;uBACoB;;;;;;AAEpC,MAAMA,yBAAyB,CACpCC,WACAC;IAEA,IAAI,CAACD,WAAW,OAAO;IAEvB,OAAOE,IAAAA,mBAAY,EAACF,WAAW;QAC7BC,WAAWE,IAAAA,mBAAU,EAACH,UAAUI,KAAK,CAACH,SAAS,EAAEA;IACnD;AACF"}
1
+ {"version":3,"sources":["../../../../src/components/TextField/adornmentWithClassName.ts"],"sourcesContent":["import classNames from \"classnames\";\nimport { ReactElement, cloneElement } from \"react\";\n\nexport const adornmentWithClassName = (\n component?: ReactElement,\n validationClasses?: string,\n className?: string,\n) => {\n if (!component) return null;\n\n return cloneElement(component, {\n className: classNames(\n component.props.className,\n validationClasses,\n className,\n ),\n });\n};\n"],"names":["adornmentWithClassName","component","validationClasses","className","cloneElement","classNames","props"],"mappings":";;;;+BAGaA;;;eAAAA;;;mEAHU;uBACoB;;;;;;AAEpC,MAAMA,yBAAyB,CACpCC,WACAC,mBACAC;IAEA,IAAI,CAACF,WAAW,OAAO;IAEvB,OAAOG,IAAAA,mBAAY,EAACH,WAAW;QAC7BE,WAAWE,IAAAA,mBAAU,EACnBJ,UAAUK,KAAK,CAACH,SAAS,EACzBD,mBACAC;IAEJ;AACF"}