@xqmsg/ui-core 0.16.0 → 0.16.2
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/components/input/StackedInput/StackedInput.d.ts +2 -0
- package/dist/components/input/components/dropdown/index.d.ts +1 -0
- package/dist/components/input/components/label/index.d.ts +1 -0
- package/dist/components/input/index.d.ts +4 -1
- package/dist/ui-core.cjs.development.js +285 -303
- package/dist/ui-core.cjs.development.js.map +1 -1
- package/dist/ui-core.cjs.production.min.js +1 -1
- package/dist/ui-core.cjs.production.min.js.map +1 -1
- package/dist/ui-core.esm.js +288 -306
- package/dist/ui-core.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/input/Input.stories.tsx +0 -1
- package/src/components/input/StackedInput/StackedInput.tsx +14 -3
- package/src/components/input/StackedMultiSelect/index.tsx +113 -21
- package/src/components/input/StackedPilledInput/index.tsx +27 -26
- package/src/components/input/StackedSelect/index.tsx +117 -18
- package/src/components/input/components/dropdown/index.tsx +10 -3
- package/src/components/input/components/label/index.tsx +14 -3
- package/src/components/input/index.tsx +17 -1
- package/src/theme/customXQChakraTheme.ts +0 -2
- package/dist/theme/components/modal.d.ts +0 -242
- package/src/theme/components/modal.ts +0 -216
package/package.json
CHANGED
|
@@ -5,7 +5,6 @@ import { Input, InputProps } from '.';
|
|
|
5
5
|
import { useFormHandler } from '../form/hooks/useFormHandler';
|
|
6
6
|
import * as Yup from 'yup';
|
|
7
7
|
import { Form } from '../form';
|
|
8
|
-
import { Box } from '@chakra-ui/react';
|
|
9
8
|
|
|
10
9
|
const meta: Meta<InputProps<StoryFormSchema>> = {
|
|
11
10
|
title: 'Input example',
|
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Input } from '@chakra-ui/react';
|
|
2
|
+
import { Input, InputGroup } from '@chakra-ui/react';
|
|
3
3
|
import { InputFieldProps } from '../InputTypes';
|
|
4
4
|
|
|
5
5
|
export interface StackedInputProps extends InputFieldProps {
|
|
6
6
|
isRequired?: boolean;
|
|
7
|
+
leftElement?: React.ReactNode;
|
|
8
|
+
rightElement?: React.ReactNode;
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* A functional React component utilized to render the `StackedInput` component.
|
|
11
13
|
*/
|
|
12
14
|
const StackedInput = React.forwardRef<HTMLInputElement, StackedInputProps>(
|
|
13
|
-
(
|
|
14
|
-
|
|
15
|
+
(
|
|
16
|
+
{ type = 'text', isRequired, rightElement, leftElement, ...props },
|
|
17
|
+
_ref
|
|
18
|
+
) => {
|
|
19
|
+
return (
|
|
20
|
+
<InputGroup>
|
|
21
|
+
{leftElement && leftElement}
|
|
22
|
+
<Input type={type} isRequired={isRequired} {...props} ref={_ref} />
|
|
23
|
+
{rightElement && rightElement}
|
|
24
|
+
</InputGroup>
|
|
25
|
+
);
|
|
15
26
|
}
|
|
16
27
|
);
|
|
17
28
|
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
KeyboardEventHandler,
|
|
3
|
+
useEffect,
|
|
4
|
+
useMemo,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import { Box, Flex, Text, Image, Input } from '@chakra-ui/react';
|
|
9
|
+
import { debounce } from 'lodash';
|
|
3
10
|
import {
|
|
4
11
|
FieldOption,
|
|
5
12
|
FieldOptions,
|
|
@@ -44,7 +51,13 @@ const StackedMultiSelect = React.forwardRef<
|
|
|
44
51
|
const [localOptions, setLocalOptions] = useState<FieldOptions>(options);
|
|
45
52
|
const [isFocussed, setIsFocussed] = useState(false);
|
|
46
53
|
const [shouldSideScroll, setShouldSideScroll] = useState(false);
|
|
54
|
+
const [optionIndex, setOptionIndex] = useState<number | null>(null);
|
|
55
|
+
|
|
47
56
|
const [position, setPosition] = useState<'top' | 'bottom'>('top');
|
|
57
|
+
const [searchValue, setSearchValue] = useState('');
|
|
58
|
+
const [debouncedSearchValue, setDebouncedSearchValue] = useState('');
|
|
59
|
+
|
|
60
|
+
console.log({ searchValue, debouncedSearchValue });
|
|
48
61
|
|
|
49
62
|
const boundingClientRect = dropdownRef.current?.getBoundingClientRect() as DOMRect;
|
|
50
63
|
|
|
@@ -122,27 +135,105 @@ const StackedMultiSelect = React.forwardRef<
|
|
|
122
135
|
);
|
|
123
136
|
};
|
|
124
137
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
138
|
+
const handleOnKeyDown: KeyboardEventHandler<HTMLInputElement> = e => {
|
|
139
|
+
const initialOptionIndex = options[0].value === 'section_header' ? 1 : 0;
|
|
140
|
+
|
|
141
|
+
if (
|
|
142
|
+
!isFocussed &&
|
|
143
|
+
(e.key === 'Enter' || e.key === 'ArrowUp' || e.key === 'ArrowDown')
|
|
144
|
+
) {
|
|
145
|
+
setIsFocussed(true);
|
|
146
|
+
return setOptionIndex(initialOptionIndex);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (isFocussed) {
|
|
150
|
+
if (
|
|
151
|
+
optionIndex === null &&
|
|
152
|
+
(e.key === 'Enter' || e.key === 'ArrowUp' || e.key === 'ArrowDown')
|
|
153
|
+
) {
|
|
154
|
+
return setOptionIndex(initialOptionIndex);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (e.key === 'ArrowUp' && optionIndex !== null && optionIndex > 0) {
|
|
158
|
+
const incrementValue =
|
|
159
|
+
localOptions[optionIndex - 1] &&
|
|
160
|
+
localOptions[optionIndex - 1].value === 'section_header'
|
|
161
|
+
? 2
|
|
162
|
+
: 1;
|
|
163
|
+
setOptionIndex(optionIndex - incrementValue);
|
|
164
|
+
|
|
165
|
+
return dropdownMenuRef.current?.scrollTo({
|
|
166
|
+
top: optionIndex * 24,
|
|
167
|
+
behavior: 'smooth',
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (
|
|
172
|
+
e.key === 'ArrowDown' &&
|
|
173
|
+
optionIndex !== null &&
|
|
174
|
+
optionIndex < localOptions.length
|
|
175
|
+
) {
|
|
176
|
+
const incrementValue =
|
|
177
|
+
localOptions[optionIndex + 1] &&
|
|
178
|
+
localOptions[optionIndex + 1].value === 'section_header'
|
|
179
|
+
? 2
|
|
180
|
+
: 1;
|
|
181
|
+
setOptionIndex(optionIndex + incrementValue);
|
|
182
|
+
|
|
183
|
+
return dropdownMenuRef.current?.scrollTo({
|
|
184
|
+
top: optionIndex * 24,
|
|
185
|
+
behavior: 'smooth',
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (e.key === 'Enter' && optionIndex !== null) {
|
|
190
|
+
const option = localOptions.find((_, idx) => optionIndex === idx);
|
|
191
|
+
if (!option) return;
|
|
134
192
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
193
|
+
handleChange(option);
|
|
194
|
+
|
|
195
|
+
return setIsFocussed(false);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (e.key === 'Tab') {
|
|
199
|
+
return setIsFocussed(false);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return update(debouncedSearchValue.concat(e.key));
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
useEffect(() => {
|
|
207
|
+
if (searchValue.length) {
|
|
208
|
+
const idx = options.findIndex(
|
|
209
|
+
option =>
|
|
210
|
+
option.label.substring(0, searchValue.length).toLowerCase() ===
|
|
211
|
+
searchValue.toLowerCase()
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
dropdownMenuRef.current?.scrollTo({
|
|
215
|
+
top: idx * 24,
|
|
216
|
+
behavior: 'smooth',
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
setSearchValue('');
|
|
220
|
+
setDebouncedSearchValue('');
|
|
221
|
+
}
|
|
222
|
+
}, [options, searchValue]);
|
|
223
|
+
|
|
224
|
+
const updateSearchValue = useMemo(() => {
|
|
225
|
+
return debounce(val => {
|
|
226
|
+
setSearchValue(val);
|
|
227
|
+
}, 1000);
|
|
228
|
+
}, []);
|
|
229
|
+
|
|
230
|
+
const update = (value: string) => {
|
|
231
|
+
updateSearchValue(value);
|
|
232
|
+
setDebouncedSearchValue(value);
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
return (
|
|
236
|
+
<Box ref={dropdownRef} position="relative" onKeyDown={handleOnKeyDown}>
|
|
146
237
|
<Flex
|
|
147
238
|
fontSize="13px"
|
|
148
239
|
h="26px"
|
|
@@ -218,6 +309,7 @@ const StackedMultiSelect = React.forwardRef<
|
|
|
218
309
|
onSelectItem={option => handleChange(option)}
|
|
219
310
|
options={localOptions}
|
|
220
311
|
position={position}
|
|
312
|
+
optionIndex={optionIndex}
|
|
221
313
|
/>
|
|
222
314
|
)}
|
|
223
315
|
</Box>
|
|
@@ -261,35 +261,36 @@ const StackedPilledInput = React.forwardRef<
|
|
|
261
261
|
}}
|
|
262
262
|
ref={scrollRef}
|
|
263
263
|
>
|
|
264
|
-
{lastestFormValueToArray.length
|
|
265
|
-
lastestFormValueToArray.map((label, index) => (
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
264
|
+
{lastestFormValueToArray.length
|
|
265
|
+
? lastestFormValueToArray.map((label, index) => (
|
|
266
|
+
<Box
|
|
267
|
+
mr="4px"
|
|
268
|
+
border={
|
|
269
|
+
tokenIndex === index
|
|
270
|
+
? `1px solid ${colors.border.focus}`
|
|
271
|
+
: 'none'
|
|
272
|
+
}
|
|
273
|
+
borderRadius="full"
|
|
274
|
+
onClick={() => isFocussed && setTokenIndex(index)}
|
|
275
|
+
width="100%"
|
|
276
|
+
id={`${name}_token_${index}`}
|
|
277
|
+
>
|
|
278
|
+
<Token
|
|
279
|
+
label={label}
|
|
280
|
+
onDelete={(e: any) => {
|
|
281
|
+
e.stopPropagation();
|
|
282
|
+
e.preventDefault();
|
|
283
|
+
onRemoveTag(index);
|
|
284
|
+
}}
|
|
285
|
+
/>
|
|
286
|
+
</Box>
|
|
287
|
+
))
|
|
288
|
+
: null}
|
|
289
|
+
{!lastestFormValueToArray.length && !isFocussed ? (
|
|
289
290
|
<Text color={colors.label.secondary.light} fontSize="13px">
|
|
290
291
|
{placeholder}
|
|
291
292
|
</Text>
|
|
292
|
-
)}
|
|
293
|
+
) : null}
|
|
293
294
|
</Flex>
|
|
294
295
|
<Flex flex={1} minWidth={isFocussed ? '20%' : 0}>
|
|
295
296
|
<Input
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
KeyboardEventHandler,
|
|
3
|
+
useEffect,
|
|
4
|
+
useRef,
|
|
5
|
+
useMemo,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import {
|
|
3
9
|
Box,
|
|
4
10
|
Image,
|
|
@@ -14,6 +20,7 @@ import SubtractIcon from './assets/svg/subtract.svg';
|
|
|
14
20
|
import { Dropdown } from '../components/dropdown';
|
|
15
21
|
import useDidMountEffect from '../../../hooks/useDidMountEffect';
|
|
16
22
|
import { useOnClickOutside } from '../../../hooks/useOnOutsideClick';
|
|
23
|
+
import { debounce } from 'lodash';
|
|
17
24
|
|
|
18
25
|
export interface StackedSelectProps extends StackedInputProps {
|
|
19
26
|
options: FieldOptions;
|
|
@@ -46,7 +53,10 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
|
|
|
46
53
|
const [selectedOption, setSelectedOption] = useState(
|
|
47
54
|
options.find(option => option.value === value)?.label ?? ''
|
|
48
55
|
);
|
|
56
|
+
const [optionIndex, setOptionIndex] = useState<number | null>(null);
|
|
49
57
|
const [position, setPosition] = useState<'top' | 'bottom'>('top');
|
|
58
|
+
const [searchValue, setSearchValue] = useState('');
|
|
59
|
+
const [debouncedSearchValue, setDebouncedSearchValue] = useState('');
|
|
50
60
|
|
|
51
61
|
const boundingClientRect = dropdownRef.current?.getBoundingClientRect() as DOMRect;
|
|
52
62
|
|
|
@@ -81,6 +91,109 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
|
|
|
81
91
|
setIsFocussed(false);
|
|
82
92
|
};
|
|
83
93
|
|
|
94
|
+
const handleOnKeyDown: KeyboardEventHandler<HTMLInputElement> = e => {
|
|
95
|
+
const initialOptionIndex = options[0].value === 'section_header' ? 1 : 0;
|
|
96
|
+
|
|
97
|
+
if (
|
|
98
|
+
!isFocussed &&
|
|
99
|
+
(e.key === 'Enter' || e.key === 'ArrowUp' || e.key === 'ArrowDown')
|
|
100
|
+
) {
|
|
101
|
+
setIsFocussed(true);
|
|
102
|
+
return setOptionIndex(initialOptionIndex);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (isFocussed) {
|
|
106
|
+
if (
|
|
107
|
+
optionIndex === null &&
|
|
108
|
+
(e.key === 'Enter' || e.key === 'ArrowUp' || e.key === 'ArrowDown')
|
|
109
|
+
) {
|
|
110
|
+
return setOptionIndex(initialOptionIndex);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (e.key === 'ArrowUp' && optionIndex !== null && optionIndex > 0) {
|
|
114
|
+
const incrementValue =
|
|
115
|
+
options[optionIndex - 1] &&
|
|
116
|
+
options[optionIndex - 1].value === 'section_header'
|
|
117
|
+
? 2
|
|
118
|
+
: 1;
|
|
119
|
+
setOptionIndex(optionIndex - incrementValue);
|
|
120
|
+
|
|
121
|
+
return dropdownMenuRef.current?.scrollTo({
|
|
122
|
+
top: optionIndex * 24,
|
|
123
|
+
behavior: 'smooth',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (
|
|
128
|
+
e.key === 'ArrowDown' &&
|
|
129
|
+
optionIndex !== null &&
|
|
130
|
+
optionIndex < options.length
|
|
131
|
+
) {
|
|
132
|
+
const incrementValue =
|
|
133
|
+
options[optionIndex + 1] &&
|
|
134
|
+
options[optionIndex + 1].value === 'section_header'
|
|
135
|
+
? 2
|
|
136
|
+
: 1;
|
|
137
|
+
setOptionIndex(optionIndex + incrementValue);
|
|
138
|
+
|
|
139
|
+
return dropdownMenuRef.current?.scrollTo({
|
|
140
|
+
top: optionIndex * 24,
|
|
141
|
+
behavior: 'smooth',
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (e.key === 'Enter' && optionIndex !== null) {
|
|
146
|
+
const option = options.find((_, idx) => optionIndex === idx);
|
|
147
|
+
if (!option) return;
|
|
148
|
+
|
|
149
|
+
if (handleOnChange) {
|
|
150
|
+
handleOnChange(option.value);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
setSelectedOption(option?.label);
|
|
154
|
+
setValue(name as string, option.value, {
|
|
155
|
+
shouldDirty: true,
|
|
156
|
+
shouldValidate: true,
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
return setIsFocussed(false);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (e.key === 'Tab') {
|
|
163
|
+
return setIsFocussed(false);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
if (searchValue.length) {
|
|
170
|
+
const idx = options.findIndex(
|
|
171
|
+
option =>
|
|
172
|
+
option.label.substring(0, searchValue.length).toLowerCase() ===
|
|
173
|
+
searchValue.toLowerCase()
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
dropdownMenuRef.current?.scrollTo({
|
|
177
|
+
top: idx * 24,
|
|
178
|
+
behavior: 'smooth',
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
setSearchValue('');
|
|
182
|
+
setDebouncedSearchValue('');
|
|
183
|
+
}
|
|
184
|
+
}, [options, searchValue]);
|
|
185
|
+
|
|
186
|
+
const updateSearchValue = useMemo(() => {
|
|
187
|
+
return debounce(val => {
|
|
188
|
+
setSearchValue(val);
|
|
189
|
+
}, 1000);
|
|
190
|
+
}, []);
|
|
191
|
+
|
|
192
|
+
const update = (value: string) => {
|
|
193
|
+
updateSearchValue(value);
|
|
194
|
+
setDebouncedSearchValue(value);
|
|
195
|
+
};
|
|
196
|
+
|
|
84
197
|
return (
|
|
85
198
|
<Box ref={dropdownRef} position="relative">
|
|
86
199
|
<InputGroup>
|
|
@@ -96,23 +209,8 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
|
|
|
96
209
|
value={selectedOption}
|
|
97
210
|
disabled={disabled}
|
|
98
211
|
autoComplete="off"
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (e.key === 'Tab') {
|
|
102
|
-
return setIsFocussed(false);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const idx = options.findIndex(
|
|
106
|
-
option => option.label[0].toLocaleLowerCase() === e.key
|
|
107
|
-
);
|
|
108
|
-
console.log(idx);
|
|
109
|
-
|
|
110
|
-
dropdownMenuRef.current?.scrollTo({
|
|
111
|
-
top: idx * 27,
|
|
112
|
-
behavior: 'smooth',
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
}}
|
|
212
|
+
onChange={e => update(debouncedSearchValue.concat(e.target.value))}
|
|
213
|
+
onKeyDown={handleOnKeyDown}
|
|
116
214
|
/>
|
|
117
215
|
<InputRightElement
|
|
118
216
|
cursor={disabled ? 'not-allowed' : 'pointer'}
|
|
@@ -127,6 +225,7 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
|
|
|
127
225
|
dropdownRef={dropdownMenuRef}
|
|
128
226
|
onSelectItem={option => handleOnSelectItem(option)}
|
|
129
227
|
options={options}
|
|
228
|
+
optionIndex={optionIndex}
|
|
130
229
|
/>
|
|
131
230
|
)}
|
|
132
231
|
</Box>
|
|
@@ -8,6 +8,7 @@ export interface DropdownProps {
|
|
|
8
8
|
options: FieldOptions;
|
|
9
9
|
dropdownRef: RefObject<HTMLDivElement>;
|
|
10
10
|
position: 'top' | 'bottom';
|
|
11
|
+
optionIndex?: number | null;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -18,6 +19,7 @@ export const Dropdown: React.FC<DropdownProps> = ({
|
|
|
18
19
|
options,
|
|
19
20
|
dropdownRef,
|
|
20
21
|
position,
|
|
22
|
+
optionIndex,
|
|
21
23
|
}) => {
|
|
22
24
|
const DropdownContent = useMemo(() => {
|
|
23
25
|
return options.map((option, idx) => (
|
|
@@ -55,22 +57,27 @@ export const Dropdown: React.FC<DropdownProps> = ({
|
|
|
55
57
|
px="8px"
|
|
56
58
|
py="4px"
|
|
57
59
|
width="100%"
|
|
58
|
-
color={
|
|
60
|
+
color={
|
|
61
|
+
optionIndex === idx
|
|
62
|
+
? colors.label.primary.dark
|
|
63
|
+
: colors.label.primary.light
|
|
64
|
+
}
|
|
59
65
|
_hover={{
|
|
60
66
|
color: colors.label.primary.dark,
|
|
61
67
|
bg: colors.fill.action,
|
|
62
68
|
borderRadius: '4px',
|
|
63
69
|
width: '100%',
|
|
64
70
|
}}
|
|
65
|
-
bg=
|
|
71
|
+
bg={optionIndex === idx ? colors.fill.action : 'inherit'}
|
|
66
72
|
whiteSpace="nowrap"
|
|
73
|
+
id={option.value}
|
|
67
74
|
>
|
|
68
75
|
{option.label}
|
|
69
76
|
</Box>
|
|
70
77
|
)}
|
|
71
78
|
</>
|
|
72
79
|
));
|
|
73
|
-
}, [onSelectItem, options]);
|
|
80
|
+
}, [onSelectItem, optionIndex, options]);
|
|
74
81
|
|
|
75
82
|
return (
|
|
76
83
|
<Flex
|
|
@@ -1,24 +1,35 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Box, FormLabel } from '@chakra-ui/react';
|
|
2
|
+
import { Box, FormLabel, Tooltip } from '@chakra-ui/react';
|
|
3
3
|
import colors from '../../../../../src/theme/foundations/colors';
|
|
4
|
+
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
|
4
5
|
|
|
5
6
|
export interface LabelProps {
|
|
6
7
|
label: string;
|
|
8
|
+
tooltipText?: string;
|
|
7
9
|
isRequired?: boolean;
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* A functional React component utilized to render the `Label` component
|
|
12
14
|
*/
|
|
13
|
-
export const Label: React.FC<LabelProps> = ({
|
|
15
|
+
export const Label: React.FC<LabelProps> = ({
|
|
16
|
+
tooltipText,
|
|
17
|
+
isRequired,
|
|
18
|
+
label,
|
|
19
|
+
}) => {
|
|
14
20
|
return (
|
|
15
|
-
<FormLabel>
|
|
21
|
+
<FormLabel display="flex" alignItems="center">
|
|
16
22
|
{label}
|
|
17
23
|
{isRequired && (
|
|
18
24
|
<Box ml={1} color={colors.label.error}>
|
|
19
25
|
*
|
|
20
26
|
</Box>
|
|
21
27
|
)}
|
|
28
|
+
{!!tooltipText && (
|
|
29
|
+
<Tooltip label={tooltipText} placement="top">
|
|
30
|
+
<QuestionOutlineIcon boxSize="13px" ml="8px" />
|
|
31
|
+
</Tooltip>
|
|
32
|
+
)}
|
|
22
33
|
</FormLabel>
|
|
23
34
|
);
|
|
24
35
|
};
|
|
@@ -40,9 +40,12 @@ export interface InputProps<T extends FieldValues> extends ValidationProps {
|
|
|
40
40
|
control: Control<T, any>;
|
|
41
41
|
onChange?: (value?: string) => void;
|
|
42
42
|
disabled?: boolean;
|
|
43
|
+
tooltipText?: string;
|
|
43
44
|
setValue: UseFormSetValue<T>;
|
|
44
45
|
setError: UseFormSetError<T>;
|
|
45
46
|
clearErrors: UseFormClearErrors<T>;
|
|
47
|
+
leftElement?: React.ReactNode;
|
|
48
|
+
rightElement?: React.ReactNode;
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
/**
|
|
@@ -58,6 +61,7 @@ export function Input<T extends FieldValues>({
|
|
|
58
61
|
name,
|
|
59
62
|
helperText,
|
|
60
63
|
options,
|
|
64
|
+
tooltipText,
|
|
61
65
|
isInvalid,
|
|
62
66
|
errorText,
|
|
63
67
|
isRequired,
|
|
@@ -65,6 +69,8 @@ export function Input<T extends FieldValues>({
|
|
|
65
69
|
defaultValue,
|
|
66
70
|
control,
|
|
67
71
|
disabled,
|
|
72
|
+
rightElement,
|
|
73
|
+
leftElement,
|
|
68
74
|
onChange,
|
|
69
75
|
setValue,
|
|
70
76
|
setError,
|
|
@@ -91,6 +97,8 @@ export function Input<T extends FieldValues>({
|
|
|
91
97
|
onChange={onChange}
|
|
92
98
|
onBlur={onBlur}
|
|
93
99
|
ref={ref}
|
|
100
|
+
rightElement={rightElement}
|
|
101
|
+
leftElement={leftElement}
|
|
94
102
|
disabled={disabled}
|
|
95
103
|
value={value}
|
|
96
104
|
/>
|
|
@@ -136,6 +144,7 @@ export function Input<T extends FieldValues>({
|
|
|
136
144
|
className={`input-${inputType} ${className ?? ''}`}
|
|
137
145
|
name={name}
|
|
138
146
|
id={name}
|
|
147
|
+
placeholder={placeholder}
|
|
139
148
|
maxLength={maxLength}
|
|
140
149
|
isInvalid={isInvalid}
|
|
141
150
|
onChange={onChange}
|
|
@@ -194,6 +203,7 @@ export function Input<T extends FieldValues>({
|
|
|
194
203
|
ref={ref}
|
|
195
204
|
disabled={disabled}
|
|
196
205
|
value={value}
|
|
206
|
+
placeholder={placeholder}
|
|
197
207
|
setValue={setValue as UseFormSetValue<FieldValues>}
|
|
198
208
|
setError={setError as UseFormSetError<FieldValues>}
|
|
199
209
|
clearErrors={clearErrors as UseFormClearErrors<FieldValues>}
|
|
@@ -234,7 +244,13 @@ export function Input<T extends FieldValues>({
|
|
|
234
244
|
position="relative"
|
|
235
245
|
py={label || helperText || isInvalid ? 6 : 0}
|
|
236
246
|
>
|
|
237
|
-
{label &&
|
|
247
|
+
{label && (
|
|
248
|
+
<Label
|
|
249
|
+
tooltipText={tooltipText}
|
|
250
|
+
label={label}
|
|
251
|
+
isRequired={isRequired}
|
|
252
|
+
/>
|
|
253
|
+
)}
|
|
238
254
|
{selectedInputField(
|
|
239
255
|
onChange ? onChange : fieldOnChange,
|
|
240
256
|
onBlur,
|
|
@@ -12,7 +12,6 @@ import FormError from './components/form-error';
|
|
|
12
12
|
import FormLabel from './components/form-label';
|
|
13
13
|
import Input from './components/input';
|
|
14
14
|
import Link from './components/link';
|
|
15
|
-
import Modal from './components/modal';
|
|
16
15
|
import Select from './components/select';
|
|
17
16
|
import Switch from './components/switch';
|
|
18
17
|
import Table from './components/table';
|
|
@@ -36,7 +35,6 @@ const customXQChakraTheme = extendTheme({
|
|
|
36
35
|
FormLabel,
|
|
37
36
|
Input,
|
|
38
37
|
Link,
|
|
39
|
-
Modal,
|
|
40
38
|
Select,
|
|
41
39
|
Switch,
|
|
42
40
|
Table,
|