@xqmsg/ui-core 0.22.4 → 0.23.1-rc.1

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 (40) hide show
  1. package/dist/components/form/FormTypes.d.ts +2 -0
  2. package/dist/components/input/StackedCheckbox/StackedCheckbox.d.ts +3 -2
  3. package/dist/components/input/StackedInput/StackedInput.d.ts +2 -0
  4. package/dist/components/input/StackedPilledInput/index.d.ts +3 -0
  5. package/dist/components/input/StackedTextarea/StackedTextarea.d.ts +4 -0
  6. package/dist/components/input/components/token/index.d.ts +1 -0
  7. package/dist/components/input/index.d.ts +3 -2
  8. package/dist/components/select/index.d.ts +27 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/theme/components/button.d.ts +113 -0
  11. package/dist/theme/components/checkbox.d.ts +29 -0
  12. package/dist/theme/components/input.d.ts +23 -0
  13. package/dist/theme/components/select.d.ts +23 -0
  14. package/dist/theme/components/textarea.d.ts +78 -0
  15. package/dist/ui-core.cjs.development.js +336 -54
  16. package/dist/ui-core.cjs.development.js.map +1 -1
  17. package/dist/ui-core.cjs.production.min.js +1 -1
  18. package/dist/ui-core.cjs.production.min.js.map +1 -1
  19. package/dist/ui-core.esm.js +338 -57
  20. package/dist/ui-core.esm.js.map +1 -1
  21. package/package.json +1 -1
  22. package/src/components/button/Button.stories.tsx +92 -27
  23. package/src/components/form/FormTypes.ts +2 -0
  24. package/src/components/form/section/index.tsx +2 -0
  25. package/src/components/input/Input.stories.tsx +67 -0
  26. package/src/components/input/StackedCheckbox/StackedCheckbox.tsx +12 -4
  27. package/src/components/input/StackedInput/StackedInput.tsx +11 -1
  28. package/src/components/input/StackedPilledInput/index.tsx +310 -266
  29. package/src/components/input/StackedTextarea/StackedTextarea.tsx +30 -4
  30. package/src/components/input/components/dropdown/index.tsx +1 -1
  31. package/src/components/input/components/token/index.tsx +6 -5
  32. package/src/components/input/index.tsx +25 -9
  33. package/src/components/select/index.tsx +140 -0
  34. package/src/components/tabs/TabsWrapper.stories.tsx +1 -1
  35. package/src/index.tsx +3 -0
  36. package/src/theme/components/button.ts +67 -0
  37. package/src/theme/components/checkbox.ts +28 -0
  38. package/src/theme/components/input.ts +23 -1
  39. package/src/theme/components/textarea.ts +21 -0
  40. package/src/theme/customXQChakraTheme.ts +2 -0
@@ -17,6 +17,9 @@ export interface StackedPilledInputProps extends InputFieldProps {
17
17
  setError: UseFormSetError<FieldValues>;
18
18
  clearErrors: UseFormClearErrors<FieldValues>;
19
19
  control: Control<FieldValues, any>;
20
+ separators?: string[];
21
+ variant?: string;
22
+ label?: string;
20
23
  }
21
24
 
