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

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 (30) hide show
  1. package/dist/cjs/f/FormInput/FormInput.js +7 -0
  2. package/dist/cjs/f/fields/QueryCombobox/QueryCombobox.js +14 -8
  3. package/dist/cjs/f/fields/QuerySelect/QuerySelect.js +201 -0
  4. package/dist/cjs/f/fields/QuerySelect/index.js +15 -0
  5. package/dist/cjs/f/fields/QuerySelect/styles.scss +21 -0
  6. package/dist/cjs/f/fields/SelectInput/SelectInput.js +15 -3
  7. package/dist/cjs/f/fields/SelectInput/styles.scss +27 -14
  8. package/dist/cjs/f/fields/index.js +9 -1
  9. package/dist/es/f/FormInput/FormInput.js +8 -1
  10. package/dist/es/f/fields/QueryCombobox/QueryCombobox.js +14 -8
  11. package/dist/es/f/fields/QuerySelect/QuerySelect.js +179 -0
  12. package/dist/es/f/fields/QuerySelect/index.js +2 -0
  13. package/dist/es/f/fields/QuerySelect/styles.scss +21 -0
  14. package/dist/es/f/fields/SelectInput/SelectInput.js +14 -3
  15. package/dist/es/f/fields/SelectInput/styles.scss +27 -14
  16. package/dist/es/f/fields/index.js +2 -1
  17. package/package.json +1 -1
  18. package/src/__snapshots__/Storyshots.test.js.snap +582 -246
  19. package/src/stories/f/FormInput.stories.jsx +124 -6
  20. package/src/stories/f/QueryCombobox.stories.jsx +6 -4
  21. package/src/stories/f/QuerySelect.stories.jsx +134 -0
  22. package/src/stories/f/__generated__/FormInputAllTaskStatusesQuery.graphql.js +122 -0
  23. package/src/stories/f/__generated__/QuerySelectAllTaskStatusesQuery.graphql.js +122 -0
  24. package/src/ui/f/FormInput/FormInput.jsx +10 -0
  25. package/src/ui/f/fields/QueryCombobox/QueryCombobox.jsx +17 -13
  26. package/src/ui/f/fields/QuerySelect/QuerySelect.jsx +200 -0
  27. package/src/ui/f/fields/QuerySelect/index.js +2 -0
  28. package/src/ui/f/fields/SelectInput/SelectInput.jsx +16 -3
  29. package/src/ui/f/fields/SelectInput/styles.scss +27 -14
  30. package/src/ui/f/fields/index.js +1 -0
@@ -0,0 +1,200 @@
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
+ query,
26
+ variables,
27
+ optionsKeyMap,
28
+ description,
29
+ disabled,
30
+ color,
31
+ loadingOption,
32
+ defaultOption,
33
+ // ...otherProps
34
+ }) => {
35
+ const [, , helpers] = useField(name)
36
+
37
+ const { setError } = helpers
38
+
39
+ const environment = useRelayEnvironment()
40
+
41
+ const [isFetching, setIsFetching] = useState(false)
42
+
43
+ const [options, setOptions] = useState([])
44
+
45
+ const { graphql, accessor } = query
46
+
47
+ const getOptions = () => {
48
+ if (isFetching) return
49
+
50
+ fetchQuery(
51
+ environment,
52
+ graphql,
53
+ variables,
54
+ )
55
+ .subscribe({
56
+ start:() => {
57
+ setIsFetching(true)
58
+ setOptions([loadingOption])
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([
69
+ defaultOption,
70
+ ...data[accessor].edges.map(({ node }) => ({
71
+ value:node[optionsKeyMap.value],
72
+ label:optionsKeyMap.getLabel(node),
73
+ })),
74
+ ])
75
+ },
76
+ })
77
+ }
78
+
79
+ useEffect(() => {
80
+ getOptions()
81
+ }, [variables])
82
+
83
+ return (
84
+ <SelectInput
85
+ id={id}
86
+ className={userClassName}
87
+ style={style}
88
+ name={name}
89
+ label={label}
90
+ color={color}
91
+ description={description}
92
+ disabled={isFetching || disabled}
93
+ options={options}
94
+ isLoading={isFetching}
95
+ />
96
+ )
97
+ }
98
+
99
+ QuerySelect.propTypes = {
100
+ /**
101
+ * The HTML id for this element
102
+ */
103
+ id:PropTypes.string,
104
+
105
+ /**
106
+ * The HTML class names for this element
107
+ */
108
+ className:PropTypes.string,
109
+
110
+ /**
111
+ * The React-written, css properties for this element.
112
+ */
113
+ style:PropTypes.objectOf(PropTypes.string),
114
+
115
+ /**
116
+ * The name of the custom select input
117
+ */
118
+ name:PropTypes.string,
119
+
120
+ /**
121
+ * The label of the custom select input
122
+ */
123
+ label:PropTypes.string,
124
+
125
+ /**
126
+ * The custom select input description
127
+ */
128
+ description:PropTypes.string,
129
+
130
+ /**
131
+ * Whether the input should be disabled
132
+ */
133
+ disabled:PropTypes.bool,
134
+
135
+ /**
136
+ * The base color of the custom select input
137
+ */
138
+ color:PropTypes.string,
139
+
140
+ /**
141
+ * The graphql query to fetch the options and the accessor to destructure the results from
142
+ */
143
+ query:PropTypes.shape({
144
+ accessor:PropTypes.string,
145
+ graphql :PropTypes.oneOfType([
146
+ PropTypes.string,
147
+ PropTypes.object,
148
+ ]).isRequired,
149
+ }),
150
+
151
+ /**
152
+ * The variables that might be required to be used in the query to fetch
153
+ * select options.
154
+ */
155
+ variables:PropTypes.objectOf(PropTypes.string),
156
+
157
+ /**
158
+ * The select option keys to be used to map the data to the select options.
159
+ * i.e `{ value: 'id', label: 'name' }`
160
+ */
161
+ optionsKeyMap:PropTypes.shape({
162
+ value :PropTypes.string.isRequired,
163
+ getLabel:PropTypes.func.isRequired,
164
+ }).isRequired,
165
+
166
+ /**
167
+ * The default select option for the query select
168
+ */
169
+ defaultOption:PropTypes.shape({
170
+ value :PropTypes.string.isRequired,
171
+ label :PropTypes.string.isRequired,
172
+ disabled:PropTypes.bool.isRequired,
173
+ }),
174
+
175
+ /**
176
+ * The option to dipslayed when the select options are being fetched
177
+ */
178
+ loadingOption:PropTypes.shape({
179
+ value :PropTypes.string.isRequired,
180
+ label :PropTypes.string.isRequired,
181
+ disabled:PropTypes.bool.isRequired,
182
+ }),
183
+ }
184
+
185
+ QuerySelect.defaultProps = {
186
+ disabled :false,
187
+ color :'background2',
188
+ defaultOption:{
189
+ value :'',
190
+ label :'Select an option',
191
+ disabled:true,
192
+ },
193
+ loadingOption:{
194
+ value :'',
195
+ label :'Fetching Options',
196
+ disabled:true,
197
+ },
198
+ }
199
+
200
+ export default QuerySelect
@@ -0,0 +1,2 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ export { default as QuerySelect } from './QuerySelect'
@@ -9,6 +9,8 @@ import PropTypes from 'prop-types'
9
9
 
