@simplybusiness/mobius 5.9.0 → 5.11.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 (75) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/components/AddressLookup/AddressLookup.js +66 -0
  3. package/dist/cjs/components/AddressLookup/AddressLookup.js.map +1 -0
  4. package/dist/cjs/components/AddressLookup/LoqateAddressLookupService.js +92 -0
  5. package/dist/cjs/components/AddressLookup/LoqateAddressLookupService.js.map +1 -0
  6. package/dist/cjs/components/AddressLookup/index.js +22 -0
  7. package/dist/cjs/components/AddressLookup/index.js.map +1 -0
  8. package/dist/cjs/components/AddressLookup/types.js +6 -0
  9. package/dist/cjs/components/AddressLookup/types.js.map +1 -0
  10. package/dist/cjs/components/Checkbox/CheckboxGroup.js +13 -21
  11. package/dist/cjs/components/Checkbox/CheckboxGroup.js.map +1 -1
  12. package/dist/cjs/components/Combobox/Combobox.js +10 -2
  13. package/dist/cjs/components/Combobox/Combobox.js.map +1 -1
  14. package/dist/cjs/components/Combobox/useComboboxOptions.js +5 -0
  15. package/dist/cjs/components/Combobox/useComboboxOptions.js.map +1 -1
  16. package/dist/cjs/components/index.js +1 -0
  17. package/dist/cjs/components/index.js.map +1 -1
  18. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  19. package/dist/cjs/utils/delay.js +23 -0
  20. package/dist/cjs/utils/delay.js.map +1 -0
  21. package/dist/cjs/utils/index.js +1 -0
  22. package/dist/cjs/utils/index.js.map +1 -1
  23. package/dist/esm/components/AddressLookup/AddressLookup.js +56 -0
  24. package/dist/esm/components/AddressLookup/AddressLookup.js.map +1 -0
  25. package/dist/esm/components/AddressLookup/LoqateAddressLookupService.js +82 -0
  26. package/dist/esm/components/AddressLookup/LoqateAddressLookupService.js.map +1 -0
  27. package/dist/esm/components/AddressLookup/index.js +5 -0
  28. package/dist/esm/components/AddressLookup/index.js.map +1 -0
  29. package/dist/esm/components/AddressLookup/types.js +3 -0
  30. package/dist/esm/components/AddressLookup/types.js.map +1 -0
  31. package/dist/esm/components/Checkbox/CheckboxGroup.js +15 -23
  32. package/dist/esm/components/Checkbox/CheckboxGroup.js.map +1 -1
  33. package/dist/esm/components/Combobox/Combobox.js +10 -2
  34. package/dist/esm/components/Combobox/Combobox.js.map +1 -1
  35. package/dist/esm/components/Combobox/useComboboxOptions.js +5 -0
  36. package/dist/esm/components/Combobox/useComboboxOptions.js.map +1 -1
  37. package/dist/esm/components/index.js +1 -0
  38. package/dist/esm/components/index.js.map +1 -1
  39. package/dist/esm/utils/delay.js +13 -0
  40. package/dist/esm/utils/delay.js.map +1 -0
  41. package/dist/esm/utils/index.js +1 -0
  42. package/dist/esm/utils/index.js.map +1 -1
  43. package/dist/types/components/AddressLookup/AddressLookup.d.ts +2 -0
  44. package/dist/types/components/AddressLookup/AddressLookup.stories.d.ts +6 -0
  45. package/dist/types/components/AddressLookup/AddressLookup.test.d.ts +1 -0
  46. package/dist/types/components/AddressLookup/LoqateAddressLookupService.d.ts +11 -0
  47. package/dist/types/components/AddressLookup/LoqateAddressLookupService.test.d.ts +1 -0
  48. package/dist/types/components/AddressLookup/__mocks__/LoqateAddressLookupService.d.ts +335 -0
  49. package/dist/types/components/AddressLookup/index.d.ts +3 -0
  50. package/dist/types/components/AddressLookup/types.d.ts +19 -0
  51. package/dist/types/components/Combobox/useComboboxOptions.d.ts +1 -0
  52. package/dist/types/components/index.d.ts +1 -0
  53. package/dist/types/utils/delay.d.ts +3 -0
  54. package/dist/types/utils/delay.test.d.ts +1 -0
  55. package/dist/types/utils/index.d.ts +1 -0
  56. package/package.json +1 -1
  57. package/src/components/AddressLookup/AddressLookup.stories.tsx +63 -0
  58. package/src/components/AddressLookup/AddressLookup.test.tsx +77 -0
  59. package/src/components/AddressLookup/AddressLookup.tsx +84 -0
  60. package/src/components/AddressLookup/LoqateAddressLookupService.test.tsx +99 -0
  61. package/src/components/AddressLookup/LoqateAddressLookupService.tsx +44 -0
  62. package/src/components/AddressLookup/__mocks__/LoqateAddressLookupService.tsx +405 -0
  63. package/src/components/AddressLookup/index.tsx +3 -0
  64. package/src/components/AddressLookup/types.tsx +26 -0
  65. package/src/components/Checkbox/CheckboxGroup.tsx +10 -17
  66. package/src/components/Combobox/Combobox.css +7 -0
  67. package/src/components/Combobox/Combobox.stories.tsx +2 -7
  68. package/src/components/Combobox/Combobox.test.tsx +7 -0
  69. package/src/components/Combobox/Combobox.tsx +24 -8
  70. package/src/components/Combobox/useComboboxOptions.test.ts +9 -1
  71. package/src/components/Combobox/useComboboxOptions.ts +15 -1
  72. package/src/components/index.tsx +1 -0
  73. package/src/utils/delay.test.ts +36 -0
  74. package/src/utils/delay.ts +11 -0
  75. package/src/utils/index.ts +1 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 03ed793: Add `AddressLookup` component
