@pareto-engineering/design-system 4.0.0-alpha.62 → 4.0.0-alpha.63

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 (192) hide show
  1. package/dist/cjs/f/FormInput/FormInput.js +43 -13
  2. package/dist/cjs/f/common/V2/Description/Description.js +76 -0
  3. package/dist/cjs/f/common/V2/Description/index.js +13 -0
  4. package/dist/cjs/f/common/V2/Description/styles.scss +10 -0
  5. package/dist/cjs/f/common/V2/Label/Label.js +84 -0
  6. package/dist/cjs/f/common/V2/Label/index.js +13 -0
  7. package/dist/cjs/f/common/V2/Label/styles.scss +9 -0
  8. package/dist/cjs/f/common/V2/index.js +19 -0
  9. package/dist/cjs/f/common/index.js +12 -0
  10. package/dist/cjs/f/fields/V2/Checkbox/Checkbox.js +122 -0
  11. package/dist/cjs/f/fields/V2/Checkbox/index.js +13 -0
  12. package/dist/cjs/f/fields/V2/Checkbox/styles.scss +16 -0
  13. package/dist/cjs/f/fields/V2/ChoicesInput/ChoicesInput.js +154 -0
  14. package/dist/cjs/f/fields/V2/ChoicesInput/common/Choice/Choice.js +104 -0
  15. package/dist/cjs/f/fields/V2/ChoicesInput/common/Choice/index.js +13 -0
  16. package/dist/cjs/f/fields/V2/ChoicesInput/common/index.js +12 -0
  17. package/dist/cjs/f/fields/V2/ChoicesInput/index.js +13 -0
  18. package/dist/cjs/f/fields/V2/ChoicesInput/styles.scss +79 -0
  19. package/dist/cjs/f/fields/V2/EditorInput/EditorInput.js +197 -0
  20. package/dist/cjs/f/fields/V2/EditorInput/common/Toolbar.js +257 -0
  21. package/dist/cjs/f/fields/V2/EditorInput/common/TreeViewPlugin.js +18 -0
  22. package/dist/cjs/f/fields/V2/EditorInput/common/index.js +20 -0
  23. package/dist/cjs/f/fields/V2/EditorInput/index.js +13 -0
  24. package/dist/cjs/f/fields/V2/EditorInput/styles.scss +149 -0
  25. package/dist/cjs/f/fields/V2/LinkInput/LinkInput.js +156 -0
  26. package/dist/cjs/f/fields/V2/LinkInput/index.js +13 -0
  27. package/dist/cjs/f/fields/V2/LinkInput/styles.scss +90 -0
  28. package/dist/cjs/f/fields/V2/QueryChoices/QueryChoices.js +137 -0
  29. package/dist/cjs/f/fields/V2/QueryChoices/index.js +13 -0
  30. package/dist/cjs/f/fields/V2/QueryCombobox/QueryCombobox.js +229 -0
  31. package/dist/cjs/f/fields/V2/QueryCombobox/common/Combobox/Combobox.js +236 -0
  32. package/dist/cjs/f/fields/V2/QueryCombobox/common/Combobox/index.js +13 -0
  33. package/dist/cjs/f/fields/V2/QueryCombobox/common/Menu/Menu.js +83 -0
  34. package/dist/cjs/f/fields/V2/QueryCombobox/common/Menu/index.js +13 -0
  35. package/dist/cjs/f/fields/V2/QueryCombobox/common/MultipleCombobox/MultipleCombobox.js +300 -0
  36. package/dist/cjs/f/fields/V2/QueryCombobox/common/MultipleCombobox/index.js +13 -0
  37. package/dist/cjs/f/fields/V2/QueryCombobox/common/index.js +26 -0
  38. package/dist/cjs/f/fields/V2/QueryCombobox/index.js +13 -0
  39. package/dist/cjs/f/fields/V2/QueryCombobox/styles.scss +127 -0
  40. package/dist/cjs/f/fields/V2/QuerySelect/QuerySelect.js +198 -0
  41. package/dist/cjs/f/fields/V2/QuerySelect/index.js +13 -0
  42. package/dist/cjs/f/fields/V2/RatingsInput/RatingsInput.js +130 -0
  43. package/dist/cjs/f/fields/V2/RatingsInput/common/Rating/Rating.js +117 -0
  44. package/dist/cjs/f/fields/V2/RatingsInput/common/Rating/index.js +13 -0
  45. package/dist/cjs/f/fields/V2/RatingsInput/common/index.js +12 -0
  46. package/dist/cjs/f/fields/V2/RatingsInput/index.js +13 -0
  47. package/dist/cjs/f/fields/V2/RatingsInput/styles.scss +48 -0
  48. package/dist/cjs/f/fields/V2/SelectInput/SelectInput.js +154 -0
  49. package/dist/cjs/f/fields/V2/SelectInput/index.js +13 -0
  50. package/dist/cjs/f/fields/V2/SelectInput/styles.scss +87 -0
  51. package/dist/cjs/f/fields/V2/TextInput/TextInput.js +155 -0
  52. package/dist/cjs/f/fields/V2/TextInput/index.js +13 -0
  53. package/dist/cjs/f/fields/V2/TextInput/styles.scss +78 -0
  54. package/dist/cjs/f/fields/V2/TextareaInput/TextareaInput.js +152 -0
  55. package/dist/cjs/f/fields/V2/TextareaInput/index.js +13 -0
  56. package/dist/cjs/f/fields/V2/TextareaInput/styles.scss +53 -0
  57. package/dist/cjs/f/fields/V2/index.js +82 -0
  58. package/dist/cjs/f/fields/index.js +26 -1
  59. package/dist/es/f/FormInput/FormInput.js +33 -3
  60. package/dist/es/f/common/V2/Description/Description.js +68 -0
  61. package/dist/es/f/common/V2/Description/index.js +2 -0
  62. package/dist/es/f/common/V2/Description/styles.scss +10 -0
  63. package/dist/es/f/common/V2/Label/Label.js +76 -0
  64. package/dist/es/f/common/V2/Label/index.js +2 -0
  65. package/dist/es/f/common/V2/Label/styles.scss +9 -0
  66. package/dist/es/f/common/V2/index.js +2 -0
  67. package/dist/es/f/common/index.js +2 -1
  68. package/dist/es/f/fields/V2/Checkbox/Checkbox.js +114 -0
  69. package/dist/es/f/fields/V2/Checkbox/index.js +2 -0
  70. package/dist/es/f/fields/V2/Checkbox/styles.scss +16 -0
  71. package/dist/es/f/fields/V2/ChoicesInput/ChoicesInput.js +148 -0
  72. package/dist/es/f/fields/V2/ChoicesInput/common/Choice/Choice.js +97 -0
  73. package/dist/es/f/fields/V2/ChoicesInput/common/Choice/index.js +2 -0
  74. package/dist/es/f/fields/V2/ChoicesInput/common/index.js +1 -0
  75. package/dist/es/f/fields/V2/ChoicesInput/index.js +2 -0
  76. package/dist/es/f/fields/V2/ChoicesInput/styles.scss +79 -0
  77. package/dist/es/f/fields/V2/EditorInput/EditorInput.js +192 -0
  78. package/dist/es/f/fields/V2/EditorInput/common/Toolbar.js +246 -0
  79. package/dist/es/f/fields/V2/EditorInput/common/TreeViewPlugin.js +11 -0
  80. package/dist/es/f/fields/V2/EditorInput/common/index.js +2 -0
  81. package/dist/es/f/fields/V2/EditorInput/index.js +2 -0
  82. package/dist/es/f/fields/V2/EditorInput/styles.scss +149 -0
  83. package/dist/es/f/fields/V2/LinkInput/LinkInput.js +148 -0
  84. package/dist/es/f/fields/V2/LinkInput/index.js +2 -0
  85. package/dist/es/f/fields/V2/LinkInput/styles.scss +90 -0
  86. package/dist/es/f/fields/V2/QueryChoices/QueryChoices.js +126 -0
  87. package/dist/es/f/fields/V2/QueryChoices/index.js +2 -0
  88. package/dist/es/f/fields/V2/QueryCombobox/QueryCombobox.js +221 -0
  89. package/dist/es/f/fields/V2/QueryCombobox/common/Combobox/Combobox.js +229 -0
  90. package/dist/es/f/fields/V2/QueryCombobox/common/Combobox/index.js +2 -0
  91. package/dist/es/f/fields/V2/QueryCombobox/common/Menu/Menu.js +73 -0
  92. package/dist/es/f/fields/V2/QueryCombobox/common/Menu/index.js +2 -0
  93. package/dist/es/f/fields/V2/QueryCombobox/common/MultipleCombobox/MultipleCombobox.js +293 -0
  94. package/dist/es/f/fields/V2/QueryCombobox/common/MultipleCombobox/index.js +2 -0
  95. package/dist/es/f/fields/V2/QueryCombobox/common/index.js +3 -0
  96. package/dist/es/f/fields/V2/QueryCombobox/index.js +2 -0
  97. package/dist/es/f/fields/V2/QueryCombobox/styles.scss +127 -0
  98. package/dist/es/f/fields/V2/QuerySelect/QuerySelect.js +186 -0
  99. package/dist/es/f/fields/V2/QuerySelect/index.js +2 -0
  100. package/dist/es/f/fields/V2/RatingsInput/RatingsInput.js +124 -0
  101. package/dist/es/f/fields/V2/RatingsInput/common/Rating/Rating.js +109 -0
  102. package/dist/es/f/fields/V2/RatingsInput/common/Rating/index.js +2 -0
  103. package/dist/es/f/fields/V2/RatingsInput/common/index.js +1 -0
  104. package/dist/es/f/fields/V2/RatingsInput/index.js +2 -0
  105. package/dist/es/f/fields/V2/RatingsInput/styles.scss +48 -0
  106. package/dist/es/f/fields/V2/SelectInput/SelectInput.js +146 -0
  107. package/dist/es/f/fields/V2/SelectInput/index.js +2 -0
  108. package/dist/es/f/fields/V2/SelectInput/styles.scss +87 -0
  109. package/dist/es/f/fields/V2/TextInput/TextInput.js +147 -0
  110. package/dist/es/f/fields/V2/TextInput/index.js +2 -0
  111. package/dist/es/f/fields/V2/TextInput/styles.scss +78 -0
  112. package/dist/es/f/fields/V2/TextareaInput/TextareaInput.js +146 -0
  113. package/dist/es/f/fields/V2/TextareaInput/index.js +2 -0
  114. package/dist/es/f/fields/V2/TextareaInput/styles.scss +53 -0
  115. package/dist/es/f/fields/V2/index.js +11 -0
  116. package/dist/es/f/fields/index.js +2 -1
  117. package/package.json +3 -3
  118. package/src/stories/f/v2/Checkbox.stories.jsx +102 -0
  119. package/src/stories/f/v2/ChoicesInput.stories.jsx +139 -0
  120. package/src/stories/f/v2/EditorInput.stories.jsx +81 -0
  121. package/src/stories/f/v2/LinkInput.stories.jsx +93 -0
  122. package/src/stories/f/v2/QueryChoices.stories.jsx +144 -0
  123. package/src/stories/f/v2/QueryCombobox.stories.jsx +301 -0
  124. package/src/stories/f/v2/QuerySelect.stories.jsx +150 -0
  125. package/src/stories/f/v2/RatingsInput.stories.jsx +77 -0
  126. package/src/stories/f/v2/SelectInput.stories.jsx +95 -0
  127. package/src/stories/f/v2/TextInput.stories.jsx +120 -0
  128. package/src/stories/f/v2/TextareaInput.stories.jsx +107 -0
  129. package/src/stories/f/v2/__generated__/FormInputAllTaskStatusesQuery.graphql.js +122 -0
  130. package/src/stories/f/v2/__generated__/FormInputAllTeamsQuery.graphql.js +139 -0
  131. package/src/stories/f/v2/__generated__/QueryChoicesAllTaskStatusesQuery.graphql.js +122 -0
  132. package/src/stories/f/v2/__generated__/QueryComboboxAllTeamsQuery.graphql.js +139 -0
  133. package/src/stories/f/v2/__generated__/QuerySelectAllTaskStatusesQuery.graphql.js +122 -0
  134. package/src/ui/f/FormInput/FormInput.jsx +57 -12
  135. package/src/ui/f/common/V2/Description/Description.jsx +94 -0
  136. package/src/ui/f/common/V2/Description/index.js +2 -0
  137. package/src/ui/f/common/V2/Description/styles.scss +10 -0
  138. package/src/ui/f/common/V2/Label/Label.jsx +102 -0
  139. package/src/ui/f/common/V2/Label/index.js +2 -0
  140. package/src/ui/f/common/V2/Label/styles.scss +9 -0
  141. package/src/ui/f/common/V2/index.js +2 -0
  142. package/src/ui/f/common/index.js +1 -0
  143. package/src/ui/f/fields/V2/Checkbox/Checkbox.jsx +146 -0
  144. package/src/ui/f/fields/V2/Checkbox/index.js +2 -0
  145. package/src/ui/f/fields/V2/Checkbox/styles.scss +16 -0
  146. package/src/ui/f/fields/V2/ChoicesInput/ChoicesInput.jsx +183 -0
  147. package/src/ui/f/fields/V2/ChoicesInput/common/Choice/Choice.jsx +125 -0
  148. package/src/ui/f/fields/V2/ChoicesInput/common/Choice/index.js +2 -0
  149. package/src/ui/f/fields/V2/ChoicesInput/common/index.js +1 -0
  150. package/src/ui/f/fields/V2/ChoicesInput/index.js +2 -0
  151. package/src/ui/f/fields/V2/ChoicesInput/styles.scss +79 -0
  152. package/src/ui/f/fields/V2/EditorInput/EditorInput.jsx +244 -0
  153. package/src/ui/f/fields/V2/EditorInput/common/Toolbar.jsx +356 -0
  154. package/src/ui/f/fields/V2/EditorInput/common/TreeViewPlugin.jsx +16 -0
  155. package/src/ui/f/fields/V2/EditorInput/common/index.jsx +2 -0
  156. package/src/ui/f/fields/V2/EditorInput/index.js +2 -0
  157. package/src/ui/f/fields/V2/EditorInput/styles.scss +149 -0
  158. package/src/ui/f/fields/V2/LinkInput/LinkInput.jsx +187 -0
  159. package/src/ui/f/fields/V2/LinkInput/index.js +2 -0
  160. package/src/ui/f/fields/V2/LinkInput/styles.scss +90 -0
  161. package/src/ui/f/fields/V2/QueryChoices/QueryChoices.jsx +153 -0
  162. package/src/ui/f/fields/V2/QueryChoices/index.js +2 -0
  163. package/src/ui/f/fields/V2/QueryCombobox/QueryCombobox.jsx +254 -0
  164. package/src/ui/f/fields/V2/QueryCombobox/common/Combobox/Combobox.jsx +276 -0
  165. package/src/ui/f/fields/V2/QueryCombobox/common/Combobox/index.js +2 -0
  166. package/src/ui/f/fields/V2/QueryCombobox/common/Menu/Menu.jsx +103 -0
  167. package/src/ui/f/fields/V2/QueryCombobox/common/Menu/index.js +2 -0
  168. package/src/ui/f/fields/V2/QueryCombobox/common/MultipleCombobox/MultipleCombobox.jsx +362 -0
  169. package/src/ui/f/fields/V2/QueryCombobox/common/MultipleCombobox/index.js +2 -0
  170. package/src/ui/f/fields/V2/QueryCombobox/common/index.js +3 -0
  171. package/src/ui/f/fields/V2/QueryCombobox/index.js +2 -0
  172. package/src/ui/f/fields/V2/QueryCombobox/styles.scss +127 -0
  173. package/src/ui/f/fields/V2/QuerySelect/QuerySelect.jsx +220 -0
  174. package/src/ui/f/fields/V2/QuerySelect/index.js +2 -0
  175. package/src/ui/f/fields/V2/RatingsInput/RatingsInput.jsx +152 -0
  176. package/src/ui/f/fields/V2/RatingsInput/common/Rating/Rating.jsx +142 -0
  177. package/src/ui/f/fields/V2/RatingsInput/common/Rating/index.js +2 -0
  178. package/src/ui/f/fields/V2/RatingsInput/common/index.js +1 -0
  179. package/src/ui/f/fields/V2/RatingsInput/index.js +2 -0
  180. package/src/ui/f/fields/V2/RatingsInput/styles.scss +48 -0
  181. package/src/ui/f/fields/V2/SelectInput/SelectInput.jsx +187 -0
  182. package/src/ui/f/fields/V2/SelectInput/index.js +2 -0
  183. package/src/ui/f/fields/V2/SelectInput/styles.scss +87 -0
  184. package/src/ui/f/fields/V2/TextInput/TextInput.jsx +192 -0
  185. package/src/ui/f/fields/V2/TextInput/index.js +2 -0
  186. package/src/ui/f/fields/V2/TextInput/styles.scss +78 -0
  187. package/src/ui/f/fields/V2/TextareaInput/TextareaInput.jsx +180 -0
  188. package/src/ui/f/fields/V2/TextareaInput/index.js +2 -0
  189. package/src/ui/f/fields/V2/TextareaInput/styles.scss +53 -0
  190. package/src/ui/f/fields/V2/index.js +11 -0
  191. package/src/ui/f/fields/index.js +1 -0
  192. package/tests/__snapshots__/Storyshots.test.js.snap +5909 -0
