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

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 (90) hide show
  1. package/.env.scripts.example +4 -0
  2. package/.eslintrc.js +25 -1
  3. package/babel.config.js +1 -0
  4. package/dist/cjs/a/Popover/styles.scss +9 -19
  5. package/dist/cjs/f/FormInput/FormInput.js +5 -2
  6. package/dist/cjs/f/FormInput/styles.scss +11 -0
  7. package/dist/cjs/f/fields/QueryCombobox/QueryCombobox.js +207 -0
  8. package/dist/cjs/f/fields/QueryCombobox/common/Combobox/Combobox.js +181 -0
  9. package/dist/cjs/f/fields/QueryCombobox/common/Combobox/index.js +15 -0
  10. package/dist/cjs/f/fields/QueryCombobox/common/Menu/Menu.js +103 -0
  11. package/dist/cjs/f/fields/QueryCombobox/common/Menu/index.js +15 -0
  12. package/dist/cjs/f/fields/QueryCombobox/common/MultipleCombobox/MultipleCombobox.js +229 -0
  13. package/dist/cjs/f/fields/QueryCombobox/common/MultipleCombobox/index.js +15 -0
  14. package/dist/cjs/f/fields/QueryCombobox/common/index.js +21 -0
  15. package/dist/cjs/f/fields/QueryCombobox/index.js +15 -0
  16. package/dist/cjs/f/fields/QueryCombobox/styles.scss +71 -0
  17. package/dist/cjs/f/fields/SelectInput/SelectInput.js +0 -1
  18. package/dist/cjs/f/fields/SelectInput/styles.scss +8 -6
  19. package/dist/cjs/f/fields/index.js +9 -1
  20. package/dist/cjs/index.js +13 -0
  21. package/dist/cjs/test/QueryLoader/QueryLoader.js +41 -0
  22. package/dist/cjs/test/QueryLoader/__generated__/QueryLoaderHelloQuery.graphql.js +71 -0
  23. package/dist/cjs/test/QueryLoader/common/PreloadedTestData/PreloadedTestData.js +49 -0
  24. package/dist/cjs/test/QueryLoader/common/PreloadedTestData/index.js +15 -0
  25. package/dist/cjs/test/QueryLoader/common/index.js +13 -0
  26. package/dist/cjs/test/QueryLoader/index.js +15 -0
  27. package/dist/cjs/test/QueryLoader/styles.scss +9 -0
  28. package/dist/cjs/test/index.js +13 -0
  29. package/dist/es/a/Popover/styles.scss +9 -19
  30. package/dist/es/f/FormInput/FormInput.js +4 -1
  31. package/dist/es/f/FormInput/styles.scss +11 -0
  32. package/dist/es/f/fields/QueryCombobox/QueryCombobox.js +184 -0
  33. package/dist/es/f/fields/QueryCombobox/common/Combobox/Combobox.js +161 -0
  34. package/dist/es/f/fields/QueryCombobox/common/Combobox/index.js +2 -0
  35. package/dist/es/f/fields/QueryCombobox/common/Menu/Menu.js +77 -0
  36. package/dist/es/f/fields/QueryCombobox/common/Menu/index.js +2 -0
  37. package/dist/es/f/fields/QueryCombobox/common/MultipleCombobox/MultipleCombobox.js +202 -0
  38. package/dist/es/f/fields/QueryCombobox/common/MultipleCombobox/index.js +2 -0
  39. package/dist/es/f/fields/QueryCombobox/common/index.js +2 -0
  40. package/dist/es/f/fields/QueryCombobox/index.js +2 -0
  41. package/dist/es/f/fields/QueryCombobox/styles.scss +71 -0
  42. package/dist/es/f/fields/SelectInput/SelectInput.js +0 -1
  43. package/dist/es/f/fields/SelectInput/styles.scss +8 -6
  44. package/dist/es/f/fields/index.js +2 -1
  45. package/dist/es/index.js +2 -1
  46. package/dist/es/test/QueryLoader/QueryLoader.js +29 -0
  47. package/dist/es/test/QueryLoader/__generated__/QueryLoaderHelloQuery.graphql.js +71 -0
  48. package/dist/es/test/QueryLoader/common/PreloadedTestData/PreloadedTestData.js +31 -0
  49. package/dist/es/test/QueryLoader/common/PreloadedTestData/index.js +2 -0
  50. package/dist/es/test/QueryLoader/common/index.js +1 -0
  51. package/dist/es/test/QueryLoader/index.js +2 -0
  52. package/dist/es/test/QueryLoader/styles.scss +9 -0
  53. package/dist/es/test/index.js +1 -0
  54. package/package.json +16 -3
  55. package/relay.config.js +12 -0
  56. package/schema.graphql +4075 -0
  57. package/scripts/fetchSchema.js +74 -0
  58. package/src/__snapshots__/Storyshots.test.js.snap +168 -8
  59. package/src/stories/f/QueryCombobox.stories.jsx +220 -0
  60. package/src/stories/f/__generated__/QueryComboboxAllTeamsQuery.graphql.js +139 -0
  61. package/src/stories/test/QueryLoader.stories.jsx +36 -0
  62. package/src/stories/utils/generateNodeId.js +12 -0
  63. package/src/stories/utils/relay/EnvironmentProvider.jsx +14 -0
  64. package/src/stories/utils/relay/environment.js +5 -0
  65. package/src/stories/utils/relay/index.js +4 -0
  66. package/src/stories/utils/relay/mockRelayOperation.js +14 -0
  67. package/src/stories/utils/relay/mockResolvers.js +299 -0
  68. package/src/stories/utils/testData.js +63 -0
  69. package/src/ui/a/Popover/styles.scss +9 -19
  70. package/src/ui/f/FormInput/FormInput.jsx +5 -1
  71. package/src/ui/f/FormInput/styles.scss +11 -0
  72. package/src/ui/f/fields/QueryCombobox/QueryCombobox.jsx +200 -0
  73. package/src/ui/f/fields/QueryCombobox/common/Combobox/Combobox.jsx +198 -0
  74. package/src/ui/f/fields/QueryCombobox/common/Combobox/index.js +2 -0
  75. package/src/ui/f/fields/QueryCombobox/common/Menu/Menu.jsx +103 -0
  76. package/src/ui/f/fields/QueryCombobox/common/Menu/index.js +2 -0
  77. package/src/ui/f/fields/QueryCombobox/common/index.js +2 -0
  78. package/src/ui/f/fields/QueryCombobox/index.js +2 -0
  79. package/src/ui/f/fields/QueryCombobox/styles.scss +71 -0
  80. package/src/ui/f/fields/SelectInput/SelectInput.jsx +1 -1
  81. package/src/ui/f/fields/SelectInput/styles.scss +8 -6
  82. package/src/ui/f/fields/index.js +1 -0
  83. package/src/ui/index.js +1 -0
  84. package/src/ui/test/QueryLoader/QueryLoader.jsx +41 -0
  85. package/src/ui/test/QueryLoader/__generated__/QueryLoaderHelloQuery.graphql.js +68 -0
  86. package/src/ui/test/QueryLoader/common/PreloadedTestData/PreloadedTestData.jsx +51 -0
  87. package/src/ui/test/QueryLoader/common/PreloadedTestData/index.js +2 -0
  88. package/src/ui/test/QueryLoader/common/index.js +1 -0
  89. package/src/ui/test/QueryLoader/index.js +2 -0
  90. package/src/ui/test/index.js +1 -0