8
+
9
+ ### Patch Changes
10
+
11
+ - 58ed811: Add AddressLookup to questionnaire
12
+
13
+ ## 5.10.0
14
+
15
+ ### Minor Changes
16
+
17
+ - a9ceb42: Add Answers state in Questionnaire
18
+
19
+ ### Patch Changes
20
+
21
+ - cc5b228: Add id prop to Combobox
22
+
3
23
  ## 5.9.0
4
24
 
5
25
  ### Minor Changes
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "AddressLookup", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return AddressLookup;
9
+ }
10
+ });
11
+ const _jsxruntime = require("react/jsx-runtime");
12
+ const _icons = require("@simplybusiness/icons");
13
+ const _react = require("react");
14
+ const _Combobox = require("../Combobox");
15
+ const _Icon = require("../Icon");
16
+ function optionsFromResponse({ Items }, addressLookupService) {
17
+ if (!Items || !Array.isArray(Items)) {
18
+ throw Error("No address found");
19
+ }
20
+ if (Items[0].Error) {
21
+ throw Error(Items[0].Description);
22
+ }
23
+ return Items.map((item)=>({
24
+ id: item.Id,
25
+ label: `${item.Text}, ${item.Description}`,
26
+ value: item.Text,
27
+ // Add a callback to trigger secondary search
28
+ // if the address type is not "Address"
29
+ callback: item.Type === "Address" ? undefined : async ()=>{
30
+ const result = await addressLookupService.findById(item.Id);
31
+ return optionsFromResponse(result, addressLookupService);
32
+ }
33
+ }));
34
+ }
35
+ function AddressLookup({ addressLookupService, onAddressSelected, errorMessage, ...otherProps }) {
36
+ const [error, setError] = (0, _react.useState)(null);
37
+ const asyncOptions = (0, _react.useCallback)(async (searchTerm)=>{
38
+ try {
39
+ const response = await addressLookupService.search(searchTerm);
40
+ return optionsFromResponse(response, addressLookupService);
41
+ } catch (e) {
42
+ setError(e);
43
+ return [];
44
+ }
45
+ }, [
46
+ addressLookupService,
47
+ setError
48
+ ]);
49
+ const handleSelected = (selected)=>{
50
+ setError(null);
51
+ return addressLookupService// @ts-expect-error - Fix types
52
+ .get(selected.id).then(onAddressSelected).catch(setError);
53
+ };
54
+ const realErrorMessage = error && "An error occurred" || errorMessage;
55
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_Combobox.Combobox, {
56
+ ...otherProps,
57
+ onSelected: handleSelected,
58
+ asyncOptions: asyncOptions,
59
+ errorMessage: realErrorMessage,
60
+ icon: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Icon.Icon, {
61
+ icon: _icons.search
62
+ })
63
+ });
64
+ }
65
+
66
+ //# sourceMappingURL=AddressLookup.js.map
@@ -0,0 +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"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "LoqateAddressLookupService", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return LoqateAddressLookupService;
9
+ }
10
+ });
11
+ function _check_private_redeclaration(obj, privateCollection) {
12
+ if (privateCollection.has(obj)) {
13
+ throw new TypeError("Cannot initialize the same private elements twice on an object");
14
+ }
15
+ }
16
+ function _class_apply_descriptor_get(receiver, descriptor) {
17
+ if (descriptor.get) {
18
+ return descriptor.get.call(receiver);
19
+ }
20
+ return descriptor.value;
21
+ }
22
+ function _class_apply_descriptor_set(receiver, descriptor, value) {
23
+ if (descriptor.set) {
24
+ descriptor.set.call(receiver, value);
25
+ } else {
26
+ if (!descriptor.writable) {
27
+ throw new TypeError("attempted to set read only private field");
28
+ }
29
+ descriptor.value = value;
30
+ }
31
+ }
32
+ function _class_extract_field_descriptor(receiver, privateMap, action) {
33
+ if (!privateMap.has(receiver)) {
34
+ throw new TypeError("attempted to " + action + " private field on non-instance");
35
+ }
36
+ return privateMap.get(receiver);
37
+ }
38
+ function _class_private_field_get(receiver, privateMap) {
39
+ var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
40
+ return _class_apply_descriptor_get(receiver, descriptor);
41
+ }
42
+ function _class_private_field_init(obj, privateMap, value) {
43
+ _check_private_redeclaration(obj, privateMap);
44
+ privateMap.set(obj, value);
45
+ }
46
+ function _class_private_field_set(receiver, privateMap, value) {
47
+ var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
48
+ _class_apply_descriptor_set(receiver, descriptor, value);
49
+ return value;
50
+ }
51
+ const LOQATE_BASE_URL = "https://api.addressy.com/Capture/Interactive";
52
+ const LOQATE_FIND_URL = "/Find/v1.00/json3.ws";
53
+ const LOQATE_RETRIEVE_URL = "/Retrieve/v1.2/json3.ws";
54
+ var /**
55
+ * Base URL for the Loqate API
56
+ */ _baseUrl = /*#__PURE__*/ new WeakMap(), /**
57
+ * API key for the Loqate API
58
+ */ _apiKey = /*#__PURE__*/ new WeakMap();
59
+ class LoqateAddressLookupService {
60
+ fetchFromApi(url) {
61
+ return fetch(`${_class_private_field_get(this, _baseUrl)}${url}`).then((response)=>response.json());
62
+ }
63
+ // TODO: Fix type
64
+ search(searchTerm) {
65
+ const url = `${LOQATE_FIND_URL}?Key=${_class_private_field_get(this, _apiKey)}&Text=${searchTerm}`;
66
+ return this.fetchFromApi(url);
67
+ }
68
+ // TODO: Fix type
69
+ findById(id) {
70
+ const url = `${LOQATE_FIND_URL}?Key=${_class_private_field_get(this, _apiKey)}&Container=${id}`;
71
+ return this.fetchFromApi(url);
72
+ }
73
+ // TODO: Fix type
74
+ get(id) {
75
+ const url = `${LOQATE_RETRIEVE_URL}?Key=${_class_private_field_get(this, _apiKey)}&Id=${id}`;
76
+ return this.fetchFromApi(url);
77
+ }
78
+ constructor({ baseUrl, apiKey }){
79
+ _class_private_field_init(this, _baseUrl, {
80
+ writable: true,
81
+ value: void 0
82
+ });
83
+ _class_private_field_init(this, _apiKey, {
84
+ writable: true,
85
+ value: void 0
86
+ });
87
+ _class_private_field_set(this, _apiKey, apiKey);
88
+ _class_private_field_set(this, _baseUrl, baseUrl || LOQATE_BASE_URL);
89
+ }
90
+ }
91
+
92
+ //# sourceMappingURL=LoqateAddressLookupService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/AddressLookup/LoqateAddressLookupService.tsx"],"sourcesContent":["const LOQATE_BASE_URL = \"https://api.addressy.com/Capture/Interactive\";\nconst LOQATE_FIND_URL = \"/Find/v1.00/json3.ws\";\nconst LOQATE_RETRIEVE_URL = \"/Retrieve/v1.2/json3.ws\";\n\nexport class LoqateAddressLookupService {\n /**\n * Base URL for the Loqate API\n */\n #baseUrl: string;\n\n /**\n * API key for the Loqate API\n */\n #apiKey?: string;\n\n constructor({ baseUrl, apiKey }: { baseUrl?: string; apiKey?: string }) {\n this.#apiKey = apiKey;\n this.#baseUrl = baseUrl || LOQATE_BASE_URL;\n }\n\n private fetchFromApi<TResponse = unknown>(url: string): Promise<unknown> {\n return fetch(`${this.#baseUrl}${url}`).then(response =>\n response.json(),\n ) as Promise<TResponse>;\n }\n\n // TODO: Fix type\n search(searchTerm: string): Promise<any> {\n const url = `${LOQATE_FIND_URL}?Key=${this.#apiKey}&Text=${searchTerm}`;\n return this.fetchFromApi(url);\n }\n\n // TODO: Fix type\n findById(id: string): Promise<any> {\n const url = `${LOQATE_FIND_URL}?Key=${this.#apiKey}&Container=${id}`;\n return this.fetchFromApi(url);\n }\n\n // TODO: Fix type\n get(id: string): Promise<any> {\n const url = `${LOQATE_RETRIEVE_URL}?Key=${this.#apiKey}&Id=${id}`;\n return this.fetchFromApi(url);\n }\n}\n"],"names":["LoqateAddressLookupService","LOQATE_BASE_URL","LOQATE_FIND_URL","LOQATE_RETRIEVE_URL","fetchFromApi","url","fetch","then","response","json","search","searchTerm","findById","id","get","constructor","baseUrl","apiKey"],"mappings":";;;;+BAIaA;;;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAJb,MAAMC,kBAAkB;AACxB,MAAMC,kBAAkB;AACxB,MAAMC,sBAAsB;IAG1B;;GAEC,GACD,wCAEA;;GAEC,GACD;AATK,MAAMH;IAgBHI,aAAkCC,GAAW,EAAoB;QACvE,OAAOC,MAAM,4BAAG,IAAI,EAAC,YAAWD,KAAK,EAAEE,IAAI,CAACC,CAAAA,WAC1CA,SAASC,IAAI;IAEjB;IAEA,iBAAiB;IACjBC,OAAOC,UAAkB,EAAgB;QACvC,MAAMN,MAAM,GAAGH,gBAAgB,KAAK,2BAAE,IAAI,EAAC,SAAQ,MAAM,EAAES,YAAY;QACvE,OAAO,IAAI,CAACP,YAAY,CAACC;IAC3B;IAEA,iBAAiB;IACjBO,SAASC,EAAU,EAAgB;QACjC,MAAMR,MAAM,GAAGH,gBAAgB,KAAK,2BAAE,IAAI,EAAC,SAAQ,WAAW,EAAEW,IAAI;QACpE,OAAO,IAAI,CAACT,YAAY,CAACC;IAC3B;IAEA,iBAAiB;IACjBS,IAAID,EAAU,EAAgB;QAC5B,MAAMR,MAAM,GAAGF,oBAAoB,KAAK,2BAAE,IAAI,EAAC,SAAQ,IAAI,EAAEU,IAAI;QACjE,OAAO,IAAI,CAACT,YAAY,CAACC;IAC3B;IA3BAU,YAAY,EAAEC,OAAO,EAAEC,MAAM,EAAyC,CAAE;QAPxE,gCAAA;;mBAAA,KAAA;;QAKA,gCAAA;;mBAAA,KAAA;;uCAGO,SAAUA;uCACV,UAAWD,WAAWf;IAC7B;AAyBF"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ _export_star(require("./AddressLookup"), exports);
6
+ _export_star(require("./LoqateAddressLookupService"), exports);
7
+ _export_star(require("./types"), exports);
8
+ function _export_star(from, to) {
9
+ Object.keys(from).forEach(function(k) {
10
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
11
+ Object.defineProperty(to, k, {
12
+ enumerable: true,
13
+ get: function() {
14
+ return from[k];
15
+ }
16
+ });
17
+ }
18
+ });
19
+ return from;
20
+ }
21
+
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/AddressLookup/index.tsx"],"sourcesContent":["export * from \"./AddressLookup\";\nexport * from \"./LoqateAddressLookupService\";\nexport * from \"./types\";\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/AddressLookup/types.tsx"],"names":[],"mappings":""}
@@ -47,34 +47,26 @@ const CheckboxGroup = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
47
47
  const labelId = (0, _react.useId)();