22
25
  /**
@@ -25,318 +28,359 @@ export interface StackedPilledInputProps extends InputFieldProps {
25
28
  const StackedPilledInput = React.forwardRef<
26
29
  HTMLInputElement,
27
30
  StackedPilledInputProps
28
- >(({ name, setValue, control, placeholder, disabled }, _ref) => {
29
- const watchedValue = useWatch({ control, name: name as string });
30
- const [lastestFormValueToArray, setLatestFormValueToArray] = useState<
31
- string[]
32
- >([]);
33
-
34
- const inputRef = useRef<HTMLInputElement>(null);
35
- const inputWrapperRef = useRef(null);
36
- const scrollRef = useRef<HTMLDivElement>(null);
37
-
38
- const [tokenIndex, setTokenIndex] = useState<number | null>(null);
39
- const [isFocussed, setIsFocussed] = useState(false);
40
- const [localValue, setLocalValue] = useState('');
41
-
42
- const latestTokenElement = document.getElementById(
43
- `${name}_token_${lastestFormValueToArray.length - 1}`
44
- );
45
-
46
- // gets latest watched form value (common delimited) from RHF state and creates a list
47
- useEffect(() => {
48
- if (watchedValue !== undefined && !watchedValue.length) {
49
- setLatestFormValueToArray([]);
50
- }
51
-
52
- if (watchedValue !== undefined && watchedValue?.length) {
53
- setLatestFormValueToArray(
54
- watchedValue
55
- .split(';')
56
- .join(',')
57
- .split(',')
58
- .filter(Boolean)
59
- );
31
+ >(
32
+ (
33
+ {
34
+ name,
35
+ setValue,
36
+ control,
37
+ placeholder,
38
+ disabled,
39
+ separators = ['Enter', ' ', ',', ';', 'Tab'],
40
+ variant,
41
+ label,
42
+ },
43
+ _ref
44
+ ) => {
45
+ const watchedValue = useWatch({ control, name: name as string });
46
+ const [lastestFormValueToArray, setLatestFormValueToArray] = useState<
47
+ string[]
48
+ >([]);
49
+
50
+ const inputRef = useRef<HTMLInputElement>(null);
51
+ const inputWrapperRef = useRef(null);
52
+ const scrollRef = useRef<HTMLDivElement>(null);
53
+
54
+ const [tokenIndex, setTokenIndex] = useState<number | null>(null);
55
+ const [isFocussed, setIsFocussed] = useState(false);
56
+ const [localValue, setLocalValue] = useState('');
57
+
58
+ const latestTokenElement = document.getElementById(
59
+ `${name}_token_${lastestFormValueToArray.length - 1}`
60
+ );
60
61
 
61
- if (latestTokenElement) {
62
- latestTokenElement.scrollIntoView({
63
- block: 'end',
64
- inline: 'center',
65
- behavior: 'smooth',
66
- });
62
+ // gets latest watched form value (common delimited) from RHF state and creates a list
63
+ useEffect(() => {
64
+ if (watchedValue !== undefined && !watchedValue.length) {
65
+ setLatestFormValueToArray([]);
67
66
  }
68
- }
69
- }, [latestTokenElement, watchedValue]);
70
-
71
- const onHandleKeyDown = (e: React.KeyboardEvent) => {
72
- if (e.key === 'Enter') {
73
- e.stopPropagation();
74
- e.preventDefault();
75
- }
76
-
77
- if (
78
- (e.key === 'Enter' ||
79
- e.key === ',' ||
80
- e.key === ';' ||
81
- e.key === 'Tab') &&
82
- localValue.trim().length
83
- ) {
84
- if (
85
- e.key === 'Enter' &&
86
- !localValue.trim().length &&
87
- tokenIndex !== null
88
- ) {
89
- setLocalValue(lastestFormValueToArray[tokenIndex]);
90
67
 
91
- const filteredUniqueValues = Array.from(
92
- new Set(
93
- lastestFormValueToArray.filter(
94
- value => value !== lastestFormValueToArray[tokenIndex]
95
- )
96
- )
68
+ if (watchedValue !== undefined && watchedValue?.length) {
69
+ setLatestFormValueToArray(
70
+ watchedValue
71
+ .split(';')
72
+ .join(',')
73
+ .split(',')
74
+ .filter(Boolean)
97
75
  );
98
76
 
99
- setValue(name as string, filteredUniqueValues.toString(), {
100
- shouldValidate: true,
101
- shouldDirty: true,
102
- });
103
-
104
- return setTokenIndex(null);
77
+ if (latestTokenElement) {
78
+ latestTokenElement.scrollIntoView({
79
+ block: 'end',
80
+ inline: 'center',
81
+ behavior: 'smooth',
82
+ });
83
+ }
105
84
  }
85
+ }, [latestTokenElement, watchedValue]);
106
86
 
107
- const filteredUniqueValues = Array.from(
108
- new Set([
109
- ...lastestFormValueToArray,
110
- ...localValue
87
+ const handleOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
88
+ if (tokenIndex === null) {
89
+ setLocalValue(
90
+ e.target.value
111
91
  .trim()
112
- .split(';')
113
- .join(',')
114
- .split(','),
115
- ])
116
- );
92
+ .replace(',', '')
93
+ .replace(';', '').length
94
+ ? e.target.value
95
+ : ''
96
+ );
97
+ }
98
+ };
117
99
 
118
- setLocalValue('');
100
+ const onHandleKeyDown = (e: React.KeyboardEvent) => {
101
+ if (e.key === 'Enter') {
102
+ e.stopPropagation();
103
+ e.preventDefault();
104
+ }
119
105
 
120
- return setValue(name as string, filteredUniqueValues.toString(), {
121
- shouldValidate: true,
122
- shouldDirty: true,
123
- });
124
- }
106
+ if (separators.includes(e.key)) {
107
+ if (
108
+ e.key === 'Enter' &&
109
+ !localValue.trim().length &&
110
+ tokenIndex !== null
111
+ ) {
112
+ setLocalValue(lastestFormValueToArray[tokenIndex]);
113
+
114
+ const filteredUniqueValues = Array.from(
115
+ new Set(
116
+ lastestFormValueToArray.filter(
117
+ value => value !== lastestFormValueToArray[tokenIndex]
118
+ )
119
+ )
120
+ );
125
121
 
126
- if (!localValue.trim().length && lastestFormValueToArray.length) {
127
- if (e.key === 'Backspace' && tokenIndex !== null) {
128
- setLocalValue(
129
- lastestFormValueToArray[tokenIndex].substring(
130
- 0,
131
- lastestFormValueToArray[tokenIndex].length
132
- )
133
- );
122
+ setValue(name as string, filteredUniqueValues.toString(), {
123
+ shouldValidate: true,
124
+ shouldDirty: true,
125
+ });
126
+
127
+ return setTokenIndex(null);
128
+ }
134
129
 
135
130
  const filteredUniqueValues = Array.from(
136
- new Set(
137
- [...lastestFormValueToArray].filter(
138
- value => value !== lastestFormValueToArray[tokenIndex]
139
- )
140
- )
131
+ new Set([
132
+ ...lastestFormValueToArray,
133
+ ...localValue
134
+ .trim()
135
+ .split(';')
136
+ .join(',')
137
+ .split(','),
138
+ ])
141
139
  );
142
140
 
143
- setValue(name as string, filteredUniqueValues.toString(), {
141
+ setLocalValue('');
142
+
143
+ return setValue(name as string, filteredUniqueValues.toString(), {
144
144
  shouldValidate: true,
145
145
  shouldDirty: true,
146
146
  });
147
-
148
- return setTokenIndex(null);
149
147
  }
150
148
 
151
- if (e.key === 'ArrowLeft') {
152
- if (tokenIndex === 0) return;
149
+ if (!localValue.trim().length && lastestFormValueToArray.length) {
150
+ if (e.key === 'Backspace' && tokenIndex !== null) {
151
+ setLocalValue(
152
+ lastestFormValueToArray[tokenIndex].substring(
153
+ 0,
154
+ lastestFormValueToArray[tokenIndex].length
155
+ )
156
+ );
157
+
158
+ const filteredUniqueValues = Array.from(
159
+ new Set(
160
+ [...lastestFormValueToArray].filter(
161
+ value => value !== lastestFormValueToArray[tokenIndex]
162
+ )
163
+ )
164
+ );
165
+
166
+ setValue(name as string, filteredUniqueValues.toString(), {
167
+ shouldValidate: true,
168
+ shouldDirty: true,
169
+ });
153
170
 
154
- if (!tokenIndex) {
155
- return setTokenIndex(lastestFormValueToArray.length - 1);
171
+ return setTokenIndex(null);
156
172
  }
157
173
 
158
- setTokenIndex(prevTokenIndex => (prevTokenIndex as number) - 1);
174
+ if (e.key === 'ArrowLeft') {
175
+ if (tokenIndex === 0) return;
159
176
 
160
- const tokenElement = document.getElementById(
161
- `${name}_token_${tokenIndex}`
162
- );
177
+ if (!tokenIndex) {
178
+ return setTokenIndex(lastestFormValueToArray.length - 1);
179
+ }
163
180
 
164
- if (!tokenElement || !scrollRef.current) return;
181
+ setTokenIndex(prevTokenIndex => (prevTokenIndex as number) - 1);
165
182
 
166
- return scrollRef.current.scrollBy({
167
- left: -1 * tokenElement.getBoundingClientRect().width,
168
- behavior: 'smooth',
169
- });
170
- }
183
+ const tokenElement = document.getElementById(
184
+ `${name}_token_${tokenIndex}`
185
+ );
171
186
 
172
- if (e.key === 'ArrowRight') {
173
- if (tokenIndex === null) return;
187
+ if (!tokenElement || !scrollRef.current) return;
174
188
 
175
- if (tokenIndex === lastestFormValueToArray.length - 1) {
176
- return setTokenIndex(null);
189
+ return scrollRef.current.scrollBy({
190
+ left: -1 * tokenElement.getBoundingClientRect().width,
191
+ behavior: 'smooth',
192
+ });
177
193
  }
178
- setTokenIndex(prevTokenIndex => (prevTokenIndex as number) + 1);
179
194
 
180
- const tokenElement = document.getElementById(
181
- `${name}_token_${tokenIndex}`
182
- );
195
+ if (e.key === 'ArrowRight') {
196
+ if (tokenIndex === null) return;
183
197
 
184
- if (!tokenElement || !scrollRef.current) return;
185
-
186
- return scrollRef.current.scrollBy({
187
- left: tokenElement.getBoundingClientRect().width,
188
- behavior: 'smooth',
189
- });
190
- }
191
- }
192
- };
198
+ if (tokenIndex === lastestFormValueToArray.length - 1) {
199
+ return setTokenIndex(null);
200
+ }
201
+ setTokenIndex(prevTokenIndex => (prevTokenIndex as number) + 1);
193
202
 
194
- const onRemoveTag = (index: number) => {
195
- const filteredUniqueValues = lastestFormValueToArray.filter(
196
- (_, i) => i !== index
197
- );
203
+ const tokenElement = document.getElementById(
204
+ `${name}_token_${tokenIndex}`
205
+ );
198
206
 
199
- setLatestFormValueToArray(filteredUniqueValues);
207
+ if (!tokenElement || !scrollRef.current) return;
200
208
 
201
- setValue(name as string, filteredUniqueValues.toString(), {
202
- shouldValidate: true,
203
- shouldDirty: true,
204
- });
205
- };
209
+ return scrollRef.current.scrollBy({
210
+ left: tokenElement.getBoundingClientRect().width,
211
+ behavior: 'smooth',
212
+ });
213
+ }
214
+ }
215
+ };
206
216
 
207
- const onBlur = () => {
208
- if (localValue.trim().length) {
209
- const filteredUniqueValues = Array.from(
210
- new Set([...lastestFormValueToArray, ...localValue.trim().split(',')])
217
+ const onRemoveTag = (index: number) => {
218
+ const filteredUniqueValues = lastestFormValueToArray.filter(
219
+ (_, i) => i !== index
211
220
  );
212
221
 
222
+ setLatestFormValueToArray(filteredUniqueValues);
223
+
213
224
  setValue(name as string, filteredUniqueValues.toString(), {
214
225
  shouldValidate: true,
215
226
  shouldDirty: true,
216
227
  });
217
- setLocalValue('');
218
- }
219
- setIsFocussed(false);
220
- };
221
-
222
- useOutsideClick({
223
- ref: inputWrapperRef,
224
- handler: () => {
225
- onBlur();
226
- },
227
- });
228
-
229
- return (
230
- <Box position="relative">
231
- <Flex
232
- fontSize="13px"
233
- border={isFocussed ? '2px solid' : '.5px solid'}
234
- borderColor={isFocussed ? colors.border.focus : colors.border.default}
235
- pl="8px"
236
- borderRadius="4px"
237
- alignItems="center"
238
- justifyContent="space-between"
239
- onClick={() => {
240
- if (isFocussed && tokenIndex !== null) {
241
- setTokenIndex(null);
242
- }
228
+ };
243
229
 
244
- if (!disabled) {
245
- inputRef.current?.focus();
246
- }
247
- }}
248
- bg={disabled ? colors.fill.light.quaternary : '#ffffff'}
249
- cursor={disabled ? 'not-allowed' : 'pointer'}
250
- ref={inputWrapperRef}
251
- h="26px"
252
- >
230
+ const onBlur = () => {
231
+ if (localValue.trim().length) {
232
+ const filteredUniqueValues = Array.from(
233
+ new Set([...lastestFormValueToArray, ...localValue.trim().split(',')])
234
+ );
235
+
236
+ setValue(name as string, filteredUniqueValues.toString(), {
237
+ shouldValidate: true,
238
+ shouldDirty: true,
239
+ });
240
+ setLocalValue('');
241
+ }
242
+ setIsFocussed(false);
243
+ };
244
+
245
+ useOutsideClick({
246
+ ref: inputWrapperRef,
247
+ handler: () => {
248
+ onBlur();
249
+ },
250
+ });
251
+ const isMobile = variant === 'mobile';
252
+
253
+ return (
254
+ <Box position="relative">
253
255
  <Flex
254
- h="100%"
256
+ fontSize={isMobile ? '17px' : '13px'}
257
+ border={isFocussed ? '2px solid' : '.5px solid'}
258
+ borderColor={isFocussed ? colors.border.focus : colors.border.default}
259
+ pl="8px"
260
+ borderRadius={isMobile ? '0' : '4px'}
255
261
  alignItems="center"
256
- overflowX="scroll"
257
- overflowY="hidden"
258
- maxWidth={isFocussed ? '80%' : '100%'}
259
- style={{
260
- scrollbarWidth: 'none' /* Firefox */,
261
- msOverflowStyle: 'none',
262
- }}
263
- sx={{
264
- '::-webkit-scrollbar': {
265
- display: 'none',
266
- },
262
+ justifyContent="space-between"
263
+ style={
264
+ isMobile
265
+ ? {
266
+ cursor: 'pointer',
267
+ height: '48px',
268
+ fontSize: '17px',
269
+ lineHeight: '20px',
270
+ fontWeight: 400,
271
+ padding: '12px 16px 12px 0px',
272
+ borderRadius: 0,
273
+ border: '0.5px solid rgba(153, 153, 153, 0.1)',
274
+ borderLeft: 'none',
275
+ borderRight: 'none',
276
+ }
277
+ : undefined
278
+ }
279
+ onClick={() => {
280
+ if (isFocussed && tokenIndex !== null) {
281
+ setTokenIndex(null);
282
+ }
283
+
284
+ if (!disabled) {
285
+ inputRef.current?.focus();
286
+ }
267
287
  }}
268
- ref={scrollRef}
269
- zIndex={100}
270
- onKeyDown={onHandleKeyDown}
288
+ bg={disabled ? colors.fill.light.quaternary : '#ffffff'}
289
+ cursor={disabled ? 'not-allowed' : 'pointer'}
290
+ ref={inputWrapperRef}
291
+ h={isMobile ? '48px' : '26px'}
271
292
  >
272
- {lastestFormValueToArray.length
273
- ? lastestFormValueToArray.map((label, index) => (
274
- <Box
275
- key={index}
276
- mr="4px"
277
- border={
278
- tokenIndex === index
279
- ? `1px solid ${colors.border.focus}`
280
- : 'none'
281
- }
282
- borderRadius="full"
283
- onClick={() => setTokenIndex(index)}
284
- width="100%"
285
- id={`${name}_token_${index}`}
286
- >
287
- <Token
288
- label={label}
289
- onDelete={(e: any) => {
290
- e.stopPropagation();
291
- e.preventDefault();
292
- onRemoveTag(index);
293
- }}
294
- />
295
- </Box>
296
- ))
297
- : null}
298
- {!lastestFormValueToArray.length && !isFocussed ? (
299
- <Text color={colors.label.secondary.light} fontSize="13px">
300
- {placeholder}
301
- </Text>
302
- ) : null}
303
- </Flex>
304
- {!disabled && (
305
- <Flex flex={1} minWidth={isFocussed && !tokenIndex ? '20%' : 0}>
306
- <Input
307
- onKeyDown={onHandleKeyDown}
308
- type="text"
309
- padding={0}
310
- alignContent="flex-start"
311
- float="right"
312
- border="none"
313
- height="auto"
314
- color={tokenIndex !== null ? 'transparent' : colors.label.primary}
315
- _focus={{ boxShadow: 'none !important' }}
316
- value={localValue}
317
- onChange={e =>
318
- tokenIndex === null &&
319
- setLocalValue(
320
- e.target.value
321
- .trim()
322
- .replace(',', '')
323
- .replace(';', '').length
324
- ? e.target.value
325
- : ''
326
- )
327
- }
328
- ref={inputRef}
329
- onFocus={() => setIsFocussed(true)}
330
- onBlur={() => {
331
- setIsFocussed(false);
332
- return setTokenIndex(null);
333
- }}
334
- />
293
+ <Flex
294
+ h="100%"
295
+ alignItems="center"
296
+ overflowX="scroll"
297
+ overflowY="hidden"
298
+ maxWidth={isFocussed ? '80%' : '100%'}
299
+ style={{
300
+ scrollbarWidth: 'none' /* Firefox */,
301
+ msOverflowStyle: 'none',
302
+ }}
303
+ sx={{
304
+ '::-webkit-scrollbar': {
305
+ display: 'none',
306
+ },
307
+ }}
308
+ ref={scrollRef}
309
+ zIndex={100}
310
+ onKeyDown={onHandleKeyDown}
311
+ >
312
+ {lastestFormValueToArray.length
313
+ ? lastestFormValueToArray.map((label, index) => (
314
+ <Box
315
+ key={index}
316
+ mr="4px"
317
+ border={
318
+ tokenIndex === index
319
+ ? `1px solid ${colors.border.focus}`
320
+ : 'none'
321
+ }
322
+ borderRadius="full"
323
+ onClick={() => setTokenIndex(index)}
324
+ width="100%"
325
+ id={`${name}_token_${index}`}
326
+ >
327
+ <Token
328
+ label={label}
329
+ onDelete={(e: any) => {
330
+ e.stopPropagation();
331
+ e.preventDefault();
332
+ onRemoveTag(index);
333
+ }}
334
+ isMobile={isMobile}
335
+ />
336
+ </Box>
337
+ ))
338
+ : null}
339
+ {!lastestFormValueToArray.length && !isFocussed ? (
340
+ <Text
341
+ color={colors.label.secondary.light}
342
+ fontSize={isMobile ? '17px' : '13px'}
343
+ >
344
+ {placeholder}
345
+ </Text>
346
+ ) : null}
335
347
  </Flex>
336
- )}
337
- </Flex>
338
- </Box>
339
- );
340
- });
348
+ {!disabled && (
349
+ <Flex flex={1} minWidth={isFocussed && !tokenIndex ? '20%' : 0}>
350
+ <Input
351
+ onKeyDown={onHandleKeyDown}
352
+ type="text"
353
+ padding={0}
354
+ alignContent="flex-start"
355
+ float="right"
356
+ border="none"
357
+ height="auto"
358
+ color={
359
+ tokenIndex !== null ? 'transparent' : colors.label.primary
360
+ }
361
+ _focus={{ boxShadow: 'none !important' }}
362
+ value={localValue}
363
+ onChange={handleOnChange}
364
+ ref={inputRef}
365
+ onFocus={() => setIsFocussed(true)}
366
+ onBlur={() => {
367
+ setIsFocussed(false);
368
+ return setTokenIndex(null);
369
+ }}
370
+ placeholder={
371
+ isMobile && label && lastestFormValueToArray.length === 0
372
+ ? (label as string)
373
+ : ''
374
+ }
375
+ variant={variant}
376
+ style={isMobile ? { border: 'none' } : undefined}
377
+ />
378
+ </Flex>
379
+ )}
380
+ </Flex>
381
+ </Box>
382
+ );
383
+ }
384
+ );
341
385
 
342
386
  export default StackedPilledInput;