@@ -1,24 +1,17 @@
1
1
  /* @pareto-engineering/generator-front 1.0.12 */
2
2
  @use "@pareto-engineering/bem";
3
3
 
4
- $default-padding: 1em;
5
- $default-margin: 1em;
6
4
  $default-border: var(--theme-border-style) var(--metadata);
7
5
 
8
- .#{bem.$base}.popover{
9
- position: absolute;
10
- z-index: 1;
11
- background-color: var(--x);
12
- padding: $default-padding;
13
- border: $default-border;
6
+ .#{bem.$base}.popover {
7
+ position: absolute;
8
+ z-index: 1;
9
+ background-color: var(--x);
10
+ border: $default-border;
14
11
 
15
- &:not(.open) {
16
- display: none;
17
- }
18
-
19
- > *:not(:last-child) {
20
- margin-bottom: $default-margin / 2;
21
- }
12
+ &:not(.open) {
13
+ display: none;
14
+ }
22
15
 
23
16
  &.bottom {
24
17
  top: 100%;
@@ -37,7 +30,4 @@ $default-border: var(--theme-border-style) var(--metadata);
37
30
  bottom: 100%;
38
31
  top: auto;
39
32
  }
40
- }
41
-
42
-
43
-
33
+ }
@@ -2,7 +2,7 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
2
2
 
