@pareto-engineering/design-system 2.0.0-alpha.43 → 2.0.0-alpha.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.scripts.example +4 -0
- package/.eslintrc.js +25 -1
- package/babel.config.js +1 -0
- package/dist/cjs/f/FormInput/FormInput.js +5 -2
- package/dist/cjs/f/FormInput/styles.scss +11 -0
- package/dist/cjs/f/fields/QueryCombobox/QueryCombobox.js +222 -0
- package/dist/cjs/f/fields/QueryCombobox/common/Combobox/Combobox.js +148 -0
- package/dist/cjs/f/fields/QueryCombobox/common/Combobox/index.js +15 -0
- package/dist/cjs/f/fields/QueryCombobox/common/Menu/Menu.js +103 -0
- package/dist/cjs/f/fields/QueryCombobox/common/Menu/index.js +15 -0
- package/dist/cjs/f/fields/QueryCombobox/common/MultipleCombobox/MultipleCombobox.js +229 -0
- package/dist/cjs/f/fields/QueryCombobox/common/MultipleCombobox/index.js +15 -0
- package/dist/cjs/f/fields/QueryCombobox/common/index.js +29 -0
- package/dist/cjs/f/fields/QueryCombobox/index.js +15 -0
- package/dist/cjs/f/fields/QueryCombobox/styles.scss +65 -0
- package/dist/cjs/f/fields/SelectInput/SelectInput.js +0 -1
- package/dist/cjs/f/fields/SelectInput/styles.scss +8 -6
- package/dist/cjs/index.js +13 -0
- package/dist/cjs/test/QueryLoader/QueryLoader.js +41 -0
- package/dist/cjs/test/QueryLoader/__generated__/QueryLoaderHelloQuery.graphql.js +71 -0
- package/dist/cjs/test/QueryLoader/common/PreloadedTestData/PreloadedTestData.js +49 -0
- package/dist/cjs/test/QueryLoader/common/PreloadedTestData/index.js +15 -0
- package/dist/cjs/test/QueryLoader/common/index.js +13 -0
- package/dist/cjs/test/QueryLoader/index.js +15 -0
- package/dist/cjs/test/QueryLoader/styles.scss +9 -0
- package/dist/cjs/test/index.js +13 -0
- package/dist/es/f/FormInput/FormInput.js +4 -1
- package/dist/es/f/FormInput/styles.scss +11 -0
- package/dist/es/f/fields/QueryCombobox/QueryCombobox.js +197 -0
- package/dist/es/f/fields/QueryCombobox/common/Combobox/Combobox.js +129 -0
- package/dist/es/f/fields/QueryCombobox/common/Combobox/index.js +2 -0
- package/dist/es/f/fields/QueryCombobox/common/Menu/Menu.js +77 -0
- package/dist/es/f/fields/QueryCombobox/common/Menu/index.js +2 -0
- package/dist/es/f/fields/QueryCombobox/common/MultipleCombobox/MultipleCombobox.js +202 -0
- package/dist/es/f/fields/QueryCombobox/common/MultipleCombobox/index.js +2 -0
- package/dist/es/f/fields/QueryCombobox/common/index.js +3 -0
- package/dist/es/f/fields/QueryCombobox/index.js +2 -0
- package/dist/es/f/fields/QueryCombobox/styles.scss +65 -0
- package/dist/es/f/fields/SelectInput/SelectInput.js +0 -1
- package/dist/es/f/fields/SelectInput/styles.scss +8 -6
- package/dist/es/index.js +2 -1
- package/dist/es/test/QueryLoader/QueryLoader.js +29 -0
- package/dist/es/test/QueryLoader/__generated__/QueryLoaderHelloQuery.graphql.js +71 -0
- package/dist/es/test/QueryLoader/common/PreloadedTestData/PreloadedTestData.js +31 -0
- package/dist/es/test/QueryLoader/common/PreloadedTestData/index.js +2 -0
- package/dist/es/test/QueryLoader/common/index.js +1 -0
- package/dist/es/test/QueryLoader/index.js +2 -0
- package/dist/es/test/QueryLoader/styles.scss +9 -0
- package/dist/es/test/index.js +1 -0
- package/package.json +14 -2
- package/relay.config.js +12 -0
- package/schema.graphql +4075 -0
- package/scripts/fetchSchema.js +74 -0
- package/src/__snapshots__/Storyshots.test.js.snap +10 -8
- package/src/stories/test/QueryLoader.stories.jsx +36 -0
- package/src/stories/utils/relay/EnvironmentProvider.jsx +14 -0
- package/src/stories/utils/relay/environment.js +5 -0
- package/src/stories/utils/relay/index.js +4 -0
- package/src/stories/utils/relay/mockRelayOperation.js +14 -0
- package/src/stories/utils/relay/mockResolvers.js +299 -0
- package/src/ui/f/FormInput/FormInput.jsx +5 -1
- package/src/ui/f/FormInput/styles.scss +11 -0
- package/src/ui/f/fields/SelectInput/SelectInput.jsx +1 -1
- package/src/ui/f/fields/SelectInput/styles.scss +8 -6
- package/src/ui/index.js +1 -0
- package/src/ui/test/QueryLoader/QueryLoader.jsx +41 -0
- package/src/ui/test/QueryLoader/__generated__/QueryLoaderHelloQuery.graphql.js +68 -0
- package/src/ui/test/QueryLoader/common/PreloadedTestData/PreloadedTestData.jsx +51 -0
- package/src/ui/test/QueryLoader/common/PreloadedTestData/index.js +2 -0
- package/src/ui/test/QueryLoader/common/index.js +1 -0
- package/src/ui/test/QueryLoader/index.js +2 -0
- package/src/ui/test/index.js +1 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.0.12 */
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { useState, useLayoutEffect } from 'react';
|
|
4
|
+
import { useRelayEnvironment, fetchQuery } from 'react-relay';
|
|
5
|
+
import PropTypes from 'prop-types';
|
|
6
|
+
import styleNames from '@pareto-engineering/bem'; // Local Definitions
|
|
7
|
+
|
|
8
|
+
import { MultipleCombobox, Combobox } from "./common";
|
|
9
|
+
const baseClassName = styleNames.base;
|
|
10
|
+
const componentClassName = 'query-combobox';
|
|
11
|
+
/**
|
|
12
|
+
* This is the component description.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const QueryCombobox = ({
|
|
16
|
+
id,
|
|
17
|
+
className: userClassName,
|
|
18
|
+
style,
|
|
19
|
+
query,
|
|
20
|
+
multiple,
|
|
21
|
+
name,
|
|
22
|
+
label,
|
|
23
|
+
color,
|
|
24
|
+
description,
|
|
25
|
+
disabled,
|
|
26
|
+
debounceMs,
|
|
27
|
+
graphQlNode,
|
|
28
|
+
searchVariable,
|
|
29
|
+
extraVariables,
|
|
30
|
+
optionsKeyMap,
|
|
31
|
+
setValue,
|
|
32
|
+
setError,
|
|
33
|
+
error // ...otherProps
|
|
34
|
+
|
|
35
|
+
}) => {
|
|
36
|
+
useLayoutEffect(() => {
|
|
37
|
+
import("./styles.scss");
|
|
38
|
+
}, []);
|
|
39
|
+
const environment = useRelayEnvironment();
|
|
40
|
+
const [isFetching, setIsFetching] = useState(false);
|
|
41
|
+
const [options, setOptions] = useState([]);
|
|
42
|
+
|
|
43
|
+
const fetchOptions = inputValue => {
|
|
44
|
+
if (isFetching) return;
|
|
45
|
+
fetchQuery(environment, query, {
|
|
46
|
+
[searchVariable]: inputValue,
|
|
47
|
+
...extraVariables
|
|
48
|
+
}).subscribe({
|
|
49
|
+
start: () => {
|
|
50
|
+
setIsFetching(true);
|
|
51
|
+
},
|
|
52
|
+
complete: () => {
|
|
53
|
+
setIsFetching(false);
|
|
54
|
+
},
|
|
55
|
+
error: theError => {
|
|
56
|
+
console.log(theError);
|
|
57
|
+
setIsFetching(false);
|
|
58
|
+
if (setError) setError(theError);
|
|
59
|
+
},
|
|
60
|
+
next: data => {
|
|
61
|
+
setOptions(data[graphQlNode].edges.map(({
|
|
62
|
+
node
|
|
63
|
+
}) => ({
|
|
64
|
+
value: node[optionsKeyMap.value],
|
|
65
|
+
label: node[optionsKeyMap.label]
|
|
66
|
+
})));
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const comboboxProps = {
|
|
72
|
+
options,
|
|
73
|
+
fetchOptions,
|
|
74
|
+
debounceMs,
|
|
75
|
+
disabled,
|
|
76
|
+
name,
|
|
77
|
+
label,
|
|
78
|
+
description,
|
|
79
|
+
setValue,
|
|
80
|
+
error
|
|
81
|
+
};
|
|
82
|
+
const Component = multiple ? MultipleCombobox : Combobox;
|
|
83
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
84
|
+
id: id,
|
|
85
|
+
className: [baseClassName, componentClassName, userClassName, `y-${color}`].filter(e => e).join(' '),
|
|
86
|
+
style: style // {...otherProps}
|
|
87
|
+
|
|
88
|
+
}, /*#__PURE__*/React.createElement(Component, comboboxProps));
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
QueryCombobox.propTypes = {
|
|
92
|
+
/**
|
|
93
|
+
* The HTML id for this element
|
|
94
|
+
*/
|
|
95
|
+
id: PropTypes.string,
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The HTML class names for this element
|
|
99
|
+
*/
|
|
100
|
+
className: PropTypes.string,
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The React-written, css properties for this element.
|
|
104
|
+
*/
|
|
105
|
+
style: PropTypes.objectOf(PropTypes.string),
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The name of the custom select input
|
|
109
|
+
*/
|
|
110
|
+
name: PropTypes.string,
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The label of the custom select input
|
|
114
|
+
*/
|
|
115
|
+
label: PropTypes.string,
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The input field validator function
|
|
119
|
+
*/
|
|
120
|
+
validate: PropTypes.func,
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The custom select input description
|
|
124
|
+
*/
|
|
125
|
+
description: PropTypes.string,
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Whether the input should be disabled
|
|
129
|
+
*/
|
|
130
|
+
disabled: PropTypes.bool,
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* The base color of the custom select input
|
|
134
|
+
*/
|
|
135
|
+
color: PropTypes.string,
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The debounce time in milliseconds
|
|
139
|
+
*/
|
|
140
|
+
debounceMs: PropTypes.number,
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* The query to fetch the options
|
|
144
|
+
*/
|
|
145
|
+
query: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The extra variables required to be used in the query.
|
|
149
|
+
*/
|
|
150
|
+
extraVariables: PropTypes.objectOf(PropTypes.string),
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* The select option keys to be used to map the data to the select options.
|
|
154
|
+
* i.e `{ value: 'id', label: 'name' }`
|
|
155
|
+
*/
|
|
156
|
+
optionsKeyMap: PropTypes.shape({
|
|
157
|
+
value: PropTypes.string.isRequired,
|
|
158
|
+
label: PropTypes.string.isRequired
|
|
159
|
+
}).isRequired,
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Whether to allow multiple items selection
|
|
163
|
+
*/
|
|
164
|
+
multiple: PropTypes.bool,
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* The graphql node to be used to destructure the fetched data
|
|
168
|
+
*/
|
|
169
|
+
graphQlNode: PropTypes.string.isRequired,
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* The variable to be used to search the data
|
|
173
|
+
*/
|
|
174
|
+
searchVariable: PropTypes.string,
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* The function to be called when the value changes
|
|
178
|
+
*/
|
|
179
|
+
setValue: PropTypes.func.isRequired,
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* The function to be called with an error when the it occurs
|
|
183
|
+
*/
|
|
184
|
+
setError: PropTypes.func,
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* The error object
|
|
188
|
+
*/
|
|
189
|
+
error: PropTypes.objectOf(PropTypes.string)
|
|
190
|
+
};
|
|
191
|
+
QueryCombobox.defaultProps = {
|
|
192
|
+
extraVariables: {},
|
|
193
|
+
multiple: false,
|
|
194
|
+
color: 'background2',
|
|
195
|
+
searchVariable: 'search'
|
|
196
|
+
};
|
|
197
|
+
export default QueryCombobox;
|
|
@@ -0,0 +1,129 @@
|
|
|
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 } 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 "../../../.."; // Local Definitions
|
|
10
|
+
|
|
11
|
+
import { Menu } from "../Menu";
|
|
12
|
+
const baseClassName = styleNames.base;
|
|
13
|
+
const componentClassName = 'combobox';
|
|
14
|
+
/**
|
|
15
|
+
* This is the component description.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const Combobox = ({
|
|
19
|
+
id,
|
|
20
|
+
className: userClassName,
|
|
21
|
+
style,
|
|
22
|
+
label,
|
|
23
|
+
name,
|
|
24
|
+
options: items,
|
|
25
|
+
fetchOptions,
|
|
26
|
+
setValue,
|
|
27
|
+
error,
|
|
28
|
+
description // ...otherProps
|
|
29
|
+
|
|
30
|
+
}) => {
|
|
31
|
+
const {
|
|
32
|
+
isOpen,
|
|
33
|
+
selectedItem,
|
|
34
|
+
getLabelProps,
|
|
35
|
+
getMenuProps,
|
|
36
|
+
getInputProps,
|
|
37
|
+
highlightedIndex,
|
|
38
|
+
getComboboxProps,
|
|
39
|
+
getItemProps
|
|
40
|
+
} = useCombobox({
|
|
41
|
+
items,
|
|
42
|
+
itemToString: item => item ? item.label : '',
|
|
43
|
+
onInputValueChange: ({
|
|
44
|
+
inputValue
|
|
45
|
+
}) => {
|
|
46
|
+
fetchOptions(inputValue);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (selectedItem) {
|
|
51
|
+
setValue(selectedItem.value);
|
|
52
|
+
}
|
|
53
|
+
}, [selectedItem]);
|
|
54
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
55
|
+
id: id,
|
|
56
|
+
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
|
|
57
|
+
style: style
|
|
58
|
+
}, /*#__PURE__*/React.createElement(FormLabel, _extends({}, getLabelProps(), {
|
|
59
|
+
className: "input-label",
|
|
60
|
+
name: name
|
|
61
|
+
}), label), /*#__PURE__*/React.createElement("div", getComboboxProps(), /*#__PURE__*/React.createElement("input", _extends({}, getInputProps(), {
|
|
62
|
+
className: "input"
|
|
63
|
+
}))), /*#__PURE__*/React.createElement(Menu, _extends({
|
|
64
|
+
isOpen: isOpen,
|
|
65
|
+
getItemProps: getItemProps,
|
|
66
|
+
highlightedIndex: highlightedIndex,
|
|
67
|
+
items: items
|
|
68
|
+
}, getMenuProps())), (description || error) && /*#__PURE__*/React.createElement(FormDescription, {
|
|
69
|
+
isError: !!error
|
|
70
|
+
}, error || description));
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
Combobox.propTypes = {
|
|
74
|
+
/**
|
|
75
|
+
* The HTML id for this element
|
|
76
|
+
*/
|
|
77
|
+
id: PropTypes.string,
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* The HTML class names for this element
|
|
81
|
+
*/
|
|
82
|
+
className: PropTypes.string,
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The React-written, css properties for this element.
|
|
86
|
+
*/
|
|
87
|
+
style: PropTypes.objectOf(PropTypes.string),
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The label of the custom select input
|
|
91
|
+
*/
|
|
92
|
+
label: PropTypes.string,
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The custom select input options from the backend
|
|
96
|
+
*/
|
|
97
|
+
options: PropTypes.arrayOf(PropTypes.shape({
|
|
98
|
+
value: PropTypes.string,
|
|
99
|
+
label: PropTypes.string
|
|
100
|
+
})),
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The name of the custom select input
|
|
104
|
+
*/
|
|
105
|
+
name: PropTypes.string,
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The function to fetch the options from the backend
|
|
109
|
+
*/
|
|
110
|
+
fetchOptions: PropTypes.func,
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The function to set the value of the custom select input
|
|
114
|
+
*/
|
|
115
|
+
setValue: PropTypes.func.isRequired,
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The custom select input description
|
|
119
|
+
*/
|
|
120
|
+
description: PropTypes.string,
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The error object
|
|
124
|
+
*/
|
|
125
|
+
error: PropTypes.objectOf(PropTypes.string)
|
|
126
|
+
};
|
|
127
|
+
Combobox.defaultProps = {// someProp:false
|
|
128
|
+
};
|
|
129
|
+
export default 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 : ''}`
|
|
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,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,65 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.0.12 */
|
|
2
|
+
|
|
3
|
+
@use "@pareto-engineering/bem";
|
|
4
|
+
|
|
5
|
+
$default-input-padding: .75em .75em .55em;
|
|
6
|
+
$default-padding: 1em;
|
|
7
|
+
$default-margin: 1em;
|
|
8
|
+
|
|
9
|
+
.#{bem.$base}.query-combobox {
|
|
10
|
+
.input {
|
|
11
|
+
background: var(--light-y);
|
|
12
|
+
border: var(--theme-border-style) var(--dark-y);
|
|
13
|
+
color: var(--on-y);
|
|
14
|
+
padding: $default-input-padding;
|
|
15
|
+
width: 100%;
|
|
16
|
+
|
|
17
|
+
&::placeholder {
|
|
18
|
+
color: var(--metadata);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
&:not(:disabled):hover {
|
|
22
|
+
border: var(--theme-border-style) var(--light-background4);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
&:disabled {
|
|
26
|
+
background-color: var(--dark-y);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&:focus {
|
|
30
|
+
background: var(--light-background4);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.menu {
|
|
35
|
+
list-style: none;
|
|
36
|
+
margin: 0;
|
|
37
|
+
outline: 0;
|
|
38
|
+
padding: 0;
|
|
39
|
+
|
|
40
|
+
/* stylelint-disable selector-max-universal -- Allow */
|
|
41
|
+
>* {
|
|
42
|
+
padding-block: $default-padding / 2;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* stylelint-enable selector-max-universal */
|
|
46
|
+
>.item {
|
|
47
|
+
&.#{bem.$modifier-active} {
|
|
48
|
+
background-color: var(--background2);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.multiple-combobox {
|
|
54
|
+
.selected-items {
|
|
55
|
+
display: flex;
|
|
56
|
+
|
|
57
|
+
/* stylelint-disable selector-max-universal -- Allow */
|
|
58
|
+
>*:not(:first-child) {
|
|
59
|
+
margin-left: $default-margin;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* stylelint-enable selector-max-universal */
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|