@pareto-engineering/design-system 2.0.0-alpha.45 → 2.0.0-alpha.48

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 (25) hide show
  1. package/dist/cjs/f/FormInput/FormInput.js +8 -1
  2. package/dist/cjs/f/fields/QueryCombobox/QueryCombobox.js +29 -6
  3. package/dist/cjs/f/fields/QueryCombobox/common/Combobox/Combobox.js +29 -5
  4. package/dist/cjs/f/fields/QueryCombobox/common/MultipleCombobox/MultipleCombobox.js +101 -26
  5. package/dist/cjs/f/fields/QueryCombobox/common/index.js +9 -1
  6. package/dist/cjs/f/fields/QueryCombobox/styles.scss +24 -5
  7. package/dist/es/f/FormInput/FormInput.js +9 -2
  8. package/dist/es/f/fields/QueryCombobox/QueryCombobox.js +30 -7
  9. package/dist/es/f/fields/QueryCombobox/common/Combobox/Combobox.js +30 -6
  10. package/dist/es/f/fields/QueryCombobox/common/MultipleCombobox/MultipleCombobox.js +101 -27
  11. package/dist/es/f/fields/QueryCombobox/common/index.js +2 -1
  12. package/dist/es/f/fields/QueryCombobox/styles.scss +24 -5
  13. package/package.json +2 -2
  14. package/src/__snapshots__/Storyshots.test.js.snap +379 -14
  15. package/src/local.scss +3 -3
  16. package/src/stories/f/FormInput.stories.jsx +115 -0
  17. package/src/stories/f/QueryCombobox.stories.jsx +55 -8
  18. package/src/stories/f/__generated__/FormInputAllTeamsQuery.graphql.js +139 -0
  19. package/src/ui/f/FormInput/FormInput.jsx +11 -0
  20. package/src/ui/f/fields/QueryCombobox/QueryCombobox.jsx +29 -6
  21. package/src/ui/f/fields/QueryCombobox/common/Combobox/Combobox.jsx +27 -3
  22. package/src/ui/f/fields/QueryCombobox/common/MultipleCombobox/MultipleCombobox.jsx +318 -0
  23. package/src/ui/f/fields/QueryCombobox/common/MultipleCombobox/index.js +2 -0
  24. package/src/ui/f/fields/QueryCombobox/common/index.js +1 -0
  25. package/src/ui/f/fields/QueryCombobox/styles.scss +24 -5
@@ -67,6 +67,13 @@ var FormInput = _ref => {
67
67
  }, otherProps));
68
68
  }
69
69
 