3
3
  /* @pareto-engineering/generator-front 1.0.12 */
4
4
  import * as React from 'react';
5
- import { memo } from 'react';
5
+ import { memo, useLayoutEffect } from 'react';
6
6
  import PropTypes from 'prop-types';
7
7
  import { TextInput, TextareaInput, ChoicesInput, SelectInput } from "../fields"; // Local Definitions
8
8
  // const baseClassName = styleNames.base
@@ -19,6 +19,9 @@ const FormInput = ({
19
19
  disabled,
20
20
  ...otherProps
21
21
  }) => {
22
+ useLayoutEffect(() => {
23
+ import("./styles.scss");
24
+ }, []);
22
25
  const newClassName = [className, componentClassName].filter(Boolean).join(' ');
23
26
 
24
27
  if (type === 'textarea') {
@@ -0,0 +1,11 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+
3
+ @use "@pareto-engineering/bem";
4
+
5
+ $default-margin: 1em;
6
+
7
+ .#{bem.$base}.form-input {
8
+ &+& {
9
+ margin-top: $default-margin;
10
+ }
11
+ }
@@ -0,0 +1,184 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ import * as React from 'react';
3
+ import { useState, useLayoutEffect } from 'react';
4
+ import { useField } from 'formik';
5
+ import { useRelayEnvironment, fetchQuery } from 'react-relay';
6
+ import PropTypes from 'prop-types'; // Local Definitions
7
+
8
+ import { Combobox } from "./common";
9
+ /**
10
+ * This is the component description.
11
+ */
12
+
13
+ const QueryCombobox = ({
14
+ query,
15
+ // multiple,
16
+ name,
17
+ label,
18
+ color,
19
+ description,
20
+ disabled,
21
+ debounceMs,
22
+ graphQlNode,
23
+ searchVariable,
24
+ extraVariables,
25
+ optionsKeyMap // ...otherProps
26
+
27
+ }) => {
28
+ useLayoutEffect(() => {
29
+ import("./styles.scss");
30
+ }, []);
31
+ const [, meta, helpers] = useField(name);
32
+ const {
33
+ setValue,
34
+ setError
35
+ } = helpers;
36
+ const {
37
+ error,
38
+ value
39
+ } = meta;
40
+ const environment = useRelayEnvironment();
41
+ const [isFetching, setIsFetching] = useState(false);
42
+ const [options, setOptions] = useState([]);
43
+
44
+ const getOptions = inputValue => {
45
+ if (isFetching) return;
46
+ let variables = {
47
+ [searchVariable]: inputValue
48
+ };
49
+
50
+ if (extraVariables) {
51
+ variables = { ...variables,
52
+ ...extraVariables
53
+ };
54
+ }
55
+
56
+ fetchQuery(environment, query, variables).subscribe({
57
+ start: () => {
58
+ setIsFetching(true);
59
+ },
60
+ complete: () => {
61
+ setIsFetching(false);
62
+ },
63
+ error: fetchError => {
64
+ setIsFetching(false);
65
+ if (setError) setError(fetchError.message);
66
+ },
67
+ next: data => {
68
+ setOptions(data[graphQlNode].edges.map(({
69
+ node
70
+ }) => ({
71
+ value: node[optionsKeyMap.value],
72
+ label: node[optionsKeyMap.label]
73
+ })));
74
+ }
75
+ });
76
+ };
77
+
78
+ const comboboxProps = {
79
+ options,
80
+ getOptions,
81
+ debounceMs,
82
+ disabled,
83
+ name,
84
+ label,
85
+ description,
86
+ setValue,
87
+ error,
88
+ value,
89
+ color
90
+ };
91
+ const Input = Combobox;
92
+ return /*#__PURE__*/React.createElement(Input, comboboxProps);
93
+ };
94
+
95
+ QueryCombobox.propTypes = {
96
+ /**
97
+ * The HTML id for this element
98
+ */
99
+ id: PropTypes.string,
100
+
101
+ /**
102
+ * The HTML class names for this element
103
+ */
104
+ className: PropTypes.string,
105
+
106
+ /**
107
+ * The React-written, css properties for this element.
108
+ */
109
+ style: PropTypes.objectOf(PropTypes.string),
110
+
111
+ /**
112
+ * The name of the custom select input
113
+ */
114
+ name: PropTypes.string,
115
+
116
+ /**
117
+ * The label of the custom select input
118
+ */
119
+ label: PropTypes.string,
120
+
121
+ /**
122
+ * The custom select input description
123
+ */
124
+ description: PropTypes.string,
125
+
126
+ /**
127
+ * Whether the input should be disabled
128
+ */
129
+ disabled: PropTypes.bool,
130
+
131
+ /**
132
+ * The base color of the custom select input
133
+ */
134
+ color: PropTypes.string,
135
+
136
+ /**
137
+ * The debounce time in milliseconds
138
+ */
139
+ debounceMs: PropTypes.number,
140
+
141
+ /**
142
+ * The query to fetch the options
143
+ */
144
+ query: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
145
+
146
+ /**
147
+ * The extra variables required to be used in the query.
148
+ */
149
+ extraVariables: PropTypes.objectOf(PropTypes.string),
150
+
151
+ /**
152
+ * The select option keys to be used to map the data to the select options.
153
+ * i.e `{ value: 'id', label: 'name' }`
154
+ */
155
+ optionsKeyMap: PropTypes.shape({
156
+ value: PropTypes.string.isRequired,
157
+ label: PropTypes.string.isRequired
158
+ }),
159
+
160
+ /**
161
+ * Whether to allow multiple items selection
162
+ */
163
+ multiple: PropTypes.bool,
164
+
165
+ /**
166
+ * The graphql node to be used to destructure the fetched data
167
+ */
168
+ graphQlNode: PropTypes.string.isRequired,
169
+
170
+ /**
171
+ * The variable to be used to search the data
172
+ */
173
+ searchVariable: PropTypes.string
174
+ };
175
+ QueryCombobox.defaultProps = {
176
+ optionsKeyMap: {
177
+ value: 'id',
178
+ label: 'name'
179
+ },
180
+ multiple: false,
181
+ color: 'background2',
182
+ searchVariable: 'search'
183
+ };
184
+ export default QueryCombobox;
@@ -0,0 +1,161 @@
1
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ /* @pareto-engineering/generator-front 1.0.12 */
4
+ import * as React from 'react';
5
+ import { useEffect, useRef } from 'react';
6
+ import PropTypes from 'prop-types';
7
+ import { useCombobox } from 'downshift';
8
+ import styleNames from '@pareto-engineering/bem';
9
+ import { FormLabel, FormDescription } from "../../../..";
10
+ import { Popover } from "../../../../../a"; // Local Definitions
11
+
12
+ import { Menu } from "../Menu";
13
+ const baseClassName = styleNames.base;
14
+ const componentClassName = 'combobox';
15
+ /**
16
+ * This is the component description.
17
+ */
18
+
19
+ const Combobox = ({
20
+ id,
21
+ className: userClassName,
22
+ style,
23
+ label,
24
+ name,
25
+ options: items,
26
+ getOptions,
27
+ setValue,
28
+ error,
29
+ description,
30
+ value,
31
+ color // ...otherProps
32
+
33
+ }) => {
34
+ const {
35
+ isOpen,
36
+ selectItem,
37
+ selectedItem,
38
+ getLabelProps,
39
+ getMenuProps,
40
+ getInputProps,
41
+ highlightedIndex,
42
+ getComboboxProps,
43
+ getItemProps
44
+ } = useCombobox({
45
+ items,
46
+ initialSelectedItem: value,
47
+ itemToString: item => item ? item.label : '',
48
+ onInputValueChange: ({
49
+ inputValue
50
+ }) => {
51
+ getOptions(inputValue);
52
+ }
53
+ }); // If the user has selected an item, we'll set the value of the field
54
+ // or if the combobox state has a selected item, we'll set the value to the formik state
55
+
56
+ useEffect(() => {
57
+ if (selectedItem) {
58
+ setValue(selectedItem);
59
+ }
60
+ }, [selectedItem]); // If the formik state has a value, we'll set the selected item to the combobox state
61
+
62
+ useEffect(() => {
63
+ if ((value === null || value === void 0 ? void 0 : value.value) !== (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.value)) {
64
+ selectItem(value);
65
+ }
66
+ }, [value]);
67
+ const parentRef = useRef(null);
68
+ return /*#__PURE__*/React.createElement("div", {
69
+ id: id,
70
+ className: [baseClassName, componentClassName, userClassName, `y-${color}`].filter(e => e).join(' '),
71
+ style: style,
72
+ ref: parentRef
73
+ }, /*#__PURE__*/React.createElement(FormLabel, _extends({}, getLabelProps(), {
74
+ name: name
75
+ }), label), /*#__PURE__*/React.createElement("div", _extends({}, getComboboxProps(), {
76
+ className: "input-wrapper"
77
+ }), /*#__PURE__*/React.createElement("input", _extends({}, getInputProps(), {
78
+ className: "input"
79
+ }))), /*#__PURE__*/React.createElement(Popover, {
80
+ isOpen: isOpen,
81
+ parentRef: parentRef
82
+ }, /*#__PURE__*/React.createElement(Menu, _extends({
83
+ isOpen: isOpen,
84
+ getItemProps: getItemProps,
85
+ highlightedIndex: highlightedIndex,
86
+ items: items
87
+ }, getMenuProps()))), (description || error) && /*#__PURE__*/React.createElement(FormDescription, {
88
+ isError: !!error
89
+ }, error || description));
90
+ };
91
+
92
+ Combobox.propTypes = {
93
+ /**
94
+ * The HTML id for this element
95
+ */
96
+ id: PropTypes.string,
97
+
98
+ /**
99
+ * The HTML class names for this element
100
+ */
101
+ className: PropTypes.string,
102
+
103
+ /**
104
+ * The React-written, css properties for this element.
105
+ */
106
+ style: PropTypes.objectOf(PropTypes.string),
107
+
108
+ /**
109
+ * The label of the custom select input
110
+ */
111
+ label: PropTypes.string,
112
+
113
+ /**
114
+ * The custom select input options from the backend
115
+ */
116
+ options: PropTypes.arrayOf(PropTypes.shape({
117
+ value: PropTypes.string,
118
+ label: PropTypes.string
119
+ })),
120
+
121
+ /**
122
+ * The name of the custom select input
123
+ */
124
+ name: PropTypes.string,
125
+
126
+ /**
127
+ * The function to fetch the options from the backend
128
+ */
129
+ getOptions: PropTypes.func,
130
+
131
+ /**
132
+ * The function to set the value of the custom select input
133
+ */
134
+ setValue: PropTypes.func.isRequired,
135
+
136
+ /**
137
+ * The custom select input description
138
+ */
139
+ description: PropTypes.string,
140
+
141
+ /**
142
+ * The error object
143
+ */
144
+ error: PropTypes.objectOf(PropTypes.string),
145
+
146
+ /**
147
+ * The value of the custom select input
148
+ */
149
+ value: PropTypes.shape({
150
+ value: PropTypes.string,
151
+ label: PropTypes.string
152
+ }),
153
+
154
+ /**
155
+ * The base color of the combobox custom select input
156
+ */
157
+ color: PropTypes.string
158
+ };
159
+ Combobox.defaultProps = {// someProp:false
160
+ };
161
+ export default Combobox;
@@ -0,0 +1,2 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ export { default as Combobox } from "./Combobox";
@@ -0,0 +1,77 @@
1
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ /* @pareto-engineering/generator-front 1.0.12 */
4
+ import * as React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import styleNames from '@pareto-engineering/bem'; // Local Definitions
7
+
8
+ const baseClassName = styleNames.base;
9
+ const componentClassName = 'menu';
10
+ /**
11
+ * This is the component description.
12
+ */
13
+
14
+ const Menu = /*#__PURE__*/React.forwardRef(({
15
+ id,
16
+ className: userClassName,
17
+ style,
18
+ items,
19
+ isOpen,
20
+ highlightedIndex,
21
+ getItemProps,
22
+ ...otherProps
23
+ }, ref) => /*#__PURE__*/React.createElement("ul", _extends({
24
+ id: id,
25
+ className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
26
+ style: style,
27
+ ref: ref
28
+ }, otherProps), isOpen && items.map((item, index) => /*#__PURE__*/React.createElement("li", _extends({
29
+ key: item.label
30
+ }, getItemProps({
31
+ item,
32
+ index
33
+ }), {
34
+ className: ['item', highlightedIndex === index && styleNames.modifierActive].filter(Boolean).join(' ')
35
+ }), /*#__PURE__*/React.createElement("p", null, item.label)))));
36
+ Menu.propTypes = {
37
+ /**
38
+ * The HTML id for this element
39
+ */
40
+ id: PropTypes.string,
41
+
42
+ /**
43
+ * The HTML class names for this element
44
+ */
45
+ className: PropTypes.string,
46
+
47
+ /**
48
+ * The React-written, css properties for this element.
49
+ */
50
+ style: PropTypes.objectOf(PropTypes.string),
51
+
52
+ /**
53
+ * The items to be displayed in the menu
54
+ */
55
+ items: PropTypes.arrayOf(PropTypes.shape({
56
+ value: PropTypes.string,
57
+ label: PropTypes.string
58
+ })),
59
+
60
+ /**
61
+ * Whether or not the menu is open
62
+ */
63
+ isOpen: PropTypes.bool,
64
+
65
+ /**
66
+ * The index of the highlighted item
67
+ */
68
+ highlightedIndex: PropTypes.number,
69
+
70
+ /**
71
+ * The function to get the item props
72
+ */
73
+ getItemProps: PropTypes.func
74
+ };
75
+ Menu.defaultProps = {// someProp:false
76
+ };
77
+ export default Menu;
@@ -0,0 +1,2 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ export { default as Menu } from "./Menu";
@@ -0,0 +1,202 @@
1
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ /* @pareto-engineering/generator-front 1.0.12 */
4
+ import * as React from 'react';
5
+ import { useState, useEffect } from 'react';
6
+ import PropTypes from 'prop-types';
7
+ import styleNames from '@pareto-engineering/bem';
8
+ import { useCombobox, useMultipleSelection } from 'downshift';
9
+ import { Button } from "../../../../../b";
10
+ import { FormDescription, FormLabel } from "../../../.."; // Local Definitions
11
+
12
+ import { Menu } from "../Menu";
13
+ const baseClassName = styleNames.base;
14
+ const componentClassName = 'multiple-combobox';
15
+ /**
16
+ * This is the component description.
17
+ */
18
+
19
+ const MultipleCombobox = ({
20
+ id,
21
+ className: userClassName,
22
+ style,
23
+ label,
24
+ name,
25
+ options: items,
26
+ fetchOptions,
27
+ setValue,
28
+ error,
29
+ description // ...otherProps
30
+
31
+ }) => {
32
+ const [inputValue, setInputValue] = useState('');
33
+ const {
34
+ getSelectedItemProps,
35
+ getDropdownProps,
36
+ addSelectedItem,
37
+ removeSelectedItem,
38
+ selectedItems
39
+ } = useMultipleSelection();
40
+
41
+ const getFilteredItems = () => items.filter(item => selectedItems.findIndex(e => e.label === item.label) < 0 && item.label.toLowerCase().startsWith(inputValue.toLowerCase()));
42
+
43
+ const {
44
+ isOpen,
45
+ getLabelProps,
46
+ getMenuProps,
47
+ getInputProps,
48
+ getComboboxProps,
49
+ highlightedIndex,
50
+ getItemProps
51
+ } = useCombobox({
52
+ inputValue,
53
+ defaultHighlightedIndex: 0,
54
+ // after selection, highlight the first item.
55
+ selectedItem: null,
56
+ items: getFilteredItems(),
57
+ circularNavigation: true,
58
+ stateReducer: (state, actionAndChanges) => {
59
+ const {
60
+ changes,
61
+ type
62
+ } = actionAndChanges;
63
+
64
+ switch (type) {
65
+ case useCombobox.stateChangeTypes.InputKeyDownEnter:
66
+ case useCombobox.stateChangeTypes.ItemClick:
67
+ return { ...changes,
68
+ isOpen: true // keep the menu open after selection.
69
+
70
+ };
71
+
72
+ default:
73
+ break;
74
+ }
75
+
76
+ return changes;
77
+ },
78
+ onStateChange: ({
79
+ inputValue: newInputValue,
80
+ type,
81
+ selectedItem
82
+ }) => {
83
+ switch (type) {
84
+ case useCombobox.stateChangeTypes.InputChange:
85
+ fetchOptions(newInputValue);
86
+ setInputValue(newInputValue);
87
+ break;
88
+
89
+ case useCombobox.stateChangeTypes.InputKeyDownEnter:
90
+ case useCombobox.stateChangeTypes.ItemClick:
91
+ case useCombobox.stateChangeTypes.InputBlur:
92
+ if (selectedItem) {
93
+ setInputValue('');
94
+ addSelectedItem(selectedItem);
95
+ }
96
+
97
+ break;
98
+
99
+ default:
100
+ break;
101
+ }
102
+ }
103
+ });
104
+ useEffect(() => {
105
+ if (selectedItems.length > 0) {
106
+ setValue(selectedItems.map(e => e.value));
107
+ }
108
+ }, [selectedItems]);
109
+ return /*#__PURE__*/React.createElement("div", {
110
+ id: id,
111
+ className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
112
+ style: style
113
+ }, /*#__PURE__*/React.createElement(FormLabel, _extends({}, getLabelProps(), {
114
+ className: "input-label",
115
+ name: name
116
+ }), label), /*#__PURE__*/React.createElement("div", {
117
+ className: "selected-items"
118
+ }, selectedItems && selectedItems.map((selectedItem, index) => /*#__PURE__*/React.createElement("div", _extends({
119
+ key: selectedItem.label
120
+ }, getSelectedItemProps({
121
+ selectedItem,
122
+ index
123
+ })), selectedItem.label, /*#__PURE__*/React.createElement(Button, {
124
+ className: "f-icons",
125
+ onClick: e => {
126
+ e.stopPropagation();
127
+ removeSelectedItem(selectedItem);
128
+ },
129
+ isCompact: true,
130
+ isSimple: true,
131
+ color: "main2"
132
+ }, "X")))), /*#__PURE__*/React.createElement("div", getComboboxProps(), /*#__PURE__*/React.createElement("input", _extends({}, getInputProps(getDropdownProps({
133
+ preventKeyAction: isOpen
134
+ })), {
135
+ className: "input"
136
+ }))), /*#__PURE__*/React.createElement(Menu, _extends({
137
+ isOpen: isOpen,
138
+ getItemProps: getItemProps,
139
+ highlightedIndex: highlightedIndex,
140
+ items: getFilteredItems()
141
+ }, getMenuProps())), (description || error) && /*#__PURE__*/React.createElement(FormDescription, {
142
+ isError: !!error
143
+ }, error || description));
144
+ };
145
+
146
+ MultipleCombobox.propTypes = {
147
+ /**
148
+ * The HTML id for this element
149
+ */
150
+ id: PropTypes.string,
151
+
152
+ /**
153
+ * The HTML class names for this element
154
+ */
155
+ className: PropTypes.string,
156
+
157
+ /**
158
+ * The React-written, css properties for this element.
159
+ */
160
+ style: PropTypes.objectOf(PropTypes.string),
161
+
162
+ /**
163
+ * The label of the custom select input
164
+ */
165
+ label: PropTypes.string,
166
+
167
+ /**
168
+ * The custom select input options from the backend
169
+ */
170
+ options: PropTypes.arrayOf(PropTypes.shape({
171
+ value: PropTypes.string,
172
+ label: PropTypes.string
173
+ })),
174
+
175
+ /**
176
+ * The name of the custom select input
177
+ */
178
+ name: PropTypes.string,
179
+
180
+ /**
181
+ * The function to fetch the options from the backend
182
+ */
183
+ fetchOptions: PropTypes.func,
184
+
185
+ /**
186
+ * The function to set the value of the custom select input
187
+ */
188
+ setValue: PropTypes.func.isRequired,
189
+
190
+ /**
191
+ * The custom select input description
192
+ */
193
+ description: PropTypes.string,
194
+
195
+ /**
196
+ * The error object
197
+ */
198
+ error: PropTypes.objectOf(PropTypes.string)
199
+ };
200
+ MultipleCombobox.defaultProps = {// someProp:false
201
+ };
202
+ export default MultipleCombobox;
@@ -0,0 +1,2 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ export { default as MultipleCombobox } from "./MultipleCombobox";