@pareto-engineering/design-system 2.0.0-alpha.46 → 2.0.0-alpha.49
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/dist/cjs/f/FormInput/FormInput.js +7 -0
- package/dist/cjs/f/fields/QueryCombobox/QueryCombobox.js +33 -11
- package/dist/cjs/f/fields/QueryCombobox/common/Combobox/Combobox.js +20 -9
- package/dist/cjs/f/fields/QueryCombobox/common/MultipleCombobox/MultipleCombobox.js +40 -17
- package/dist/cjs/f/fields/QueryCombobox/common/index.js +9 -1
- package/dist/cjs/f/fields/QueryCombobox/styles.scss +11 -5
- package/dist/cjs/f/fields/QuerySelect/QuerySelect.js +201 -0
- package/dist/cjs/f/fields/QuerySelect/index.js +15 -0
- package/dist/cjs/f/fields/QuerySelect/styles.scss +21 -0
- package/dist/cjs/f/fields/SelectInput/SelectInput.js +15 -3
- package/dist/cjs/f/fields/SelectInput/styles.scss +27 -14
- package/dist/cjs/f/fields/index.js +9 -1
- package/dist/es/f/FormInput/FormInput.js +8 -1
- package/dist/es/f/fields/QueryCombobox/QueryCombobox.js +34 -12
- package/dist/es/f/fields/QueryCombobox/common/Combobox/Combobox.js +20 -9
- package/dist/es/f/fields/QueryCombobox/common/MultipleCombobox/MultipleCombobox.js +40 -17
- package/dist/es/f/fields/QueryCombobox/common/index.js +2 -1
- package/dist/es/f/fields/QueryCombobox/styles.scss +11 -5
- package/dist/es/f/fields/QuerySelect/QuerySelect.js +179 -0
- package/dist/es/f/fields/QuerySelect/index.js +2 -0
- package/dist/es/f/fields/QuerySelect/styles.scss +21 -0
- package/dist/es/f/fields/SelectInput/SelectInput.js +14 -3
- package/dist/es/f/fields/SelectInput/styles.scss +27 -14
- package/dist/es/f/fields/index.js +2 -1
- package/package.json +2 -2
- package/src/__snapshots__/Storyshots.test.js.snap +783 -237
- package/src/local.scss +3 -3
- package/src/stories/f/FormInput.stories.jsx +122 -4
- package/src/stories/f/QueryCombobox.stories.jsx +59 -10
- package/src/stories/f/QuerySelect.stories.jsx +134 -0
- package/src/stories/f/__generated__/FormInputAllTaskStatusesQuery.graphql.js +122 -0
- package/src/stories/f/__generated__/QuerySelectAllTaskStatusesQuery.graphql.js +122 -0
- package/src/ui/f/FormInput/FormInput.jsx +10 -0
- package/src/ui/f/fields/QueryCombobox/QueryCombobox.jsx +34 -14
- package/src/ui/f/fields/QueryCombobox/common/Combobox/Combobox.jsx +15 -7
- package/src/ui/f/fields/QueryCombobox/common/MultipleCombobox/MultipleCombobox.jsx +318 -0
- package/src/ui/f/fields/QueryCombobox/common/MultipleCombobox/index.js +2 -0
- package/src/ui/f/fields/QueryCombobox/common/index.js +1 -0
- package/src/ui/f/fields/QueryCombobox/styles.scss +11 -5
- package/src/ui/f/fields/QuerySelect/QuerySelect.jsx +200 -0
- package/src/ui/f/fields/QuerySelect/index.js +2 -0
- package/src/ui/f/fields/SelectInput/SelectInput.jsx +16 -3
- package/src/ui/f/fields/SelectInput/styles.scss +27 -14
- package/src/ui/f/fields/index.js +1 -0
|
@@ -11,7 +11,7 @@ import PropTypes from 'prop-types'
|
|
|
11
11
|
|
|
12
12
|
// Local Definitions
|
|
13
13
|
|
|
14
|
-
import { Combobox } from './common'
|
|
14
|
+
import { Combobox, MultipleCombobox } from './common'
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* This is the component description.
|
|
@@ -21,17 +21,18 @@ const QueryCombobox = ({
|
|
|
21
21
|
style,
|
|
22
22
|
className,
|
|
23
23
|
query,
|
|
24
|
-
|
|
24
|
+
multiple,
|
|
25
25
|
name,
|
|
26
26
|
label,
|
|
27
27
|
color,
|
|
28
28
|
description,
|
|
29
29
|
disabled,
|
|
30
30
|
debounceMs,
|
|
31
|
-
graphQlNode,
|
|
32
31
|
searchVariable,
|
|
33
32
|
extraVariables,
|
|
34
33
|
optionsKeyMap,
|
|
34
|
+
minLength,
|
|
35
|
+
transformSearch,
|
|
35
36
|
// ...otherProps
|
|
36
37
|
}) => {
|
|
37
38
|
useLayoutEffect(() => {
|
|
@@ -50,6 +51,8 @@ const QueryCombobox = ({
|
|
|
50
51
|
|
|
51
52
|
const [options, setOptions] = useState([])
|
|
52
53
|
|
|
54
|
+
const { graphql, accessor } = query
|
|
55
|
+
|
|
53
56
|
const getOptions = (inputValue) => {
|
|
54
57
|
if (isFetching) return
|
|
55
58
|
|
|
@@ -64,7 +67,7 @@ const QueryCombobox = ({
|
|
|
64
67
|
|
|
65
68
|
fetchQuery(
|
|
66
69
|
environment,
|
|
67
|
-
|
|
70
|
+
graphql,
|
|
68
71
|
variables,
|
|
69
72
|
)
|
|
70
73
|
.subscribe({
|
|
@@ -79,7 +82,7 @@ const QueryCombobox = ({
|
|
|
79
82
|
if (setError)setError(fetchError.message)
|
|
80
83
|
},
|
|
81
84
|
next:(data) => {
|
|
82
|
-
setOptions(data[
|
|
85
|
+
setOptions(data[accessor].edges.map(({ node }) => ({
|
|
83
86
|
value:node[optionsKeyMap.value],
|
|
84
87
|
label:node[optionsKeyMap.label],
|
|
85
88
|
})))
|
|
@@ -103,9 +106,11 @@ const QueryCombobox = ({
|
|
|
103
106
|
color,
|
|
104
107
|
isFetching,
|
|
105
108
|
className,
|
|
109
|
+
minLength,
|
|
110
|
+
transformSearch,
|
|
106
111
|
}
|
|
107
112
|
|
|
108
|
-
const Input = Combobox
|
|
113
|
+
const Input = multiple ? MultipleCombobox : Combobox
|
|
109
114
|
|
|
110
115
|
return <Input {...comboboxProps} />
|
|
111
116
|
}
|
|
@@ -157,12 +162,15 @@ QueryCombobox.propTypes = {
|
|
|
157
162
|
debounceMs:PropTypes.number,
|
|
158
163
|
|
|
159
164
|
/**
|
|
160
|
-
* The query to fetch the options
|
|
165
|
+
* The graphql query to fetch the options and the accessor to destructure the results from
|
|
161
166
|
*/
|
|
162
|
-
query:PropTypes.
|
|
163
|
-
PropTypes.string,
|
|
164
|
-
PropTypes.
|
|
165
|
-
|
|
167
|
+
query:PropTypes.shape({
|
|
168
|
+
accessor:PropTypes.string,
|
|
169
|
+
graphql :PropTypes.oneOfType([
|
|
170
|
+
PropTypes.string,
|
|
171
|
+
PropTypes.object,
|
|
172
|
+
]).isRequired,
|
|
173
|
+
}),
|
|
166
174
|
|
|
167
175
|
/**
|
|
168
176
|
* The extra variables required to be used in the query.
|
|
@@ -192,6 +200,16 @@ QueryCombobox.propTypes = {
|
|
|
192
200
|
* The variable to be used to search the data
|
|
193
201
|
*/
|
|
194
202
|
searchVariable:PropTypes.string,
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* The minimum length of the search input to start fetching the options
|
|
206
|
+
*/
|
|
207
|
+
minLength:PropTypes.number,
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* The function to transform the search input
|
|
211
|
+
*/
|
|
212
|
+
transformSearch:PropTypes.func,
|
|
195
213
|
}
|
|
196
214
|
|
|
197
215
|
QueryCombobox.defaultProps = {
|
|
@@ -199,9 +217,11 @@ QueryCombobox.defaultProps = {
|
|
|
199
217
|
value:'id',
|
|
200
218
|
label:'name',
|
|
201
219
|
},
|
|
202
|
-
multiple
|
|
203
|
-
color
|
|
204
|
-
searchVariable:'search',
|
|
220
|
+
multiple :false,
|
|
221
|
+
color :'background2',
|
|
222
|
+
searchVariable :'search',
|
|
223
|
+
transformSearch:(search) => search,
|
|
224
|
+
minLength :2,
|
|
205
225
|
}
|
|
206
226
|
|
|
207
227
|
export default QueryCombobox
|
|
@@ -37,8 +37,9 @@ const Combobox = ({
|
|
|
37
37
|
description,
|
|
38
38
|
value,
|
|
39
39
|
color,
|
|
40
|
-
|
|
40
|
+
minLength,
|
|
41
41
|
isFetching,
|
|
42
|
+
transformSearch,
|
|
42
43
|
// ...otherProps
|
|
43
44
|
}) => {
|
|
44
45
|
const {
|
|
@@ -56,7 +57,10 @@ const Combobox = ({
|
|
|
56
57
|
initialSelectedItem:value,
|
|
57
58
|
itemToString :(item) => (item ? item.label : ''),
|
|
58
59
|
onInputValueChange :({ inputValue }) => {
|
|
59
|
-
|
|
60
|
+
const transformedInput = transformSearch(inputValue)
|
|
61
|
+
if (transformedInput.length > minLength) {
|
|
62
|
+
getOptions(transformedInput)
|
|
63
|
+
}
|
|
60
64
|
},
|
|
61
65
|
})
|
|
62
66
|
|
|
@@ -87,7 +91,6 @@ const Combobox = ({
|
|
|
87
91
|
componentClassName,
|
|
88
92
|
userClassName,
|
|
89
93
|
`y-${color}`,
|
|
90
|
-
`x-${loadingCircleColor}`,
|
|
91
94
|
]
|
|
92
95
|
.filter((e) => e)
|
|
93
96
|
.join(' ')}
|
|
@@ -101,7 +104,7 @@ const Combobox = ({
|
|
|
101
104
|
<div {...getComboboxProps()} className="input-wrapper">
|
|
102
105
|
<input {...getInputProps()} className="input" />
|
|
103
106
|
{isFetching && (
|
|
104
|
-
<LoadingCircle />
|
|
107
|
+
<LoadingCircle className="x-main2" />
|
|
105
108
|
)}
|
|
106
109
|
</div>
|
|
107
110
|
|
|
@@ -202,13 +205,18 @@ Combobox.propTypes = {
|
|
|
202
205
|
isFetching:PropTypes.bool.isRequired,
|
|
203
206
|
|
|
204
207
|
/**
|
|
205
|
-
* The
|
|
208
|
+
* The minimum length of the search input to start fetching the options
|
|
206
209
|
*/
|
|
207
|
-
|
|
210
|
+
minLength:PropTypes.number,
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* The function to transform the search input
|
|
214
|
+
*/
|
|
215
|
+
transformSearch:PropTypes.func,
|
|
208
216
|
}
|
|
209
217
|
|
|
210
218
|
Combobox.defaultProps = {
|
|
211
|
-
|
|
219
|
+
// someProp: false
|
|
212
220
|
}
|
|
213
221
|
|
|
214
222
|
export default Combobox
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.0.12 */
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
|
|
4
|
+
import { useState, useEffect, useRef } from 'react'
|
|
5
|
+
|
|
6
|
+
import PropTypes from 'prop-types'
|
|
7
|
+
|
|
8
|
+
import styleNames from '@pareto-engineering/bem'
|
|
9
|
+
|
|
10
|
+
import { useCombobox, useMultipleSelection } from 'downshift'
|
|
11
|
+
|
|
12
|
+
import { Button } from 'ui/b'
|
|
13
|
+
|
|
14
|
+
import { Popover, LoadingCircle } from 'ui/a'
|
|
15
|
+
|
|
16
|
+
import { FormDescription, FormLabel } from 'ui/f'
|
|
17
|
+
|
|
18
|
+
// Local Definitions
|
|
19
|
+
|
|
20
|
+
import { Menu } from '../Menu'
|
|
21
|
+
|
|
22
|
+
const baseClassName = styleNames.base
|
|
23
|
+
|
|
24
|
+
const componentClassName = 'multiple-combobox'
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {Array[Object]} first - first array to check if it has an item not in the second array.
|
|
28
|
+
* @param {Array[Object]} second - second array to check against the first array.
|
|
29
|
+
*
|
|
30
|
+
* @returns {Boolean} - true if the first array has an item not in the second array.
|
|
31
|
+
*/
|
|
32
|
+
const testIfArraysAreUnique = (first, second) => first
|
|
33
|
+
.filter((objInFirstArray) => !second
|
|
34
|
+
.some((objInSecondArray) => objInFirstArray.value === objInSecondArray.value))
|
|
35
|
+
.length > 0
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* This is the component description.
|
|
39
|
+
*/
|
|
40
|
+
const MultipleCombobox = ({
|
|
41
|
+
id,
|
|
42
|
+
className:userClassName,
|
|
43
|
+
style,
|
|
44
|
+
label,
|
|
45
|
+
name,
|
|
46
|
+
options:items,
|
|
47
|
+
getOptions,
|
|
48
|
+
setValue,
|
|
49
|
+
error,
|
|
50
|
+
description,
|
|
51
|
+
value,
|
|
52
|
+
color,
|
|
53
|
+
isFetching,
|
|
54
|
+
minLength,
|
|
55
|
+
transformSearch,
|
|
56
|
+
// ...otherProps
|
|
57
|
+
}) => {
|
|
58
|
+
const [searchInputValue, setSearchInputValue] = useState('')
|
|
59
|
+
const {
|
|
60
|
+
getSelectedItemProps,
|
|
61
|
+
getDropdownProps,
|
|
62
|
+
addSelectedItem,
|
|
63
|
+
removeSelectedItem,
|
|
64
|
+
setSelectedItems,
|
|
65
|
+
selectedItems,
|
|
66
|
+
} = useMultipleSelection({
|
|
67
|
+
initialSelectedItems:value || [],
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @returns {Boolean} - Unique items from the options array so that the combobox
|
|
72
|
+
* shows only the options that are not yet selected.
|
|
73
|
+
*/
|
|
74
|
+
const getFilteredItems = () => items
|
|
75
|
+
.filter((item) => selectedItems
|
|
76
|
+
.findIndex((e) => e.label === item.label) < 0)
|
|
77
|
+
|
|
78
|
+
const {
|
|
79
|
+
isOpen,
|
|
80
|
+
getLabelProps,
|
|
81
|
+
getMenuProps,
|
|
82
|
+
getInputProps,
|
|
83
|
+
getComboboxProps,
|
|
84
|
+
highlightedIndex,
|
|
85
|
+
getItemProps,
|
|
86
|
+
} = useCombobox({
|
|
87
|
+
searchInputValue,
|
|
88
|
+
defaultHighlightedIndex:0, // after selection, highlight the first item.
|
|
89
|
+
selectedItem :null,
|
|
90
|
+
items :getFilteredItems(),
|
|
91
|
+
circularNavigation :true,
|
|
92
|
+
stateReducer :(state, actionAndChanges) => {
|
|
93
|
+
const { changes, type } = actionAndChanges
|
|
94
|
+
switch (type) {
|
|
95
|
+
case useCombobox.stateChangeTypes.InputKeyDownEnter:
|
|
96
|
+
case useCombobox.stateChangeTypes.ItemClick:
|
|
97
|
+
return {
|
|
98
|
+
...changes,
|
|
99
|
+
isOpen:true, // keep the menu open after selection.
|
|
100
|
+
}
|
|
101
|
+
default:
|
|
102
|
+
break
|
|
103
|
+
}
|
|
104
|
+
return changes
|
|
105
|
+
},
|
|
106
|
+
onStateChange:({ inputValue:newSearchInputValue, type, selectedItem }) => {
|
|
107
|
+
switch (type) {
|
|
108
|
+
case useCombobox.stateChangeTypes.InputChange: {
|
|
109
|
+
const transformedInput = transformSearch(newSearchInputValue)
|
|
110
|
+
if (transformedInput.length > minLength) {
|
|
111
|
+
getOptions(transformedInput)
|
|
112
|
+
}
|
|
113
|
+
setSearchInputValue(newSearchInputValue)
|
|
114
|
+
break
|
|
115
|
+
}
|
|
116
|
+
case useCombobox.stateChangeTypes.InputKeyDownEnter:
|
|
117
|
+
case useCombobox.stateChangeTypes.ItemClick:
|
|
118
|
+
case useCombobox.stateChangeTypes.InputBlur:
|
|
119
|
+
if (selectedItem) {
|
|
120
|
+
setSearchInputValue('')
|
|
121
|
+
addSelectedItem(selectedItem)
|
|
122
|
+
}
|
|
123
|
+
break
|
|
124
|
+
default:
|
|
125
|
+
break
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
if (selectedItems?.length > 0) {
|
|
132
|
+
setValue(selectedItems)
|
|
133
|
+
}
|
|
134
|
+
}, [selectedItems])
|
|
135
|
+
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
if (value?.length > 0 && (
|
|
138
|
+
testIfArraysAreUnique(value, selectedItems)
|
|
139
|
+
|| testIfArraysAreUnique(selectedItems, value)
|
|
140
|
+
)) {
|
|
141
|
+
setSelectedItems(value)
|
|
142
|
+
}
|
|
143
|
+
}, [value])
|
|
144
|
+
|
|
145
|
+
const parentRef = useRef(null)
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<div
|
|
149
|
+
id={id}
|
|
150
|
+
className={[
|
|
151
|
+
|
|
152
|
+
baseClassName,
|
|
153
|
+
|
|
154
|
+
componentClassName,
|
|
155
|
+
userClassName,
|
|
156
|
+
`y-${color}`,
|
|
157
|
+
]
|
|
158
|
+
.filter((e) => e)
|
|
159
|
+
.join(' ')}
|
|
160
|
+
style={style}
|
|
161
|
+
>
|
|
162
|
+
|
|
163
|
+
<FormLabel {...getLabelProps()} name={name}>
|
|
164
|
+
{label}
|
|
165
|
+
</FormLabel>
|
|
166
|
+
|
|
167
|
+
{selectedItems?.length > 0 && (
|
|
168
|
+
<div className="selected-items">
|
|
169
|
+
{selectedItems.map((selectedItem, index) => (
|
|
170
|
+
<div
|
|
171
|
+
key={selectedItem.label}
|
|
172
|
+
{...getSelectedItemProps({ selectedItem, index })}
|
|
173
|
+
className="item"
|
|
174
|
+
>
|
|
175
|
+
<Button
|
|
176
|
+
onClick={(e) => {
|
|
177
|
+
e.stopPropagation()
|
|
178
|
+
removeSelectedItem(selectedItem)
|
|
179
|
+
}}
|
|
180
|
+
isCompact
|
|
181
|
+
isSimple
|
|
182
|
+
color={color}
|
|
183
|
+
>
|
|
184
|
+
<span className="v25 mr-v">{selectedItem.label}</span>
|
|
185
|
+
<span className="f-icons close">Y</span>
|
|
186
|
+
</Button>
|
|
187
|
+
</div>
|
|
188
|
+
))}
|
|
189
|
+
</div>
|
|
190
|
+
)}
|
|
191
|
+
<div {...getComboboxProps()} className="input-wrapper">
|
|
192
|
+
<input
|
|
193
|
+
{...getInputProps(
|
|
194
|
+
getDropdownProps({ preventKeyAction: isOpen }),
|
|
195
|
+
)}
|
|
196
|
+
className="input"
|
|
197
|
+
/>
|
|
198
|
+
{isFetching && (
|
|
199
|
+
<LoadingCircle className="x-main2" />
|
|
200
|
+
)}
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
<Popover
|
|
204
|
+
isOpen={isOpen}
|
|
205
|
+
parentRef={parentRef}
|
|
206
|
+
>
|
|
207
|
+
<Menu
|
|
208
|
+
isOpen={isOpen}
|
|
209
|
+
getItemProps={getItemProps}
|
|
210
|
+
highlightedIndex={highlightedIndex}
|
|
211
|
+
items={getFilteredItems()}
|
|
212
|
+
{...getMenuProps()}
|
|
213
|
+
/>
|
|
214
|
+
</Popover>
|
|
215
|
+
|
|
216
|
+
{(description || error) && (
|
|
217
|
+
<FormDescription isError={!!error}>
|
|
218
|
+
{ error || description }
|
|
219
|
+
</FormDescription>
|
|
220
|
+
)}
|
|
221
|
+
|
|
222
|
+
</div>
|
|
223
|
+
)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
MultipleCombobox.propTypes = {
|
|
227
|
+
/**
|
|
228
|
+
* The HTML id for this element
|
|
229
|
+
*/
|
|
230
|
+
id:PropTypes.string,
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* The HTML class names for this element
|
|
234
|
+
*/
|
|
235
|
+
className:PropTypes.string,
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* The React-written, css properties for this element.
|
|
239
|
+
*/
|
|
240
|
+
style:PropTypes.objectOf(PropTypes.string),
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* The label of the custom select input
|
|
244
|
+
*/
|
|
245
|
+
label:PropTypes.string,
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* The custom select input options from the backend
|
|
249
|
+
*/
|
|
250
|
+
options:PropTypes.arrayOf(
|
|
251
|
+
PropTypes.shape({
|
|
252
|
+
value:PropTypes.string,
|
|
253
|
+
label:PropTypes.string,
|
|
254
|
+
}),
|
|
255
|
+
),
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* The name of the custom select input
|
|
259
|
+
*/
|
|
260
|
+
name:PropTypes.string,
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* The function to fetch the options from the backend
|
|
264
|
+
*/
|
|
265
|
+
getOptions:PropTypes.func,
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* The function to set the value of the custom select input
|
|
269
|
+
*/
|
|
270
|
+
setValue:PropTypes.func.isRequired,
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* The custom select input description
|
|
274
|
+
*/
|
|
275
|
+
description:PropTypes.string,
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* The error object
|
|
279
|
+
*/
|
|
280
|
+
error:PropTypes.objectOf(PropTypes.string),
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* The value of the custom select input
|
|
284
|
+
*/
|
|
285
|
+
value:PropTypes.arrayOf(
|
|
286
|
+
PropTypes.shape({
|
|
287
|
+
value:PropTypes.string,
|
|
288
|
+
label:PropTypes.string,
|
|
289
|
+
}),
|
|
290
|
+
),
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* The base color of the custom select input
|
|
294
|
+
*/
|
|
295
|
+
color:PropTypes.string,
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Whether the query getting the combobox options is inFlight
|
|
299
|
+
*/
|
|
300
|
+
isFetching:PropTypes.bool.isRequired,
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* The minimum length of the search input to start fetching the options
|
|
304
|
+
*/
|
|
305
|
+
minLength:PropTypes.number,
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* The function to transform the search input
|
|
309
|
+
*/
|
|
310
|
+
transformSearch:PropTypes.func,
|
|
311
|
+
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
MultipleCombobox.defaultProps = {
|
|
315
|
+
// someProp: false
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export default MultipleCombobox
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
$default-input-padding: .75em .75em .55em;
|
|
6
6
|
$default-padding: 1em;
|
|
7
7
|
$default-margin: 1em;
|
|
8
|
+
$default-gap: 1em;
|
|
8
9
|
$default-loading-circle-displacement: 1em;
|
|
9
10
|
|
|
10
11
|
.#{bem.$base}.combobox,
|
|
@@ -73,12 +74,17 @@ $default-loading-circle-displacement: 1em;
|
|
|
73
74
|
.#{bem.$base}.multiple-combobox {
|
|
74
75
|
>.selected-items {
|
|
75
76
|
display: flex;
|
|
77
|
+
gap: $default-gap / 2;
|
|
78
|
+
flex-wrap: wrap;
|
|
79
|
+
margin-bottom: $default-margin / 2;
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
+
>.item {
|
|
82
|
+
background-color: var(--main2);
|
|
83
|
+
padding: $default-padding / 4;
|
|
81
84
|
|
|
82
|
-
|
|
85
|
+
.close {
|
|
86
|
+
font-size: calc(var(--s-3) * 1em);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
83
89
|
}
|
|
84
90
|
}
|