48
48
  const handleChange = (event, isLastItem = false)=>{
49
49
  const { target: { value, checked } } = event;
50
+ let newValue = [
51
+ ...selected
52
+ ];
50
53
  if (!checked) {
51
- setSelected(selected.filter((item)=>item !== value));
52
- }
53
- if (checked && lastItemDisables && isLastItem) {
54
- setSelected([
55
- value
56
- ]);
57
- return;
54
+ newValue = selected.filter((item)=>item !== value);
58
55
  }
59
56
  if (checked) {
60
- setSelected([
57
+ newValue = [
61
58
  ...selected,
62
59
  value
63
- ]);
60
+ ];
64
61
  }
65
- };
66
- // HACK: This is a workaround to ensure that the onChange event is not
67
- // fired on the initial render.
68
- const renderCount = (0, _hooks.useRenderCount)();
69
- (0, _react.useEffect)(()=>{
70
- if (onChange && renderCount > 1) {
71
- onChange(selected);
62
+ if (checked && lastItemDisables && isLastItem) {
63
+ newValue = [
64
+ value
65
+ ];
72
66
  }
73
- }, [
74
- selected,
75
- onChange,
76
- renderCount
77
- ]);
67
+ setSelected(newValue);
68
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
69
+ };
78
70
  const childrenArray = _react.Children.toArray(children);