10
10
  import styleNames from '@pareto-engineering/bem'
11
11
 
12
+ import { LoadingCircle } from 'ui/a'
13
+
12
14
  import { FormLabel, FormDescription } from '../../common'
13
15
 
14
16
  // Local Definitions
@@ -31,6 +33,7 @@ const SelectInput = ({
31
33
  validate,
32
34
  description,
33
35
  disabled,
36
+ isLoading,
34
37
  // ...otherProps
35
38
  }) => {
36
39
  useLayoutEffect(() => {
@@ -56,8 +59,9 @@ const SelectInput = ({
56
59
  // {...otherProps}
57
60
  >
58
61
  <FormLabel name={name}>{label}</FormLabel>
59
- <select className="input" {...field} value={field.value || ''} id={name} disabled={disabled}>
60
- {
62
+ <div className="select-wrapper">
63
+ <select className="input" {...field} value={field.value || ''} id={name} disabled={disabled}>
64
+ {
61
65
  options.map((option) => {
62
66
  // i.e if option is a string like "blah", return { value: "blah", label: "blah" }
63
67
  const newOption = typeof option === 'string' ? { value: option, label: option } : option
@@ -73,7 +77,11 @@ const SelectInput = ({
73
77
  )
74
78
  })
75
79
  }
76
- </select>
80
+ </select>
81
+ {isLoading && (
82
+ <LoadingCircle className="x-main2" />
83
+ )}
84
+ </div>
77
85
  {(description || (meta.touched && meta.error))
78
86
  && (
79
87
  <FormDescription isError={!!meta.error} className="v50 mt-v s-1">
@@ -142,6 +150,11 @@ SelectInput.propTypes = {
142
150
  * The color of the select input
143
151
  */
144
152
  color:PropTypes.string,
153
+
154
+ /*
155
+ * Whether the query that is fetching the select options is still in flight
156
+ */
157
+ isLoading:PropTypes.bool,
145
158
  }
146
159
 
147
160
  SelectInput.defaultProps = {
@@ -16,22 +16,35 @@ $default-margin: 1em;
16
16
  margin-bottom: $default-margin
17
17
  }
18
18
 
19
- .input {
20
- border: var(--theme-border-style) var(--dark-y);
21
- background: var(--light-y);
22
- color: var(--on-y);
23
- padding: $default-padding;
24
-
25
- &:not(:disabled):hover {
26
- border: var(--theme-border-style) var(--light-background4);
19
+ .select-wrapper {
20
+ position: relative;
21
+
22
+ >.#{bem.$base}.loading-circle {
23
+ position: absolute;
24
+ right: 0;
25
+ top: 50%;
26
+ transform: translateY(-50%);
27
27
  }
28
28
 
29
- &:disabled {
30
- background-color: var(--dark-y);
31
- }
32
-
33
- &:focus {
34
- background: var(--y);
29
+ >.input {
30
+ width: 100%;
31
+ border: var(--theme-border-style) var(--dark-y);
32
+ background: var(--light-y);
33
+ color: var(--on-y);
34
+ padding: $default-padding;
35
+
36
+ &:not(:disabled):hover {
37
+ border: var(--theme-border-style) var(--light-background4);
38
+ }
39
+
40
+ &:disabled {
41
+ background-color: var(--dark-y);
42
+ appearance: none;
43
+ }
44
+
45
+ &:focus {
46
+ background: var(--y);
47
+ }
35
48
  }
36
49
  }
37
50
  }
@@ -4,3 +4,4 @@ export { ChoicesInput } from './ChoicesInput'
4
4
  export { TextareaInput } from './TextareaInput'
5
5
  export { RatingsInput } from './RatingsInput'
6
6
  export { QueryCombobox } from './QueryCombobox'
7
+ export { QuerySelect } from './QuerySelect'