@@ -0,0 +1,362 @@
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/exports'
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 { FormDescriptionV2, FormLabelV2 } from 'ui/f'
17
+
18
+ import { lookUpInputValueFromFetchedOptions } from '../../../../../common'
19
+
20
+ // Local Definitions
21
+
22
+ import { Menu } from '../Menu'
23
+
24
+ const baseClassName = styleNames.base
25
+
26
+ const componentClassName = 'multiple-combobox'
27
+
28
+ /**
29
+ * @param {Array[Object]} first - first array to check if it has an item not in the second array.
30
+ * @param {Array[Object]} second - second array to check against the first array.
31
+ *
32
+ * @returns {Boolean} - true if the first array has an item not in the second array.
33
+ */
34
+ const testIfArraysAreUnique = (first, second) => first
35
+ .filter((objInFirstArray) => !second
36
+ .some((objInSecondArray) => objInFirstArray.value === objInSecondArray.value))
37
+ .length > 0
38
+
39
+ /**
40
+ * This is the component description.
41
+ */
42
+ const MultipleCombobox = ({
43
+ id,
44
+ className:userClassName,
45
+ style,
46
+ label,
47
+ labelColor,
48
+ name,
49
+ optional,
50
+ options:items,
51
+ getOptions,
52
+ setValue,
53
+ description,
54
+ value,
55
+ color,
56
+ isFetching,
57
+ minLength,
58
+ transformSearch,
59
+ disabled,
60
+ placeholder,
61
+ setOptions,
62
+ promptCreateNewOption,
63
+ // ...otherProps
64
+ }) => {
65
+ const [searchInputValue, setSearchInputValue] = useState('')
66
+ const {
67
+ getSelectedItemProps,
68
+ getDropdownProps,
69
+ addSelectedItem,
70
+ removeSelectedItem,
71
+ setSelectedItems,
72
+ selectedItems,
73
+ } = useMultipleSelection({
74
+ initialSelectedItems:value || [],
75
+ })
76
+
77
+ /**
78
+ * @returns {Boolean} - Unique items from the options array so that the combobox
79
+ * shows only the options that are not yet selected.
80
+ */
81
+ const getFilteredItems = () => items
82
+ .filter((item) => selectedItems
83
+ .findIndex((e) => e.label === item.label) < 0)
84
+
85
+ const {
86
+ isOpen,
87
+ getLabelProps,
88
+ getMenuProps,
89
+ getInputProps,
90
+ getComboboxProps,
91
+ highlightedIndex,
92
+ getItemProps,
93
+ inputValue,
94
+ setInputValue,
95
+ } = useCombobox({
96
+ searchInputValue,
97
+ defaultHighlightedIndex:0, // after selection, highlight the first item.
98
+ selectedItem :null,
99
+ items :getFilteredItems(),
100
+ circularNavigation :true,
101
+ stateReducer :(state, actionAndChanges) => {
102
+ const { changes, type } = actionAndChanges
103
+ switch (type) {
104
+ case useCombobox.stateChangeTypes.InputKeyDownEnter:
105
+ case useCombobox.stateChangeTypes.ItemClick:
106
+ return {
107
+ ...changes,
108
+ isOpen:true, // keep the menu open after selection.
109
+ }
110
+ default:
111
+ break
112
+ }
113
+ return changes
114
+ },
115
+ onStateChange:({ inputValue:newSearchInputValue, type, selectedItem }) => {
116
+ switch (type) {
117
+ case useCombobox.stateChangeTypes.InputChange: {
118
+ const transformedInput = transformSearch(newSearchInputValue)
119
+ if (transformedInput.length > minLength) {
120
+ getOptions(transformedInput)
121
+ }
122
+ setSearchInputValue(newSearchInputValue)
123
+ break
124
+ }
125
+ case useCombobox.stateChangeTypes.InputKeyDownEnter:
126
+ case useCombobox.stateChangeTypes.ItemClick:
127
+ case useCombobox.stateChangeTypes.InputBlur:
128
+ if (selectedItem) {
129
+ setSearchInputValue('')
130
+ addSelectedItem(selectedItem)
131
+ }
132
+ break
133
+ default:
134
+ break
135
+ }
136
+ },
137
+ })
138
+
139
+ useEffect(() => {
140
+ if (selectedItems?.length > 0) {
141
+ setValue(selectedItems)
142
+ }
143
+ }, [selectedItems])
144
+
145
+ useEffect(() => {
146
+ if (promptCreateNewOption) {
147
+ lookUpInputValueFromFetchedOptions({
148
+ items, inputValue, setOptions, minLength,
149
+ })
150
+ }
151
+ }, [inputValue, items, promptCreateNewOption])
152
+
153
+ useEffect(() => {
154
+ if (value?.length > 0 && (
155
+ testIfArraysAreUnique(value, selectedItems)
156
+ || testIfArraysAreUnique(selectedItems, value)
157
+ )) {
158
+ setSelectedItems(value)
159
+ }
160
+ }, [value])
161
+
162
+ const parentRef = useRef(null)
163
+
164
+ const resetInputValue = () => setInputValue('')
165
+
166
+ return (
167
+ <div
168
+ id={id}
169
+ className={[
170
+ baseClassName,
171
+ componentClassName,
172
+ userClassName,
173
+ ]
174
+ .filter((e) => e)
175
+ .join(' ')}
176
+ style={style}
177
+ ref={parentRef}
178
+ {...getComboboxProps()}
179
+ >
180
+ <FormLabelV2
181
+ className={[
182
+ baseClassName,
183
+ componentClassName,
184
+ ]
185
+ .filter((e) => e)
186
+ .join(' ')}
187
+ {...getLabelProps()}
188
+ name={name}
189
+ optional={optional}
190
+ color={labelColor}
191
+ >
192
+ {label}
193
+ </FormLabelV2>
194
+
195
+ {selectedItems?.length > 0 && (
196
+ <div className="selected-items">
197
+ {selectedItems.map((selectedItem, index) => (
198
+ <div
199
+ key={selectedItem.label}
200
+ {...getSelectedItemProps({ selectedItem, index })}
201
+ className="item"
202
+ >
203
+ <Button
204
+ onClick={(e) => {
205
+ e.stopPropagation()
206
+ removeSelectedItem(selectedItem)
207
+ }}
208
+ isCompact
209
+ color={color}
210
+ >
211
+ <span>{selectedItem.label}</span>
212
+ <span className="icon close">Y</span>
213
+ </Button>
214
+ </div>
215
+ ))}
216
+ </div>
217
+ )}
218
+ <input
219
+ {...getInputProps(
220
+ getDropdownProps({ preventKeyAction: isOpen }),
221
+ )}
222
+ className="input"
223
+ disabled={disabled}
224
+ placeholder={placeholder}
225
+ />
226
+ {isFetching && (
227
+ <LoadingCircle className="x-main" />
228
+ )}
229
+ {inputValue.length > minLength && !isFetching && (
230
+ <Button
231
+ isSimple
232
+ isCompact
233
+ color="interactive"
234
+ onClick={resetInputValue}
235
+ >
236
+ <span className="icon">
237
+ Y
238
+ </span>
239
+ </Button>
240
+ )}
241
+
242
+ <FormDescriptionV2 className="s-1" description={description} name={name} />
243
+ <Popover
244
+ isOpen={isOpen}
245
+ parentRef={parentRef}
246
+ >
247
+ <Menu
248
+ className={`y-${color}`}
249
+ isOpen={isOpen}
250
+ getItemProps={getItemProps}
251
+ highlightedIndex={highlightedIndex}
252
+ items={getFilteredItems()}
253
+ {...getMenuProps()}
254
+ />
255
+ </Popover>
256
+
257
+ </div>
258
+ )
259
+ }
260
+
261
+ MultipleCombobox.propTypes = {
262
+ /**
263
+ * The HTML id for this element
264
+ */
265
+ id:PropTypes.string,
266
+
267
+ /**
268
+ * The HTML class names for this element
269
+ */
270
+ className:PropTypes.string,
271
+
272
+ /**
273
+ * The React-written, css properties for this element.
274
+ */
275
+ style:PropTypes.objectOf(PropTypes.string),
276
+
277
+ /**
278
+ * The label of the custom select input
279
+ */
280
+ label:PropTypes.string,
281
+
282
+ /**
283
+ * The custom select input options from the backend
284
+ */
285
+ options:PropTypes.arrayOf(
286
+ PropTypes.shape({
287
+ value:PropTypes.string,
288
+ label:PropTypes.string,
289
+ }),
290
+ ),
291
+
292
+ /**
293
+ * The name of the custom select input
294
+ */
295
+ name:PropTypes.string,
296
+
297
+ /**
298
+ * The function to fetch the options from the backend
299
+ */
300
+ getOptions:PropTypes.func,
301
+
302
+ /**
303
+ * The function to set the value of the custom select input
304
+ */
305
+ setValue:PropTypes.func.isRequired,
306
+
307
+ /**
308
+ * The custom select input description
309
+ */
310
+ description:PropTypes.string,
311
+
312
+ /**
313
+ * The value of the custom select input
314
+ */
315
+ value:PropTypes.arrayOf(
316
+ PropTypes.shape({
317
+ value:PropTypes.string,
318
+ label:PropTypes.string,
319
+ }),
320
+ ),
321
+
322
+ /**
323
+ * The base color of the custom select input
324
+ */
325
+ color:PropTypes.string,
326
+
327
+ /**
328
+ * Whether the query getting the combobox options is inFlight
329
+ */
330
+ isFetching:PropTypes.bool.isRequired,
331
+
332
+ /**
333
+ * The minimum length of the search input to start fetching the options
334
+ */
335
+ minLength:PropTypes.number,
336
+
337
+ /**
338
+ * The function to transform the search input
339
+ */
340
+ transformSearch:PropTypes.func,
341
+
342
+ /**
343
+ * Whether the input filed shpuld be disabled
344
+ */
345
+ disabled:PropTypes.bool,
346
+
347
+ /**
348
+ * Whether the input is optional or not
349
+ */
350
+ optional:PropTypes.bool,
351
+
352
+ /**
353
+ * The placeholder text for the input
354
+ */
355
+ placeholder:PropTypes.string,
356
+ }
357
+
358
+ MultipleCombobox.defaultProps = {
359
+ // someProp: false
360
+ }
361
+
362
+ export default MultipleCombobox
@@ -0,0 +1,2 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ export { default as MultipleCombobox } from './MultipleCombobox'
@@ -0,0 +1,3 @@
1
+ export { Menu } from './Menu'
2
+ export { Combobox } from './Combobox'
3
+ export { MultipleCombobox } from './MultipleCombobox'
@@ -0,0 +1,2 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ export { default as QueryCombobox } from './QueryCombobox'
@@ -0,0 +1,127 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ /* stylelint-disable max-nesting-depth -- needed here */
3
+ /* stylelint-disable selector-max-compound-selectors -- needed here */
4
+
5
+ @use "@pareto-engineering/bem";
6
+ @use "@pareto-engineering/styles/src/mixins";
7
+ @use "@pareto-engineering/styles/src/globals" as *;
8
+
9
+ $default-input-padding: .55em .75em;
10
+ $default-gap: var(--gap);
11
+ $default-loading-circle-displacement: .5em;
12
+ $default-input-border-radius: var(--theme-default-input-border-radius);
13
+ $default-border: var(--theme-default-input-border);
14
+ $hover-border: var(--theme-hover-input-border);
15
+ $focus-border: var(--theme-focus-input-border);
16
+ $default-background: var(--background-inputs);
17
+ $on-default-background: var(--paragraph);
18
+ $disabled-background: var(--background-inputs-30);
19
+ $on-disabled-background: var(--on-background-inputs-30);
20
+
21
+ .#{bem.$base}.combobox,
22
+ .#{bem.$base}.multiple-combobox {
23
+ display: flex;
24
+ flex-direction: column;
25
+ outline: none;
26
+ position: relative;
27
+
28
+ > .#{bem.$base}.form-label {
29
+ margin-bottom: var(--gap);
30
+ }
31
+
32
+
33
+ .#{bem.$base}.popover {
34
+ border: $default-border;
35
+ border-radius: $default-input-border-radius;
36
+ width: 100%;
37
+
38
+ >.menu {
39
+ list-style: none;
40
+ margin: 0;
41
+ outline: 0;
42
+ padding: 0;
43
+
44
+ >.item {
45
+ border-radius: $default-input-border-radius;
46
+ padding: $default-input-padding;
47
+
48
+ > p {
49
+ margin: 0;
50
+ }
51
+
52
+ &.#{bem.$modifier-active} {
53
+ background-color: var(--y);
54
+
55
+ > p {
56
+ color: var(--on-y);
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ >.#{bem.$base}.loading-circle,
64
+ >.#{bem.$base}.button {
65
+ position: absolute;
66
+ right: $default-loading-circle-displacement;
67
+ }
68
+
69
+ >.#{bem.$base}.loading-circle {
70
+ top: calc($default-loading-circle-displacement * 1.5);
71
+ }
72
+
73
+ >.#{bem.$base}.button {
74
+ top: $default-loading-circle-displacement;
75
+ }
76
+
77
+ > .input {
78
+ background: $default-background;
79
+ border: $default-border;
80
+ border-radius: calc(var(--theme-default-border-radius) / 2);
81
+ color: $on-default-background;
82
+ outline: none;
83
+ padding: $default-input-padding;
84
+
85
+ &::placeholder {
86
+ color: var(--metadata);
87
+ }
88
+
89
+ &:disabled {
90
+ background-color: $disabled-background;
91
+ color: $on-disabled-background;
92
+ }
93
+
94
+ &:not(:disabled) {
95
+ &:hover,
96
+ &:active {
97
+ border: $hover-border;
98
+ }
99
+
100
+ &:focus {
101
+ border: $focus-border;
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+
108
+ .#{bem.$base}.multiple-combobox {
109
+ >.selected-items {
110
+ display: flex;
111
+ flex-wrap: wrap;
112
+ gap: calc($default-gap / 2);
113
+ margin-bottom: calc($default-gap / 2);
114
+
115
+ >.item {
116
+ >.#{bem.$base}.button {
117
+ align-items: center;
118
+ display: flex;
119
+ gap: calc($default-gap / 2);
120
+ }
121
+
122
+ .close {
123
+ font-size: calc(var(--s-3) * 1em);
124
+ }
125
+ }
126
+ }
127
+ }
@@ -0,0 +1,220 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ import * as React from 'react'
3
+
4
+ import { useState, useEffect } from 'react'
5
+
6
+ import { useRelayEnvironment, fetchQuery } from 'react-relay'
7
+
8
+ import { useField } from 'formik'
9
+
10
+ import PropTypes from 'prop-types'
11
+
12
+ // Local Definitions
13
+
14
+ import { SelectInput } from 'ui/f'
15
+
16
+ /**
17
+ * This is the component description.
18
+ */
19
+ const QuerySelect = ({
20
+ id,
21
+ className:userClassName,
22
+ style,
23
+ name,
24
+ label,
25
+ labelColor,
26
+ optional,
27
+ query,
28
+ variables,
29
+ optionsKeyMap,
30
+ description,
31
+ disabled,
32
+ color,
33
+ loadingOption,
34
+ defaultOption,
35
+ validate,
36
+ // ...otherProps
37
+ }) => {
38
+ const [, , helpers] = useField({ name, validate })
39
+
40
+ const { setError } = helpers
41
+
42
+ const environment = useRelayEnvironment()
43
+
44
+ const [isFetching, setIsFetching] = useState(false)
45
+
46
+ const [options, setOptions] = useState([])
47
+
48
+ const { graphql, accessor } = query
49
+
50
+ const getOptions = () => {
51
+ if (isFetching) return
52
+
53
+ fetchQuery(
54
+ environment,
55
+ graphql,
56
+ variables,
57
+ )
58
+ .subscribe({
59
+ start:() => {
60
+ setIsFetching(true)
61
+ setOptions([loadingOption])
62
+ },
63
+ complete:() => {
64
+ setIsFetching(false)
65
+ },
66
+ error:(fetchError) => {
67
+ setIsFetching(false)
68
+ if (setError)setError(fetchError.message)
69
+ },
70
+ next:(data) => {
71
+ setOptions([
72
+ defaultOption,
73
+ ...data[accessor].edges.map(({ node }) => ({
74
+ value:node[optionsKeyMap.value],
75
+ label:optionsKeyMap.getLabel(node),
76
+ })),
77
+ ])
78
+ },
79
+ })
80
+ }
81
+
82
+ useEffect(() => {
83
+ getOptions()
84
+ }, [variables])
85
+
86
+ return (
87
+ <SelectInput
88
+ id={id}
89
+ className={userClassName}
90
+ style={style}
91
+ name={name}
92
+ label={label}
93
+ optional={optional}
94
+ color={color}
95
+ labelColor={labelColor}
96
+ description={description}
97
+ disabled={isFetching || disabled}
98
+ options={options}
99
+ isLoading={isFetching}
100
+ />
101
+ )
102
+ }
103
+
104
+ QuerySelect.propTypes = {
105
+ /**
106
+ * The HTML id for this element
107
+ */
108
+ id:PropTypes.string,
109
+
110
+ /**
111
+ * The HTML class names for this element
112
+ */
113
+ className:PropTypes.string,
114
+
115
+ /**
116
+ * The React-written, css properties for this element.
117
+ */
118
+ style:PropTypes.objectOf(PropTypes.string),
119
+
120
+ /**
121
+ * The name of the custom select input
122
+ */
123
+ name:PropTypes.string,
124
+
125
+ /**
126
+ * The label of the custom select input
127
+ */
128
+ label:PropTypes.string,
129
+
130
+ /**
131
+ * The custom select input description
132
+ */
133
+ description:PropTypes.string,
134
+
135
+ /**
136
+ * Whether the input should be disabled
137
+ */
138
+ disabled:PropTypes.bool,
139
+
140
+ /**
141
+ * The base color of the custom select input
142
+ */
143
+ color:PropTypes.string,
144
+
145
+ /**
146
+ * The label color of the custom select input
147
+ */
148
+ labelColor:PropTypes.string,
149
+
150
+ /**
151
+ * The graphql query to fetch the options and the accessor to destructure the results from
152
+ */
153
+ query:PropTypes.shape({
154
+ accessor:PropTypes.string,
155
+ graphql :PropTypes.oneOfType([
156
+ PropTypes.string,
157
+ PropTypes.object,
158
+ ]).isRequired,
159
+ }),
160
+
161
+ /**
162
+ * The variables that might be required to be used in the query to fetch
163
+ * select options.
164
+ */
165
+ variables:PropTypes.objectOf(PropTypes.string),
166
+
167
+ /**
168
+ * The select option keys to be used to map the data to the select options.
169
+ * i.e `{ value: 'id', label: 'name' }`
170
+ */
171
+ optionsKeyMap:PropTypes.shape({
172
+ value :PropTypes.string.isRequired,
173
+ getLabel:PropTypes.func.isRequired,
174
+ }).isRequired,
175
+
176
+ /**
177
+ * The default select option for the query select
178
+ */
179
+ defaultOption:PropTypes.shape({
180
+ value :PropTypes.string.isRequired,
181
+ label :PropTypes.string.isRequired,
182
+ disabled:PropTypes.bool.isRequired,
183
+ }),
184
+
185
+ /**
186
+ * The option to dipslayed when the select options are being fetched
187
+ */
188
+ loadingOption:PropTypes.shape({
189
+ value :PropTypes.string.isRequired,
190
+ label :PropTypes.string.isRequired,
191
+ disabled:PropTypes.bool.isRequired,
192
+ }),
193
+
194
+ /**
195
+ * The query select field validator function
196
+ */
197
+ validate:PropTypes.func,
198
+
199
+ /*
200
+ * Whether the input is optional or not
201
+ */
202
+ optional:PropTypes.bool,
203
+ }
204
+
205
+ QuerySelect.defaultProps = {
206
+ disabled :false,
207
+ color :'paragraph',
208
+ defaultOption:{
209
+ value :'',
210
+ label :'Select an option',
211
+ disabled:true,
212
+ },
213
+ loadingOption:{
214
+ value :'',
215
+ label :'Fetching Options',
216
+ disabled:true,
217
+ },
218
+ }
219
+
220
+ export default QuerySelect
@@ -0,0 +1,2 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ export { default as QuerySelect } from './QuerySelect'