79
71
  const lastCheckbox = childrenArray.filter((child)=>/*#__PURE__*/ (0, _react.isValidElement)(child) && child.type === _Checkbox.Checkbox).pop();
80
72
  const lastCheckboxIsChecked = lastCheckbox && selected.includes(lastCheckbox.props.value);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/Checkbox/CheckboxGroup.tsx"],"sourcesContent":["\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport {\n type ChangeEvent,\n type ReactElement,\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n useEffect,\n useId,\n useState,\n} from \"react\";\nimport { useRenderCount, useValidationClasses } from \"../../hooks\";\nimport { ForwardedRefComponent } from \"../../types/components\";\nimport { spaceDelimitedList } from \"../../utils/spaceDelimitedList\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport { Checkbox } from \"./Checkbox\";\nimport {\n CheckboxElementType,\n CheckboxGroupElementType,\n CheckboxGroupProps,\n CheckboxGroupRef,\n} from \"./types\";\n\nexport const CheckboxGroup: ForwardedRefComponent<\n CheckboxGroupProps,\n CheckboxGroupElementType\n> = forwardRef((props: CheckboxGroupProps, ref: CheckboxGroupRef) => {\n const {\n label,\n isDisabled = false,\n isRequired,\n validationState,\n isInvalid,\n orientation = \"vertical\",\n onChange,\n className,\n errorMessage,\n children,\n defaultValue = [],\n isReadOnly,\n itemsPerRow,\n lastItemDisables = false,\n ...rest\n } = props;\n const [selected, setSelected] = useState<string[]>(defaultValue);\n const checkboxGroupClasses = classNames(\n \"mobius\",\n \"mobius-checkbox-group\",\n className,\n {\n \"--is-horizontal\": orientation === \"horizontal\",\n \"--is-vertical\": orientation === \"vertical\",\n \"--is-required\": typeof isRequired === \"boolean\" && isRequired,\n \"--is-optional\": typeof isRequired === \"boolean\" && !isRequired,\n },\n );\n const validationClasses = useValidationClasses({\n validationState,\n isInvalid,\n });\n const labelClasses = classNames(\n {\n \"--is-disabled\": isDisabled,\n },\n validationClasses,\n );\n const errorMessageId = useId();\n const shouldErrorMessageShow = errorMessage ? errorMessageId : undefined;\n const describedBy = spaceDelimitedList([\n shouldErrorMessageShow,\n props[\"aria-describedby\"],\n ]);\n const labelId = useId();\n\n const handleChange = (\n event: ChangeEvent<CheckboxElementType>,\n isLastItem = false,\n ) => {\n const {\n target: { value, checked },\n } = event;\n\n if (!checked) {\n setSelected(selected.filter(item => item !== value));\n }\n\n if (checked && lastItemDisables && isLastItem) {\n setSelected([value]);\n return;\n }\n\n if (checked) {\n setSelected([...selected, value]);\n }\n };\n\n // HACK: This is a workaround to ensure that the onChange event is not\n // fired on the initial render.\n const renderCount = useRenderCount();\n useEffect(() => {\n if (onChange && renderCount > 1) {\n onChange(selected);\n }\n }, [selected, onChange, renderCount]);\n\n const childrenArray = Children.toArray(children);\n const lastCheckbox = childrenArray\n .filter(\n child =>\n isValidElement(child) && (child as ReactElement).type === Checkbox,\n )\n .pop() as ReactElement<CheckboxElementType> | undefined;\n const lastCheckboxIsChecked =\n lastCheckbox && selected.includes(lastCheckbox.props.value);\n\n return (\n <div\n {...rest}\n aria-labelledby={props[\"aria-labelledby\"] || labelId}\n ref={ref}\n className={checkboxGroupClasses}\n role=\"group\"\n style={\n {\n \"--checkbox-items-per-row\": itemsPerRow || Children.count(children),\n } as React.CSSProperties\n }\n >\n {label && (\n <Label elementType=\"span\" id={labelId} className={labelClasses}>\n {label}\n </Label>\n )}\n <div className=\"mobius-checkbox-group__wrapper\">\n {childrenArray.map(child => {\n if (isValidElement(child)) {\n // lastItemDisables support\n const isLastItem = child === lastCheckbox;\n const isChildDisabled =\n isDisabled ||\n (lastItemDisables && lastCheckboxIsChecked && !isLastItem);\n\n return cloneElement(child as ReactElement, {\n isDisabled: isChildDisabled,\n isRequired,\n isReadOnly,\n isInvalid,\n isLastItem,\n selected: selected.includes(child.props.value),\n onChange: handleChange,\n \"aria-describedby\": describedBy,\n });\n }\n\n return child;\n })}\n </div>\n {errorMessage && (\n <ErrorMessage id={errorMessageId} errorMessage={errorMessage} />\n )}\n </div>\n );\n});\n"],"names":["CheckboxGroup","forwardRef","props","ref","label","isDisabled","isRequired","validationState","isInvalid","orientation","onChange","className","errorMessage","children","defaultValue","isReadOnly","itemsPerRow","lastItemDisables","rest","selected","setSelected","useState","checkboxGroupClasses","classNames","validationClasses","useValidationClasses","labelClasses","errorMessageId","useId","shouldErrorMessageShow","undefined","describedBy","spaceDelimitedList","labelId","handleChange","event","isLastItem","target","value","checked","filter","item","renderCount","useRenderCount","useEffect","childrenArray","Children","toArray","lastCheckbox","child","isValidElement","type","Checkbox","pop","lastCheckboxIsChecked","includes","div","aria-labelledby","role","style","count","Label","elementType","id","map","isChildDisabled","cloneElement","ErrorMessage"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/components/Checkbox/CheckboxGroup.tsx"],"sourcesContent":["\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport {\n type ChangeEvent,\n type ReactElement,\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n useId,\n useState,\n} from \"react\";\nimport { useValidationClasses } from \"../../hooks\";\nimport { ForwardedRefComponent } from \"../../types/components\";\nimport { spaceDelimitedList } from \"../../utils/spaceDelimitedList\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport { Checkbox } from \"./Checkbox\";\nimport {\n CheckboxElementType,\n CheckboxGroupElementType,\n CheckboxGroupProps,\n CheckboxGroupRef,\n} from \"./types\";\n\nexport const CheckboxGroup: ForwardedRefComponent<\n CheckboxGroupProps,\n CheckboxGroupElementType\n> = forwardRef((props: CheckboxGroupProps, ref: CheckboxGroupRef) => {\n const {\n label,\n isDisabled = false,\n isRequired,\n validationState,\n isInvalid,\n orientation = \"vertical\",\n onChange,\n className,\n errorMessage,\n children,\n defaultValue = [],\n isReadOnly,\n itemsPerRow,\n lastItemDisables = false,\n ...rest\n } = props;\n const [selected, setSelected] = useState<string[]>(defaultValue);\n const checkboxGroupClasses = classNames(\n \"mobius\",\n \"mobius-checkbox-group\",\n className,\n {\n \"--is-horizontal\": orientation === \"horizontal\",\n \"--is-vertical\": orientation === \"vertical\",\n \"--is-required\": typeof isRequired === \"boolean\" && isRequired,\n \"--is-optional\": typeof isRequired === \"boolean\" && !isRequired,\n },\n );\n const validationClasses = useValidationClasses({\n validationState,\n isInvalid,\n });\n const labelClasses = classNames(\n {\n \"--is-disabled\": isDisabled,\n },\n validationClasses,\n );\n const errorMessageId = useId();\n const shouldErrorMessageShow = errorMessage ? errorMessageId : undefined;\n const describedBy = spaceDelimitedList([\n shouldErrorMessageShow,\n props[\"aria-describedby\"],\n ]);\n const labelId = useId();\n\n const handleChange = (\n event: ChangeEvent<CheckboxElementType>,\n isLastItem = false,\n ) => {\n const {\n target: { value, checked },\n } = event;\n let newValue = [...selected];\n\n if (!checked) {\n newValue = selected.filter(item => item !== value);\n }\n\n if (checked) {\n newValue = [...selected, value];\n }\n\n if (checked && lastItemDisables && isLastItem) {\n newValue = [value];\n }\n\n setSelected(newValue);\n onChange?.(newValue);\n };\n\n const childrenArray = Children.toArray(children);\n const lastCheckbox = childrenArray\n .filter(\n child =>\n isValidElement(child) && (child as ReactElement).type === Checkbox,\n )\n .pop() as ReactElement<CheckboxElementType> | undefined;\n const lastCheckboxIsChecked =\n lastCheckbox && selected.includes(lastCheckbox.props.value);\n\n return (\n <div\n {...rest}\n aria-labelledby={props[\"aria-labelledby\"] || labelId}\n ref={ref}\n className={checkboxGroupClasses}\n role=\"group\"\n style={\n {\n \"--checkbox-items-per-row\": itemsPerRow || Children.count(children),\n } as React.CSSProperties\n }\n >\n {label && (\n <Label elementType=\"span\" id={labelId} className={labelClasses}>\n {label}\n </Label>\n )}\n <div className=\"mobius-checkbox-group__wrapper\">\n {childrenArray.map(child => {\n if (isValidElement(child)) {\n // lastItemDisables support\n const isLastItem = child === lastCheckbox;\n const isChildDisabled =\n isDisabled ||\n (lastItemDisables && lastCheckboxIsChecked && !isLastItem);\n\n return cloneElement(child as ReactElement, {\n isDisabled: isChildDisabled,\n isRequired,\n isReadOnly,\n isInvalid,\n isLastItem,\n selected: selected.includes(child.props.value),\n onChange: handleChange,\n \"aria-describedby\": describedBy,\n });\n }\n\n return child;\n })}\n </div>\n {errorMessage && (\n <ErrorMessage id={errorMessageId} errorMessage={errorMessage} />\n )}\n </div>\n );\n});\n"],"names":["CheckboxGroup","forwardRef","props","ref","label","isDisabled","isRequired","validationState","isInvalid","orientation","onChange","className","errorMessage","children","defaultValue","isReadOnly","itemsPerRow","lastItemDisables","rest","selected","setSelected","useState","checkboxGroupClasses","classNames","validationClasses","useValidationClasses","labelClasses","errorMessageId","useId","shouldErrorMessageShow","undefined","describedBy","spaceDelimitedList","labelId","handleChange","event","isLastItem","target","value","checked","newValue","filter","item","childrenArray","Children","toArray","lastCheckbox","child","isValidElement","type","Checkbox","pop","lastCheckboxIsChecked","includes","div","aria-labelledby","role","style","count","Label","elementType","id","map","isChildDisabled","cloneElement","ErrorMessage"],"mappings":"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"}