70
+ if (type === 'query-combobox') {
71
+ return /*#__PURE__*/React.createElement(_fields.QueryCombobox, _extends({
72
+ className: newClassName,
73
+ disabled: disabled
74
+ }, otherProps));
75
+ }
76
+
70
77
  if (extraTypes !== null && extraTypes !== void 0 && extraTypes[type]) {
71
78
  var Component = extraTypes[type];
72
79
  return /*#__PURE__*/React.createElement(Component, _extends({
@@ -91,7 +98,7 @@ FormInput.propTypes = {
91
98
  /**
92
99
  * The HTML class names for this element
93
100
  */
94
- type: _propTypes.default.oneOf(['text', 'email', 'password', 'number', 'date', 'datetime', 'month', 'tel', 'hidden', 'select', 'choices', 'textarea', // to be removed
101
+ type: _propTypes.default.oneOf(['text', 'email', 'password', 'number', 'date', 'datetime', 'month', 'tel', 'hidden', 'select', 'choices', 'textarea', 'query-combobox', // to be removed
95
102
  'extendedTypeInput']),
96
103
 
97
104
  /**
@@ -32,8 +32,11 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
32
32
  */
33
33
  var QueryCombobox = _ref => {
34
34
  var {
35
+ id,
36
+ style,
37
+ className,
35
38
  query,
36
- // multiple,
39
+ multiple,
37
40
  name,
38
41
  label,
39
42
  color,
@@ -43,7 +46,9 @@ var QueryCombobox = _ref => {
43
46
  graphQlNode,
44
47
  searchVariable,
45
48
  extraVariables,
46
- optionsKeyMap // ...otherProps
49
+ optionsKeyMap,
50
+ minLength,
51
+ transformSearch // ...otherProps
47
52
 
48
53
  } = _ref;
49
54
  (0, React.useLayoutEffect)(() => {
@@ -98,6 +103,8 @@ var QueryCombobox = _ref => {
98
103
  };
99
104
 
100
105
  var comboboxProps = {
106
+ id,
107
+ style,
101
108
  options,
102
109
  getOptions,
103
110
  debounceMs,
@@ -108,9 +115,13 @@ var QueryCombobox = _ref => {
108
115
  setValue,
109
116
  error,
110
117
  value,
111
- color
118
+ color,
119
+ isFetching,
120
+ className,
121
+ minLength,
122
+ transformSearch
112
123
  };
113
- var Input = _common.Combobox;
124
+ var Input = multiple ? _common.MultipleCombobox : _common.Combobox;
114
125
  return /*#__PURE__*/React.createElement(Input, comboboxProps);
115
126
  };
116
127
 
@@ -192,7 +203,17 @@ QueryCombobox.propTypes = {
192
203
  /**
193
204
  * The variable to be used to search the data
194
205
  */
195
- searchVariable: _propTypes.default.string
206
+ searchVariable: _propTypes.default.string,
207
+
208
+ /**
209
+ * The minimum length of the search input to start fetching the options
210
+ */
211
+ minLength: _propTypes.default.number,
212
+
213
+ /**
214
+ * The function to transform the search input
215
+ */
216
+ transformSearch: _propTypes.default.func
196
217
  };
197
218
  QueryCombobox.defaultProps = {
198
219
  optionsKeyMap: {
@@ -201,7 +222,9 @@ QueryCombobox.defaultProps = {
201
222
  },
202
223
  multiple: false,
203
224
  color: 'background2',
204
- searchVariable: 'search'
225
+ searchVariable: 'search',
226
+ transformSearch: search => search,
227
+ minLength: 2
205
228
  };
206
229
  var _default = QueryCombobox;
207
230
  exports.default = _default;
@@ -46,7 +46,10 @@ var Combobox = _ref => {
46
46
  error,
47
47
  description,
48
48
  value,
49
- color // ...otherProps
49
+ color,
50
+ minLength,
51
+ isFetching,
52
+ transformSearch // ...otherProps
50
53
 
51
54
  } = _ref;
52
55
  var {
@@ -67,7 +70,11 @@ var Combobox = _ref => {
67
70
  var {
68
71
  inputValue
69
72
  } = _ref2;
70
- getOptions(inputValue);
73
+ var transformedInput = transformSearch(inputValue);
74
+
75
+ if (transformedInput.length > minLength) {
76
+ getOptions(transformedInput);
77
+ }
71
78
  }
72
79
  }); // If the user has selected an item, we'll set the value of the field
73
80
  // or if the combobox state has a selected item, we'll set the value to the formik state
@@ -95,7 +102,9 @@ var Combobox = _ref => {
95
102
  className: "input-wrapper"
96
103
  }), /*#__PURE__*/React.createElement("input", _extends({}, getInputProps(), {
97
104
  className: "input"
98
- }))), /*#__PURE__*/React.createElement(_a.Popover, {
105
+ })), isFetching && /*#__PURE__*/React.createElement(_a.LoadingCircle, {
106
+ className: "x-main2"
107
+ })), /*#__PURE__*/React.createElement(_a.Popover, {
99
108
  isOpen: isOpen,
100
109
  parentRef: parentRef
101
110
  }, /*#__PURE__*/React.createElement(_Menu.Menu, _extends({
@@ -173,9 +182,24 @@ Combobox.propTypes = {
173
182
  /**
174
183
  * The base color of the combobox custom select input
175
184
  */
176
- color: _propTypes.default.string
185
+ color: _propTypes.default.string,
186
+
187
+ /**
188
+ * Whether the query getting the combobox options is inFlight
189
+ */
190
+ isFetching: _propTypes.default.bool.isRequired,
191
+
192
+ /**
193
+ * The minimum length of the search input to start fetching the options
194
+ */
195
+ minLength: _propTypes.default.number,
196
+
197
+ /**
198
+ * The function to transform the search input
199
+ */
200
+ transformSearch: _propTypes.default.func
177
201
  };
178
- Combobox.defaultProps = {// someProp:false
202
+ Combobox.defaultProps = {// someProp: false
179
203
  };
180
204
  var _default = Combobox;
181
205
  exports.default = _default;
@@ -15,6 +15,8 @@ var _downshift = require("downshift");
15
15
 
16
16
  var _b = require("../../../../../b");
17
17
 
18
+ var _a = require("../../../../../a");
19
+
18
20
  var _ = require("../../../..");
19
21
 
20
22
  var _Menu = require("../Menu");
@@ -35,10 +37,19 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
35
37
 
36
38
  var baseClassName = _bem.default.base;
37
39
  var componentClassName = 'multiple-combobox';
40
+ /**
41
+ * @param {Array[Object]} first - first array to check if it has an item not in the second array.
42
+ * @param {Array[Object]} second - second array to check against the first array.
43
+ *
44
+ * @returns {Boolean} - true if the first array has an item not in the second array.
45
+ */
46
+
47
+ var testIfArraysAreUnique = (first, second) => first.filter(objInFirstArray => !second.some(objInSecondArray => objInFirstArray.value === objInSecondArray.value)).length > 0;
38
48
  /**
39
49
  * This is the component description.
40
50
  */
41
51
 
52
+
42
53
  var MultipleCombobox = _ref => {
43
54
  var {
44
55
  id,
@@ -47,22 +58,34 @@ var MultipleCombobox = _ref => {
47
58
  label,
48
59
  name,
49
60
  options: items,
50
- fetchOptions,
61
+ getOptions,
51
62
  setValue,
52
63
  error,
53
- description // ...otherProps
64
+ description,
65
+ value,
66
+ color,
67
+ isFetching,
68
+ minLength,
69
+ transformSearch // ...otherProps
54
70
 
55
71
  } = _ref;
56
- var [inputValue, setInputValue] = (0, React.useState)('');
72
+ var [searchInputValue, setSearchInputValue] = (0, React.useState)('');
57
73
  var {
58
74
  getSelectedItemProps,
59
75
  getDropdownProps,
60
76
  addSelectedItem,
61
77
  removeSelectedItem,
78
+ setSelectedItems,
62
79
  selectedItems
63
- } = (0, _downshift.useMultipleSelection)();
80
+ } = (0, _downshift.useMultipleSelection)({
81
+ initialSelectedItems: value || []
82
+ });
83
+ /**
84
+ * @returns {Boolean} - Unique items from the options array so that the combobox
85
+ * shows only the options that are not yet selected.
86
+ */
64
87
 
65
- var getFilteredItems = () => items.filter(item => selectedItems.findIndex(e => e.label === item.label) < 0 && item.label.toLowerCase().startsWith(inputValue.toLowerCase()));
88
+ var getFilteredItems = () => items.filter(item => selectedItems.findIndex(e => e.label === item.label) < 0);
66
89
 
67
90
  var {
68
91
  isOpen,
@@ -73,7 +96,7 @@ var MultipleCombobox = _ref => {
73
96
  highlightedIndex,
74
97
  getItemProps
75
98
  } = (0, _downshift.useCombobox)({
76
- inputValue,
99
+ searchInputValue,
77
100
  defaultHighlightedIndex: 0,
78
101
  // after selection, highlight the first item.
79
102
  selectedItem: null,
@@ -101,22 +124,29 @@ var MultipleCombobox = _ref => {
101
124
  },
102
125
  onStateChange: _ref2 => {
103
126
  var {
104
- inputValue: newInputValue,
127
+ inputValue: newSearchInputValue,
105
128
  type,
106
129
  selectedItem
107
130
  } = _ref2;
108
131
 
109
132
  switch (type) {
110
133
  case _downshift.useCombobox.stateChangeTypes.InputChange:
111
- fetchOptions(newInputValue);
112
- setInputValue(newInputValue);
113
- break;
134
+ {
135
+ var transformedInput = transformSearch(newSearchInputValue);
136
+
137
+ if (transformedInput.length > minLength) {
138
+ getOptions(transformedInput);
139
+ }
140
+
141
+ setSearchInputValue(newSearchInputValue);
142
+ break;
143
+ }
114
144
 
115
145
  case _downshift.useCombobox.stateChangeTypes.InputKeyDownEnter:
116
146
  case _downshift.useCombobox.stateChangeTypes.ItemClick:
117
147
  case _downshift.useCombobox.stateChangeTypes.InputBlur:
118
148
  if (selectedItem) {
119
- setInputValue('');
149
+ setSearchInputValue('');
120
150
  addSelectedItem(selectedItem);
121
151
  }
122
152
 
@@ -128,43 +158,60 @@ var MultipleCombobox = _ref => {
128
158
  }
129
159
  });
130
160
  (0, React.useEffect)(() => {
131
- if (selectedItems.length > 0) {
132
- setValue(selectedItems.map(e => e.value));
161
+ if ((selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) > 0) {
162
+ setValue(selectedItems);
133
163
  }
134
164
  }, [selectedItems]);
165
+ (0, React.useEffect)(() => {
166
+ if ((value === null || value === void 0 ? void 0 : value.length) > 0 && (testIfArraysAreUnique(value, selectedItems) || testIfArraysAreUnique(selectedItems, value))) {
167
+ setSelectedItems(value);
168
+ }
169
+ }, [value]);
170
+ var parentRef = (0, React.useRef)(null);
135
171
  return /*#__PURE__*/React.createElement("div", {
136
172
  id: id,
137
- className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
173
+ className: [baseClassName, componentClassName, userClassName, "y-".concat(color)].filter(e => e).join(' '),
138
174
  style: style
139
175
  }, /*#__PURE__*/React.createElement(_.FormLabel, _extends({}, getLabelProps(), {
140
- className: "input-label",
141
176
  name: name
142
- }), label), /*#__PURE__*/React.createElement("div", {
177
+ }), label), (selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) > 0 && /*#__PURE__*/React.createElement("div", {
143
178
  className: "selected-items"
144
- }, selectedItems && selectedItems.map((selectedItem, index) => /*#__PURE__*/React.createElement("div", _extends({
179
+ }, selectedItems.map((selectedItem, index) => /*#__PURE__*/React.createElement("div", _extends({
145
180
  key: selectedItem.label
146
181
  }, getSelectedItemProps({
147
182
  selectedItem,
148
183
  index
149
- })), selectedItem.label, /*#__PURE__*/React.createElement(_b.Button, {
150
- className: "f-icons",
184
+ }), {
185
+ className: "item"
186
+ }), /*#__PURE__*/React.createElement(_b.Button, {
151
187
  onClick: e => {
152
188
  e.stopPropagation();
153
189
  removeSelectedItem(selectedItem);
154
190
  },
155
191
  isCompact: true,
156
192
  isSimple: true,
157
- color: "main2"
158
- }, "X")))), /*#__PURE__*/React.createElement("div", getComboboxProps(), /*#__PURE__*/React.createElement("input", _extends({}, getInputProps(getDropdownProps({
193
+ color: color
194
+ }, /*#__PURE__*/React.createElement("span", {
195
+ className: "v25 mr-v"
196
+ }, selectedItem.label), /*#__PURE__*/React.createElement("span", {
197
+ className: "f-icons close"
198
+ }, "Y"))))), /*#__PURE__*/React.createElement("div", _extends({}, getComboboxProps(), {
199
+ className: "input-wrapper"
200
+ }), /*#__PURE__*/React.createElement("input", _extends({}, getInputProps(getDropdownProps({
159
201
  preventKeyAction: isOpen
160
202
  })), {
161
203
  className: "input"
162
- }))), /*#__PURE__*/React.createElement(_Menu.Menu, _extends({
204
+ })), isFetching && /*#__PURE__*/React.createElement(_a.LoadingCircle, {
205
+ className: "x-main2"
206
+ })), /*#__PURE__*/React.createElement(_a.Popover, {
207
+ isOpen: isOpen,
208
+ parentRef: parentRef
209
+ }, /*#__PURE__*/React.createElement(_Menu.Menu, _extends({
163
210
  isOpen: isOpen,
164
211
  getItemProps: getItemProps,
165
212
  highlightedIndex: highlightedIndex,
166
213
  items: getFilteredItems()
167
- }, getMenuProps())), (description || error) && /*#__PURE__*/React.createElement(_.FormDescription, {
214
+ }, getMenuProps()))), (description || error) && /*#__PURE__*/React.createElement(_.FormDescription, {
168
215
  isError: !!error
169
216
  }, error || description));
170
217
  };
@@ -206,7 +253,7 @@ MultipleCombobox.propTypes = {
206
253
  /**
207
254
  * The function to fetch the options from the backend
208
255
  */
209
- fetchOptions: _propTypes.default.func,
256
+ getOptions: _propTypes.default.func,
210
257
 
211
258
  /**
212
259
  * The function to set the value of the custom select input
@@ -221,9 +268,37 @@ MultipleCombobox.propTypes = {
221
268
  /**
222
269
  * The error object
223
270
  */
224
- error: _propTypes.default.objectOf(_propTypes.default.string)
271
+ error: _propTypes.default.objectOf(_propTypes.default.string),
272
+
273
+ /**
274
+ * The value of the custom select input
275
+ */
276
+ value: _propTypes.default.arrayOf(_propTypes.default.shape({
277
+ value: _propTypes.default.string,
278
+ label: _propTypes.default.string
279
+ })),
280
+
281
+ /**
282
+ * The base color of the custom select input
283
+ */
284
+ color: _propTypes.default.string,
285
+
286
+ /**
287
+ * Whether the query getting the combobox options is inFlight
288
+ */
289
+ isFetching: _propTypes.default.bool.isRequired,
290
+
291
+ /**
292
+ * The minimum length of the search input to start fetching the options
293
+ */
294
+ minLength: _propTypes.default.number,
295
+
296
+ /**
297
+ * The function to transform the search input
298
+ */
299
+ transformSearch: _propTypes.default.func
225
300
  };
226
- MultipleCombobox.defaultProps = {// someProp:false
301
+ MultipleCombobox.defaultProps = {// someProp: false
227
302
  };
228
303
  var _default = MultipleCombobox;
229
304
  exports.default = _default;
@@ -15,7 +15,15 @@ Object.defineProperty(exports, "Combobox", {
15
15
  return _Combobox.Combobox;
16
16
  }
17
17
  });
18
+ Object.defineProperty(exports, "MultipleCombobox", {
19
+ enumerable: true,
20
+ get: function get() {
21
+ return _MultipleCombobox.MultipleCombobox;
22
+ }
23
+ });
18
24
 
19
25
  var _Menu = require("./Menu");
20
26
 
21
- var _Combobox = require("./Combobox");
27
+ var _Combobox = require("./Combobox");
28
+
29
+ var _MultipleCombobox = require("./MultipleCombobox");
@@ -5,11 +5,17 @@
5
5
  $default-input-padding: .75em .75em .55em;
6
6
  $default-padding: 1em;
7
7
  $default-margin: 1em;
8
+ $default-gap: 1em;
9
+ $default-loading-circle-displacement: 1em;
8
10
 
9
11
  .#{bem.$base}.combobox,
10
12
  .#{bem.$base}.multiple-combobox {
11
13
  position: relative;
12
14
 
15
+ .#{bem.$base}.label {
16
+ margin-bottom: $default-margin
17
+ }
18
+
13
19
  .#{bem.$base}.popover {
14
20
  width: 100%;
15
21
 
@@ -30,6 +36,14 @@ $default-margin: 1em;
30
36
  }
31
37
 
32
38
  >.input-wrapper {
39
+ position: relative;
40
+
41
+ >.#{bem.$base}.loading-circle {
42
+ position: absolute;
43
+ top: $default-loading-circle-displacement;
44
+ right: $default-loading-circle-displacement;
45
+ }
46
+
33
47
  >.input {
34
48
  background: var(--light-y);
35
49
  border: var(--theme-border-style) var(--dark-y);
@@ -60,12 +74,17 @@ $default-margin: 1em;
60
74
  .#{bem.$base}.multiple-combobox {
61
75
  >.selected-items {
62
76
  display: flex;
77
+ gap: $default-gap / 2;
78
+ flex-wrap: wrap;
79
+ margin-bottom: $default-margin / 2;
63
80
 
64
- /* stylelint-disable selector-max-universal -- Allow */
65
- >*:not(:first-child) {
66
- margin-left: $default-margin;
67
- }
81
+ >.item {
82
+ background-color: var(--main2);
83
+ padding: $default-padding / 4;
68
84
 
69
- /* stylelint-enable selector-max-universal */
85
+ .close {
86
+ font-size: calc(var(--s-3) * 1em);
87
+ }
88
+ }
70
89
  }
71
90
  }
@@ -4,7 +4,7 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
4
4
  import * as React from 'react';
5
5
  import { memo, useLayoutEffect } from 'react';
6
6
  import PropTypes from 'prop-types';
7
- import { TextInput, TextareaInput, ChoicesInput, SelectInput } from "../fields"; // Local Definitions
7
+ import { TextInput, TextareaInput, ChoicesInput, SelectInput, QueryCombobox } from "../fields"; // Local Definitions
8
8
  // const baseClassName = styleNames.base
9
9
 
10
10
  const componentClassName = 'form-input';
@@ -45,6 +45,13 @@ const FormInput = ({
45
45
  }, otherProps));
46
46
  }
47
47
 
48
+ if (type === 'query-combobox') {
49
+ return /*#__PURE__*/React.createElement(QueryCombobox, _extends({
50
+ className: newClassName,
51
+ disabled: disabled
52
+ }, otherProps));
53
+ }
54
+
48
55
  if (extraTypes !== null && extraTypes !== void 0 && extraTypes[type]) {
49
56
  const Component = extraTypes[type];
50
57
  return /*#__PURE__*/React.createElement(Component, _extends({
@@ -69,7 +76,7 @@ FormInput.propTypes = {
69
76
  /**
70
77
  * The HTML class names for this element
71
78
  */
72
- type: PropTypes.oneOf(['text', 'email', 'password', 'number', 'date', 'datetime', 'month', 'tel', 'hidden', 'select', 'choices', 'textarea', // to be removed
79
+ type: PropTypes.oneOf(['text', 'email', 'password', 'number', 'date', 'datetime', 'month', 'tel', 'hidden', 'select', 'choices', 'textarea', 'query-combobox', // to be removed
73
80
  'extendedTypeInput']),
74
81
 
75
82
  /**
@@ -5,14 +5,17 @@ import { useField } from 'formik';
5
5
  import { useRelayEnvironment, fetchQuery } from 'react-relay';
6
6
  import PropTypes from 'prop-types'; // Local Definitions
7
7
 
8
- import { Combobox } from "./common";
8
+ import { Combobox, MultipleCombobox } from "./common";
9
9
  /**
10
10
  * This is the component description.
11
11
  */
12
12
 
13
13
  const QueryCombobox = ({
14
+ id,
15
+ style,
16
+ className,
14
17
  query,
15
- // multiple,
18
+ multiple,
16
19
  name,
17
20
  label,
18
21
  color,
@@ -22,7 +25,9 @@ const QueryCombobox = ({
22
25
  graphQlNode,
23
26
  searchVariable,
24
27
  extraVariables,
25
- optionsKeyMap // ...otherProps
28
+ optionsKeyMap,
29
+ minLength,
30
+ transformSearch // ...otherProps
26
31
 
27
32
  }) => {
28
33
  useLayoutEffect(() => {
@@ -76,6 +81,8 @@ const QueryCombobox = ({
76
81
  };
77
82
 
78
83
  const comboboxProps = {
84
+ id,
85
+ style,
79
86
  options,
80
87
  getOptions,
81
88
  debounceMs,
@@ -86,9 +93,13 @@ const QueryCombobox = ({
86
93
  setValue,
87
94
  error,
88
95
  value,
89
- color
96
+ color,
97
+ isFetching,
98
+ className,
99
+ minLength,
100
+ transformSearch
90
101
  };
91
- const Input = Combobox;
102
+ const Input = multiple ? MultipleCombobox : Combobox;
92
103
  return /*#__PURE__*/React.createElement(Input, comboboxProps);
93
104
  };
94
105
 
@@ -170,7 +181,17 @@ QueryCombobox.propTypes = {
170
181
  /**
171
182
  * The variable to be used to search the data
172
183
  */
173
- searchVariable: PropTypes.string
184
+ searchVariable: PropTypes.string,
185
+
186
+ /**
187
+ * The minimum length of the search input to start fetching the options
188
+ */
189
+ minLength: PropTypes.number,
190
+
191
+ /**
192
+ * The function to transform the search input
193
+ */
194
+ transformSearch: PropTypes.func
174
195
  };
175
196
  QueryCombobox.defaultProps = {
176
197
  optionsKeyMap: {
@@ -179,6 +200,8 @@ QueryCombobox.defaultProps = {
179
200
  },
180
201
  multiple: false,
181
202
  color: 'background2',
182
- searchVariable: 'search'
203
+ searchVariable: 'search',
204
+ transformSearch: search => search,
205
+ minLength: 2
183
206
  };
184
207
  export default QueryCombobox;
@@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
7
7
  import { useCombobox } from 'downshift';
8
8
  import styleNames from '@pareto-engineering/bem';
9
9
  import { FormLabel, FormDescription } from "../../../..";
10
- import { Popover } from "../../../../../a"; // Local Definitions
10
+ import { Popover, LoadingCircle } from "../../../../../a"; // Local Definitions
11
11
 
12
12
  import { Menu } from "../Menu";
13
13
  const baseClassName = styleNames.base;
@@ -28,7 +28,10 @@ const Combobox = ({
28
28
  error,
29
29
  description,
30
30
  value,
31
- color // ...otherProps
31
+ color,
32
+ minLength,
33
+ isFetching,
34
+ transformSearch // ...otherProps
32
35
 
33
36
  }) => {
34
37
  const {
@@ -48,7 +51,11 @@ const Combobox = ({
48
51
  onInputValueChange: ({
49
52
  inputValue
50
53
  }) => {
51
- getOptions(inputValue);
54
+ const transformedInput = transformSearch(inputValue);
55
+
56
+ if (transformedInput.length > minLength) {
57
+ getOptions(transformedInput);
58
+ }
52
59
  }
53
60
  }); // If the user has selected an item, we'll set the value of the field
54
61
  // or if the combobox state has a selected item, we'll set the value to the formik state
@@ -76,7 +83,9 @@ const Combobox = ({
76
83
  className: "input-wrapper"
77
84
  }), /*#__PURE__*/React.createElement("input", _extends({}, getInputProps(), {
78
85
  className: "input"
79
- }))), /*#__PURE__*/React.createElement(Popover, {
86
+ })), isFetching && /*#__PURE__*/React.createElement(LoadingCircle, {
87
+ className: "x-main2"
88
+ })), /*#__PURE__*/React.createElement(Popover, {
80
89
  isOpen: isOpen,
81
90
  parentRef: parentRef
82
91
  }, /*#__PURE__*/React.createElement(Menu, _extends({
@@ -154,8 +163,23 @@ Combobox.propTypes = {
154
163
  /**
155
164
  * The base color of the combobox custom select input
156
165
  */
157
- color: PropTypes.string
166
+ color: PropTypes.string,
167
+
168
+ /**
169
+ * Whether the query getting the combobox options is inFlight
170
+ */
171
+ isFetching: PropTypes.bool.isRequired,
172
+
173
+ /**
174
+ * The minimum length of the search input to start fetching the options
175
+ */
176
+ minLength: PropTypes.number,
177
+
178
+ /**
179
+ * The function to transform the search input
180
+ */
181
+ transformSearch: PropTypes.func
158
182
  };
159
- Combobox.defaultProps = {// someProp:false
183
+ Combobox.defaultProps = {// someProp: false
160
184
  };
161
185
  export default Combobox;