@@ -24,11 +24,11 @@ function _interop_require_default(obj) {
24
24
  };
25
25
  }
26
26
  const Combobox = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
27
- const { defaultValue, options, asyncOptions, delay, minLength, onSelected, className, placeholder, icon, ...otherProps } = props;
27
+ const { id, defaultValue, options, asyncOptions, delay, minLength, onSelected, className, placeholder, icon, ...otherProps } = props;
28
28
  const fallbackRef = (0, _react.useRef)(null);
29
29
  const [inputValue, setInputValue] = (0, _react.useState)(defaultValue || "");
30
30
  const [isOpen, setIsOpen] = (0, _react.useState)(false);
31
- const { filteredOptions, isLoading } = (0, _useComboboxOptions.useComboboxOptions)({
31
+ const { filteredOptions, updateFilteredOptions, isLoading } = (0, _useComboboxOptions.useComboboxOptions)({
32
32
  options,
33
33
  asyncOptions,
34
34
  inputValue,
@@ -68,6 +68,13 @@ const Combobox = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
68
68
  const handleOptionSelect = (option)=>{
69
69
  const value = (0, _utils.getOptionValue)(option);
70
70
  if (!value) return;
71
+ // TODO: Declare this in the types
72
+ if (typeof option === "object" && "callback" in option && option.callback && typeof option.callback === "function") {
73
+ // @ts-expect-error ref types are hard
74
+ setTimeout(()=>inputRef.current.focus(), 0);
75
+ updateFilteredOptions(option.callback());
76
+ return;
77
+ }
71
78
  setIsOpen(false);
72
79
  setInputValue(value);
73
80
  onSelected === null || onSelected === void 0 ? void 0 : onSelected(option);
@@ -121,6 +128,7 @@ const Combobox = /*#__PURE__*/ (0, _react.forwardRef)((props, ref)=>{
121
128
  "mobius-combobox--is-loading": isLoading
122
129
  }, className);
123
130
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
131
+ id: id,
124
132
  "data-testid": "mobius-combobox__wrapper",
125
133
  className: classes,
126
134
  children: [
@@ -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 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, isLoading } = 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 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 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","defaultValue","options","asyncOptions","delay","minLength","onSelected","className","placeholder","icon","otherProps","fallbackRef","useRef","inputValue","setInputValue","useState","isOpen","setIsOpen","filteredOptions","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","getHighlightedOption","undefined","isOptionGroup","group","handleKeyDown","key","preventDefault","classes","classNames","div","data-testid","VisuallyHidden","role","aria-live","id","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 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":";;;;+BAiBaA;;;eAAAA;;;;+DAjBU;uBAC6B;uBACvB;2BAEH;gCACK;yBACP;sCAOa;oCACF;uBACW;;;;;;AAEvC,MAAMA,yBAGTC,IAAAA,iBAAU,EAAC,CAACC,OAAsBC;IACpC,MAAM,EACJC,EAAE,EACFC,YAAY,EACZC,OAAO,EACPC,YAAY,EACZC,KAAK,EACLC,SAAS,EACTC,UAAU,EACVC,SAAS,EACTC,WAAW,EACXC,IAAI,EACJ,GAAGC,YACJ,GAAGZ;IAEJ,MAAMa,cAAcC,IAAAA,aAAM,EAAmB;IAC7C,MAAM,CAACC,YAAYC,cAAc,GAAGC,IAAAA,eAAQ,EAACd,gBAAgB;IAC7D,MAAM,CAACe,QAAQC,UAAU,GAAGF,IAAAA,eAAQ,EAAC;IACrC,MAAM,EAAEG,eAAe,EAAEC,qBAAqB,EAAEC,SAAS,EAAE,GACzDC,IAAAA,sCAAkB,EAAC;QACjBnB;QACAC;QACAU;QACAT;QACAC;IACF;IACF,MAAM,EACJiB,gBAAgB,EAChBC,qBAAqB,EACrBC,mBAAmB,EACnBC,uBAAuB,EACvBC,oBAAoB,EACpBC,mBAAmB,EACnBC,cAAc,EACf,GAAGC,IAAAA,0CAAoB,EAACX;IAEzB,MAAMY,WAAW/B,OAAOY;IACxB,MAAMoB,YAAYC,IAAAA,YAAK;IACvB,MAAMC,WAAWD,IAAAA,YAAK;IACtB,MAAME,iBAAiBtB,IAAAA,aAAM,EAAwB;IACrD,MAAMuB,cAAcnB,UAAUE,gBAAgBkB,MAAM,GAAG;IAEvD,MAAMC,cAAc;QAClB,IAAInB,gBAAgBkB,MAAM,KAAK,GAAG;QAClC,IAAIF,eAAeI,OAAO,EAAE;YAC1BC,aAAaL,eAAeI,OAAO;YACnCJ,eAAeI,OAAO,GAAG;QAC3B;QACArB,UAAU;IACZ;IAEA,MAAMuB,aAAa;QACjBN,eAAeI,OAAO,GAAGG,WAAW;YAClCxB,UAAU;QACZ,GAAG;IACL;IAEAyB,IAAAA,mBAAY,EAAC;QACX,IAAIR,eAAeI,OAAO,EAAE;YAC1BC,aAAaL,eAAeI,OAAO;QACrC;IACF;IAEA,MAAMK,oBAAoB,CAACC;QACzB,MAAMC,WAAWD,EAAEE,MAAM,CAACC,KAAK;QAC/BjC,cAAc+B;QACd5B,UAAU;QACVW;IACF;IAEA,MAAMoB,qBAAqB,CAACC;QAC1B,MAAMF,QAAQG,IAAAA,qBAAc,EAACD;QAC7B,IAAI,CAACF,OAAO;QAEZ,kCAAkC;QAClC,IACE,OAAOE,WAAW,YAClB,cAAcA,UACdA,OAAOE,QAAQ,IACf,OAAOF,OAAOE,QAAQ,KAAK,YAC3B;YACA,sCAAsC;YACtCV,WAAW,IAAMX,SAASQ,OAAO,CAACc,KAAK,IAAI;YAC3CjC,sBAAsB8B,OAAOE,QAAQ;YACrC;QACF;QAEAlC,UAAU;QACVH,cAAciC;QACdzC,uBAAAA,iCAAAA,WAAa2C;IACf;IAEA,SAASI;QACP,IAAI/B,qBAAqB,CAAC,GAAG,OAAOgC;QAEpC,IAAIC,IAAAA,oBAAa,EAACrC,kBAAkB;YAClC,MAAMsC,QAAQtC,eAAe,CAACK,sBAAsB;YACpD,OAAOiC,kBAAAA,4BAAAA,MAAOtD,OAAO,CAACoB,iBAAiB;QACzC;QAEA,OAAOJ,eAAe,CAACI,iBAAiB;IAC1C;IAEA,MAAMmC,gBAAgB,CAACb;QACrB,OAAQA,EAAEc,GAAG;YACX,KAAK;gBACHd,EAAEe,cAAc;gBAChB1C,UAAU;gBACVO;gBACA;YACF,KAAK;gBACHoB,EAAEe,cAAc;gBAChB1C,UAAU;gBACVQ;gBACA;YACF,KAAK;gBACHmB,EAAEe,cAAc;gBAChB1C,UAAU;gBACVS;gBACA;YACF,KAAK;gBACHkB,EAAEe,cAAc;gBAChB1C,UAAU;gBACVU;gBACA;YACF,KAAK;gBACHiB,EAAEe,cAAc;gBAChB,IAAI3C,QAAQ;oBACVgC,mBAAmBK;gBACrB;gBACA;YACF,KAAK;gBACHT,EAAEe,cAAc;gBAChB1C,UAAU;gBACVW;gBACA;YACF;QAEF;IACF;IAEA,MAAMgC,UAAUC,IAAAA,eAAU,EACxB,0BACA;QACE,gCAAgC7C;QAChC,+BAA+BI;IACjC,GACAb;IAGF,qBACE,sBAACuD;QAAI9D,IAAIA;QAAI+D,eAAY;QAA2BxD,WAAWqD;;YAC5DxC,2BACC,qBAAC4C,8BAAc;gBACbC,MAAK;gBACLC,aAAU;gBACVlE,IAAIiC;gBACJkC,aAAY;gBACZ5D,WAAU;0BACX;;0BAIH,qBAAC6D,oBAAS;gBACP,GAAG1D,UAAU;gBACdH,WAAU;gBACV0D,MAAK;gBACLlB,OAAOlC;gBACPL,aAAaA;gBACb6D,SAAShC;gBACTiC,QAAQ9B;gBACR+B,WAAWd;gBACXe,UAAU7B;gBACV8B,cAAa;gBACbC,oBAAkBtD,YAAYa,WAAWqB;gBACzCqB,qBAAkB;gBAClBC,iBAAc;gBACdC,iBAAe9C;gBACf+C,iBAAe9D;gBACf+D,yBACEzD,qBAAqB,CAAC,IAClBgC,YACA,GAAGvB,UAAU,QAAQ,EAAER,sBAAsB,CAAC,EAAED,kBAAkB;gBAExE0D,cAAcvE;gBACdV,KAAK+B;;YAENK,6BACC,qBAAC8C,gBAAO;gBACNjF,IAAI+B;gBACJ7B,SAASgB;gBACTI,kBAAkBA;gBAClBC,uBAAuBA;gBACvB2D,gBAAgBlC;;;;AAK1B"}
@@ -58,8 +58,13 @@ function useComboboxOptions({ options, asyncOptions, delay = 300, minLength = 3,
58
58
  delay,
59
59
  minLength
60
60
  ]);
61
+ function updateFilteredOptions(newOptions) {
62
+ setIsLoading(true);
63
+ return newOptions.then(setFilteredOptions).catch(setError).finally(()=>setIsLoading(false));
64
+ }
61
65
  return {
62
66
  filteredOptions,
67
+ updateFilteredOptions,
63
68
  isLoading,
64
69
  error,
65
70
  isError: error != null
@@ -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 return { filteredOptions, isLoading, error, isError: error != null };\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","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,OAAO;QAAEE;QAAiBK;QAAWE;QAAOc,SAASd,SAAS;IAAK;AACrE"}
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"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
5
  _export_star(require("./Accordion"), exports);
6
+ _export_star(require("./AddressLookup"), exports);
6
7
  _export_star(require("./Alert"), exports);
7
8
  _export_star(require("./Box"), exports);
8
9
  _export_star(require("./Breadcrumbs"), exports);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/index.tsx"],"sourcesContent":["export * from \"./Accordion\";\nexport * from \"./Alert\";\nexport * from \"./Box\";\nexport * from \"./Breadcrumbs\";\nexport * from \"./Button\";\nexport * from \"./Checkbox\";\nexport * from \"./Combobox\";\nexport * from \"./Container\";\nexport * from \"./Divider\";\nexport * from \"./Drawer\";\nexport * from \"./DropdownMenu\";\nexport * from \"./ErrorMessage\";\nexport * from \"./Fieldset\";\nexport * from \"./Flex\";\nexport * from \"./Grid\";\nexport * from \"./Icon\";\nexport * from \"./Image\";\nexport * from \"./Label\";\nexport * from \"./Link\";\nexport * from \"./LinkButton\";\nexport * from \"./List\";\nexport * from \"./LoadingIndicator\";\nexport * from \"./Logo\";\nexport * from \"./Modal\";\nexport * from \"./NumberField\";\nexport * from \"./Option\";\nexport * from \"./PasswordField\";\nexport * from \"./Popover\";\nexport * from \"./Progress\";\nexport * from \"./Radio\";\nexport * from \"./Segment\";\nexport * from \"./Select\";\nexport * from \"./Slider\";\nexport * from \"./Stack\";\nexport * from \"./SVG\";\nexport * from \"./Table\";\nexport * from \"./Text\";\nexport * from \"./TextArea\";\nexport * from \"./TextAreaInput\";\nexport * from \"./TextField\";\nexport * from \"./Title\";\nexport * from \"./Trust\";\nexport * from \"./VisuallyHidden\";\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA"}
1
+ {"version":3,"sources":["../../../src/components/index.tsx"],"sourcesContent":["export * from \"./Accordion\";\nexport * from \"./AddressLookup\";\nexport * from \"./Alert\";\nexport * from \"./Box\";\nexport * from \"./Breadcrumbs\";\nexport * from \"./Button\";\nexport * from \"./Checkbox\";\nexport * from \"./Combobox\";\nexport * from \"./Container\";\nexport * from \"./Divider\";\nexport * from \"./Drawer\";\nexport * from \"./DropdownMenu\";\nexport * from \"./ErrorMessage\";\nexport * from \"./Fieldset\";\nexport * from \"./Flex\";\nexport * from \"./Grid\";\nexport * from \"./Icon\";\nexport * from \"./Image\";\nexport * from \"./Label\";\nexport * from \"./Link\";\nexport * from \"./LinkButton\";\nexport * from \"./List\";\nexport * from \"./LoadingIndicator\";\nexport * from \"./Logo\";\nexport * from \"./Modal\";\nexport * from \"./NumberField\";\nexport * from \"./Option\";\nexport * from \"./PasswordField\";\nexport * from \"./Popover\";\nexport * from \"./Progress\";\nexport * from \"./Radio\";\nexport * from \"./Segment\";\nexport * from \"./Select\";\nexport * from \"./Slider\";\nexport * from \"./Stack\";\nexport * from \"./SVG\";\nexport * from \"./Table\";\nexport * from \"./Text\";\nexport * from \"./TextArea\";\nexport * from \"./TextAreaInput\";\nexport * from \"./TextField\";\nexport * from \"./Title\";\nexport * from \"./Trust\";\nexport * from \"./VisuallyHidden\";\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA"}