@axinom/mosaic-ui 0.55.0-rc.5 → 0.55.0-rc.7
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/FormElements/Select/Select.d.ts +15 -11
- package/dist/components/FormElements/Select/Select.d.ts.map +1 -1
- package/dist/components/FormElements/Select/SelectField.d.ts.map +1 -1
- package/dist/components/FormElements/Tags/Tags.d.ts +2 -2
- package/dist/components/FormElements/Tags/Tags.d.ts.map +1 -1
- package/dist/components/FormElements/Tags/TagsField.d.ts +1 -1
- package/dist/components/FormElements/Tags/TagsField.d.ts.map +1 -1
- package/dist/index.es.js +4 -4
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/src/components/DynamicDataList/DynamicListDataEntry/Renderers/createSelectRenderer/createSelectRenderer.spec.tsx +9 -4
- package/src/components/DynamicDataList/DynamicListDataEntry/Renderers/createSelectRenderer/createSelectRenderer.tsx +2 -2
- package/src/components/FormElements/Select/Select.scss +108 -59
- package/src/components/FormElements/Select/Select.spec.tsx +52 -43
- package/src/components/FormElements/Select/Select.stories.tsx +8 -10
- package/src/components/FormElements/Select/Select.tsx +138 -52
- package/src/components/FormElements/Select/SelectField.tsx +1 -0
- package/src/components/FormElements/Tags/Tags.scss +16 -76
- package/src/components/FormElements/Tags/Tags.spec.tsx +69 -80
- package/src/components/FormElements/Tags/Tags.tsx +54 -62
- package/src/components/FormElements/Tags/TagsField.tsx +3 -13
- package/src/styles/variables.scss +8 -0
|
@@ -10,6 +10,22 @@
|
|
|
10
10
|
flex-flow: wrap;
|
|
11
11
|
gap: 10px;
|
|
12
12
|
|
|
13
|
+
.hasError {
|
|
14
|
+
input {
|
|
15
|
+
border: 1px solid
|
|
16
|
+
var(--input-invalid-border-color, $input-invalid-border-color);
|
|
17
|
+
|
|
18
|
+
&:hover {
|
|
19
|
+
border-color: var(
|
|
20
|
+
--input-invalid-border-color,
|
|
21
|
+
$input-invalid-border-color
|
|
22
|
+
);
|
|
23
|
+
box-shadow: 0 0 0 2px
|
|
24
|
+
var(--input-invalid-hover-color, $input-invalid-hover-color);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
13
29
|
.selectedItem {
|
|
14
30
|
width: max-content;
|
|
15
31
|
display: grid;
|
|
@@ -38,82 +54,6 @@
|
|
|
38
54
|
display: block;
|
|
39
55
|
grid-template-columns: none;
|
|
40
56
|
}
|
|
41
|
-
|
|
42
|
-
select {
|
|
43
|
-
-moz-appearance: none;
|
|
44
|
-
-webkit-appearance: none;
|
|
45
|
-
appearance: none;
|
|
46
|
-
|
|
47
|
-
color: var(--input-color, $input-color);
|
|
48
|
-
border: 1px solid var(--input-border-color, $input-border-color);
|
|
49
|
-
|
|
50
|
-
font-size: var(--label-font-size, $label-font-size);
|
|
51
|
-
|
|
52
|
-
height: 50px;
|
|
53
|
-
max-width: $tags-max-width;
|
|
54
|
-
|
|
55
|
-
padding: 0 40px 0 12px;
|
|
56
|
-
|
|
57
|
-
// CSS variables will not work inside the background-image url - we still pass it in there for consistency reasons.
|
|
58
|
-
background-image: svg-arrow-glyph(
|
|
59
|
-
var(--select-arrow-color, encodecolor($select-arrow-color))
|
|
60
|
-
);
|
|
61
|
-
background-repeat: no-repeat;
|
|
62
|
-
background-position-y: center;
|
|
63
|
-
background-position-x: 100%;
|
|
64
|
-
|
|
65
|
-
background-color: var(
|
|
66
|
-
--select-background-color,
|
|
67
|
-
$select-background-color
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
cursor: pointer;
|
|
71
|
-
outline: none;
|
|
72
|
-
|
|
73
|
-
transition: box-shadow 0.15s ease-in-out 0s;
|
|
74
|
-
|
|
75
|
-
&.hasError {
|
|
76
|
-
border: 1px solid
|
|
77
|
-
var(--input-invalid-border-color, $input-invalid-border-color);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
&:disabled {
|
|
81
|
-
border-color: var(
|
|
82
|
-
--input-disabled-border-color,
|
|
83
|
-
$input-disabled-border-color
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
cursor: default;
|
|
87
|
-
|
|
88
|
-
background-image: svg-arrow-glyph(
|
|
89
|
-
var(--select-arrow-color, encodecolor($select-disabled-arrow-color))
|
|
90
|
-
);
|
|
91
|
-
background-color: var(
|
|
92
|
-
--input-disabled-background-color,
|
|
93
|
-
$input-disabled-background-color
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
select,
|
|
99
|
-
option {
|
|
100
|
-
width: 325px;
|
|
101
|
-
overflow: hidden;
|
|
102
|
-
white-space: nowrap;
|
|
103
|
-
text-overflow: ellipsis;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
select:hover:enabled {
|
|
107
|
-
border: 1px solid var(--input-hover-color, $input-hover-color);
|
|
108
|
-
box-shadow: 0 0 0 2px var(--input-hover-color, $input-hover-color);
|
|
109
|
-
|
|
110
|
-
&.hasError {
|
|
111
|
-
border: 1px solid
|
|
112
|
-
var(--input-invalid-border-color, $input-invalid-border-color);
|
|
113
|
-
box-shadow: 0 0 0 2px
|
|
114
|
-
var(--input-invalid-hover-color, $input-invalid-hover-color);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
57
|
}
|
|
118
58
|
}
|
|
119
59
|
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import { mount, shallow } from 'enzyme';
|
|
1
|
+
import { mount, ReactWrapper, shallow } from 'enzyme';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { act } from 'react-dom/test-utils';
|
|
4
3
|
import { Button } from '../../Buttons';
|
|
4
|
+
import { Select } from '../Select/Select';
|
|
5
5
|
import { Tags } from './Tags';
|
|
6
6
|
|
|
7
|
+
function selectFirstOption(wrapper: ReactWrapper) {
|
|
8
|
+
const input = wrapper.find('[role="combobox"]');
|
|
9
|
+
input.simulate('mousedown');
|
|
10
|
+
const firstOption = document.querySelector('[role="option"]');
|
|
11
|
+
firstOption?.dispatchEvent(new Event('click', { bubbles: true }));
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
describe('Tags', () => {
|
|
8
15
|
it('renders the component without crashing', () => {
|
|
9
16
|
const wrapper = shallow(<Tags name={'test-name'} />);
|
|
@@ -41,61 +48,54 @@ describe('Tags', () => {
|
|
|
41
48
|
});
|
|
42
49
|
});
|
|
43
50
|
|
|
44
|
-
it('raises onChange when selecting a tag along with the new value',
|
|
45
|
-
const
|
|
51
|
+
it('raises onChange when selecting a tag along with the new value', () => {
|
|
52
|
+
const changeSpy = jest.fn();
|
|
46
53
|
const mockValue: string[] = ['1'];
|
|
47
|
-
const mockValueUpdated = '2';
|
|
48
54
|
const wrapper = mount(
|
|
49
|
-
<Tags
|
|
55
|
+
<Tags
|
|
56
|
+
name={'test-name'}
|
|
57
|
+
onChange={changeSpy}
|
|
58
|
+
value={mockValue}
|
|
59
|
+
tagsOptions={['1', '2']}
|
|
60
|
+
/>,
|
|
50
61
|
);
|
|
51
62
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
await act(async () => {
|
|
55
|
-
await select.simulate('change', {
|
|
56
|
-
currentTarget: { value: mockValueUpdated },
|
|
57
|
-
persist: jest.fn(),
|
|
58
|
-
});
|
|
59
|
-
wrapper.update();
|
|
60
|
-
});
|
|
63
|
+
selectFirstOption(wrapper);
|
|
61
64
|
|
|
62
|
-
expect(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// });
|
|
65
|
+
expect(changeSpy).toHaveBeenCalledTimes(1);
|
|
66
|
+
expect(changeSpy).toHaveBeenCalledWith(
|
|
67
|
+
expect.objectContaining({
|
|
68
|
+
currentTarget: expect.objectContaining({ value: ['1', '2'] }),
|
|
69
|
+
}),
|
|
70
|
+
);
|
|
69
71
|
});
|
|
70
72
|
|
|
71
|
-
it('raises onChange when removing a tag along with the new value',
|
|
72
|
-
const
|
|
73
|
+
it('raises onChange when removing a tag along with the new value', () => {
|
|
74
|
+
const changeSpy = jest.fn();
|
|
73
75
|
const mockValue: string[] = ['1'];
|
|
74
76
|
const wrapper = mount(
|
|
75
77
|
<Tags
|
|
76
78
|
name={'test-name'}
|
|
77
|
-
onChange={
|
|
79
|
+
onChange={changeSpy}
|
|
78
80
|
value={mockValue}
|
|
79
81
|
tagsOptions={['1', '2']}
|
|
80
82
|
/>,
|
|
81
83
|
);
|
|
82
84
|
|
|
83
|
-
const x = wrapper.find('
|
|
85
|
+
const x = wrapper.find('[data-test-id="tags-delete"]');
|
|
84
86
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
persist: jest.fn(),
|
|
88
|
-
});
|
|
89
|
-
wrapper.update();
|
|
87
|
+
x.simulate('click', {
|
|
88
|
+
persist: jest.fn(),
|
|
90
89
|
});
|
|
91
90
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
91
|
+
wrapper.update();
|
|
92
|
+
|
|
93
|
+
expect(changeSpy).toHaveBeenCalledTimes(1);
|
|
94
|
+
expect(changeSpy).toHaveBeenCalledWith(
|
|
95
|
+
expect.objectContaining({
|
|
96
|
+
currentTarget: expect.objectContaining({ value: [] }),
|
|
97
|
+
}),
|
|
98
|
+
);
|
|
99
99
|
});
|
|
100
100
|
|
|
101
101
|
it('shows select element when current selected tags and optional tags are the not same length', () => {
|
|
@@ -103,37 +103,38 @@ describe('Tags', () => {
|
|
|
103
103
|
<Tags name={'test-name'} value={['1']} tagsOptions={['1', '2']} />,
|
|
104
104
|
);
|
|
105
105
|
|
|
106
|
-
const select = wrapper.find(
|
|
106
|
+
const select = wrapper.find(Select);
|
|
107
107
|
|
|
108
|
-
expect(select
|
|
108
|
+
expect(select).toHaveLength(1);
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
it('hides select element when current selected tags and optional tags are the same length', () => {
|
|
112
|
-
const wrapper =
|
|
112
|
+
const wrapper = mount(
|
|
113
113
|
<Tags name={'test-name'} value={['1']} tagsOptions={['1', '2']} />,
|
|
114
114
|
);
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
selectFirstOption(wrapper);
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
wrapper.update();
|
|
119
119
|
|
|
120
|
-
select.
|
|
121
|
-
currentTarget: { value: '2' },
|
|
122
|
-
persist: jest.fn(),
|
|
123
|
-
});
|
|
124
|
-
select = wrapper.find('select');
|
|
120
|
+
const select = wrapper.find(Select);
|
|
125
121
|
|
|
126
|
-
expect(select
|
|
122
|
+
expect(select).toHaveLength(0);
|
|
127
123
|
});
|
|
128
124
|
|
|
129
125
|
it('raises blur and focus events', () => {
|
|
130
126
|
const blurSpy = jest.fn();
|
|
131
127
|
const focusSpy = jest.fn();
|
|
132
128
|
const wrapper = shallow(
|
|
133
|
-
<Tags
|
|
129
|
+
<Tags
|
|
130
|
+
name={'test-name'}
|
|
131
|
+
onBlur={blurSpy}
|
|
132
|
+
onFocus={focusSpy}
|
|
133
|
+
tagsOptions={['1']}
|
|
134
|
+
/>,
|
|
134
135
|
);
|
|
135
136
|
|
|
136
|
-
const select = wrapper.find(
|
|
137
|
+
const select = wrapper.find(Select);
|
|
137
138
|
|
|
138
139
|
select.simulate('blur');
|
|
139
140
|
expect(blurSpy).toHaveBeenCalledTimes(1);
|
|
@@ -166,7 +167,7 @@ describe('Tags', () => {
|
|
|
166
167
|
});
|
|
167
168
|
|
|
168
169
|
it('uses the displayValue for available tags when tagOptions are objects', () => {
|
|
169
|
-
const wrapper =
|
|
170
|
+
const wrapper = mount(
|
|
170
171
|
<Tags
|
|
171
172
|
name={'test-name'}
|
|
172
173
|
value={['1', '3']}
|
|
@@ -181,43 +182,31 @@ describe('Tags', () => {
|
|
|
181
182
|
/>,
|
|
182
183
|
);
|
|
183
184
|
|
|
184
|
-
const
|
|
185
|
+
const input = wrapper.find('[role="combobox"]');
|
|
186
|
+
input.simulate('mousedown');
|
|
185
187
|
|
|
186
|
-
|
|
188
|
+
const popper = document.querySelector('[role="tooltip"]');
|
|
189
|
+
|
|
190
|
+
const options = popper?.querySelectorAll('[role="option"]');
|
|
191
|
+
|
|
192
|
+
expect(options).toHaveLength(2);
|
|
187
193
|
|
|
188
|
-
expect(
|
|
194
|
+
expect([options?.[0].innerHTML, options?.[1].innerHTML]).toEqual([
|
|
195
|
+
'Test2',
|
|
196
|
+
'Test4',
|
|
197
|
+
]);
|
|
189
198
|
});
|
|
190
199
|
|
|
191
200
|
it('applies error styling and renders error message when an error is passed', () => {
|
|
192
201
|
const mockErrorMessage = 'test-error-message';
|
|
193
|
-
const wrapper =
|
|
194
|
-
<Tags name={'test-name'} error={mockErrorMessage} />,
|
|
202
|
+
const wrapper = mount(
|
|
203
|
+
<Tags name={'test-name'} error={mockErrorMessage} tagsOptions={['1']} />,
|
|
195
204
|
);
|
|
196
205
|
|
|
197
|
-
const errorMsg = wrapper.
|
|
198
|
-
const
|
|
206
|
+
const errorMsg = wrapper.find('small');
|
|
207
|
+
const select = wrapper.find(Select);
|
|
199
208
|
|
|
200
209
|
expect(errorMsg.text()).toBe(mockErrorMessage);
|
|
201
|
-
expect(
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it('defaults drop down label and value to empty strings', () => {
|
|
205
|
-
const wrapper = shallow(<Tags name={'test-name'} />);
|
|
206
|
-
|
|
207
|
-
const options = wrapper.find('option');
|
|
208
|
-
|
|
209
|
-
expect(options.at(0).text()).toBe('');
|
|
210
|
-
expect(options.at(0).prop('value')).toBe('');
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it('displays a label for the drop down', () => {
|
|
214
|
-
const mockDropDownLabel = 'mockLabel';
|
|
215
|
-
const wrapper = shallow(
|
|
216
|
-
<Tags name={'test-name'} dropDownLabel={mockDropDownLabel} />,
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
const options = wrapper.find('option');
|
|
220
|
-
|
|
221
|
-
expect(options.at(0).text()).toBe(mockDropDownLabel);
|
|
210
|
+
expect(select.hasClass('hasError')).toBe(true);
|
|
222
211
|
});
|
|
223
212
|
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import React, {
|
|
3
|
-
|
|
3
|
+
ChangeEvent,
|
|
4
4
|
PropsWithChildren,
|
|
5
5
|
useEffect,
|
|
6
|
+
useMemo,
|
|
6
7
|
useRef,
|
|
7
8
|
useState,
|
|
8
9
|
} from 'react';
|
|
@@ -10,13 +11,14 @@ import { CSSTransition, TransitionGroup } from 'react-transition-group';
|
|
|
10
11
|
import { noop } from '../../../helpers/utils';
|
|
11
12
|
import { Button, ButtonContext } from '../../Buttons';
|
|
12
13
|
import { IconName } from '../../Icons';
|
|
13
|
-
import { BaseFormControl,
|
|
14
|
+
import { BaseFormControl, BaseInputEvents } from '../Form.models';
|
|
14
15
|
import { FormElementContainer } from '../FormElementContainer';
|
|
16
|
+
import { Select, SelectOption } from '../Select/Select';
|
|
15
17
|
import classes from './Tags.scss';
|
|
16
18
|
|
|
17
19
|
export interface TagsProps<T = string>
|
|
18
20
|
extends BaseFormControl,
|
|
19
|
-
|
|
21
|
+
BaseInputEvents {
|
|
20
22
|
/** If set, sets the form control value */
|
|
21
23
|
value?: string[];
|
|
22
24
|
/** Array of options that can be selected from */
|
|
@@ -52,33 +54,54 @@ export const Tags = <T,>({
|
|
|
52
54
|
|
|
53
55
|
const [shouldAnimate, setShouldAnimate] = useState<boolean>(false);
|
|
54
56
|
|
|
55
|
-
const ref = useRef<
|
|
57
|
+
const ref = useRef<ChangeEvent<HTMLInputElement>>();
|
|
58
|
+
|
|
59
|
+
const transformedOptions: SelectOption[] = useMemo(() => {
|
|
60
|
+
return tagsOptions.map((option) => {
|
|
61
|
+
if (valueKey && displayKey) {
|
|
62
|
+
return {
|
|
63
|
+
value: String(option[valueKey]),
|
|
64
|
+
label: String(option[displayKey]),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return { value: String(option), label: String(option) };
|
|
68
|
+
});
|
|
69
|
+
}, [displayKey, tagsOptions, valueKey]);
|
|
70
|
+
|
|
71
|
+
const visibleOptions = useMemo(() => {
|
|
72
|
+
return transformedOptions.filter(
|
|
73
|
+
(option) => !currentTags.includes(String(option.value)),
|
|
74
|
+
);
|
|
75
|
+
}, [currentTags, transformedOptions]);
|
|
56
76
|
|
|
57
77
|
useEffect(() => {
|
|
58
78
|
setCurrentTags(value);
|
|
59
79
|
}, [value]);
|
|
60
80
|
|
|
61
|
-
const errorMsg: string | undefined = error;
|
|
62
|
-
|
|
63
81
|
useEffect(() => {
|
|
64
82
|
// Only emit if there is a current event
|
|
65
83
|
if (ref.current) {
|
|
66
84
|
onChange({
|
|
67
85
|
...ref.current,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
86
|
+
target: {
|
|
87
|
+
...ref.current.target,
|
|
88
|
+
value: currentTags as unknown as string,
|
|
89
|
+
name,
|
|
90
|
+
id,
|
|
91
|
+
},
|
|
92
|
+
currentTarget: { name, id, value: currentTags as unknown as string },
|
|
93
|
+
} as ChangeEvent<HTMLInputElement>);
|
|
71
94
|
|
|
72
95
|
// Resets event data
|
|
73
96
|
ref.current = undefined;
|
|
74
97
|
}
|
|
75
|
-
}, [currentTags, onChange]);
|
|
98
|
+
}, [currentTags, id, name, onChange]);
|
|
76
99
|
|
|
77
100
|
/**
|
|
78
101
|
* Adds a tag to currently selected list
|
|
79
102
|
* @param e Select FormEvent
|
|
80
103
|
*/
|
|
81
|
-
function addTag(e:
|
|
104
|
+
function addTag(e: ChangeEvent<HTMLInputElement>): void {
|
|
82
105
|
setShouldAnimate(true);
|
|
83
106
|
|
|
84
107
|
const newTag = e.currentTarget.value;
|
|
@@ -96,7 +119,7 @@ export const Tags = <T,>({
|
|
|
96
119
|
*/
|
|
97
120
|
function removeTag(idx: number, e: unknown): void {
|
|
98
121
|
// Set event data
|
|
99
|
-
ref.current = e as
|
|
122
|
+
ref.current = e as ChangeEvent<HTMLInputElement>;
|
|
100
123
|
|
|
101
124
|
setCurrentTags((prevState) =>
|
|
102
125
|
prevState.filter((_: string, i: number) => i !== idx),
|
|
@@ -119,59 +142,28 @@ export const Tags = <T,>({
|
|
|
119
142
|
<FormElementContainer
|
|
120
143
|
{...rest}
|
|
121
144
|
className={clsx(classes.container, 'tags-container', className)}
|
|
122
|
-
error={
|
|
145
|
+
error={error}
|
|
123
146
|
dataTestFieldType="Tags"
|
|
124
147
|
>
|
|
125
148
|
<div className={clsx(classes.tagsWrapper)}>
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
</option>,
|
|
145
|
-
].concat(
|
|
146
|
-
tagsOptions
|
|
147
|
-
.filter((currentTag: T) => {
|
|
148
|
-
if (typeof currentTag === 'string') {
|
|
149
|
-
return !currentTags.includes(currentTag);
|
|
150
|
-
} else if (valueKey) {
|
|
151
|
-
return !currentTags.includes(String(currentTag[valueKey]));
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
.map((option) => {
|
|
155
|
-
if (typeof option === 'string') {
|
|
156
|
-
return (
|
|
157
|
-
<option key={option} value={option}>
|
|
158
|
-
{option}
|
|
159
|
-
</option>
|
|
160
|
-
);
|
|
161
|
-
} else if (valueKey && displayKey) {
|
|
162
|
-
return (
|
|
163
|
-
<option
|
|
164
|
-
key={String(option[valueKey])}
|
|
165
|
-
value={String(option[valueKey])}
|
|
166
|
-
>
|
|
167
|
-
{String(option[displayKey])}
|
|
168
|
-
</option>
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
return <></>;
|
|
172
|
-
}),
|
|
173
|
-
)}
|
|
174
|
-
</select>
|
|
149
|
+
{currentTags.length < tagsOptions.length ? (
|
|
150
|
+
<Select
|
|
151
|
+
id={id}
|
|
152
|
+
name={`tags-select-${name}`}
|
|
153
|
+
className={clsx({
|
|
154
|
+
[classes.hasError]: error !== undefined,
|
|
155
|
+
})}
|
|
156
|
+
options={visibleOptions}
|
|
157
|
+
onChange={addTag}
|
|
158
|
+
blurOnSelect
|
|
159
|
+
disabled={disabled}
|
|
160
|
+
onBlur={onBlur}
|
|
161
|
+
onFocus={onFocus}
|
|
162
|
+
autoFocus={autoFocus}
|
|
163
|
+
inlineMode={true}
|
|
164
|
+
placeholder={dropDownLabel}
|
|
165
|
+
/>
|
|
166
|
+
) : null}
|
|
175
167
|
<TransitionGroup component={null}>
|
|
176
168
|
{currentTags.map((tag, idx) => (
|
|
177
169
|
<CSSTransition
|
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
import { useField } from 'formik';
|
|
2
1
|
import React, { PropsWithChildren } from 'react';
|
|
3
2
|
import { useFormikError } from '../useFormikError';
|
|
4
3
|
import { Tags, TagsProps } from './Tags';
|
|
5
4
|
export const TagsField = <T,>(
|
|
6
|
-
props: PropsWithChildren<Omit<TagsProps<T>, 'error'
|
|
5
|
+
props: PropsWithChildren<Omit<TagsProps<T>, 'error'>>,
|
|
7
6
|
): JSX.Element => {
|
|
8
|
-
const
|
|
9
|
-
const error = useFormikError(name);
|
|
10
|
-
const [field, , helpers] = useField(name);
|
|
7
|
+
const error = useFormikError(props.name);
|
|
11
8
|
|
|
12
|
-
return
|
|
13
|
-
<Tags
|
|
14
|
-
{...props}
|
|
15
|
-
value={field.value}
|
|
16
|
-
error={error}
|
|
17
|
-
onChange={(e) => helpers.setValue(e.currentTarget.value)}
|
|
18
|
-
/>
|
|
19
|
-
);
|
|
9
|
+
return <Tags {...props} error={error} />;
|
|
20
10
|
};
|
|
@@ -311,3 +311,11 @@ $context-button-hover-border-color: $blue;
|
|
|
311
311
|
$context-button-active-color: $blue;
|
|
312
312
|
$icon-button-stroke-color: $blue;
|
|
313
313
|
$icon-button-hover-color: $blue;
|
|
314
|
+
|
|
315
|
+
/* Autocomplete */
|
|
316
|
+
$popper-border-color: $blue;
|
|
317
|
+
$popper-trigger-button-color: $blue;
|
|
318
|
+
$popper-background-color: $light-gray-2;
|
|
319
|
+
$popper-item-font-size: 16px;
|
|
320
|
+
$popper-text-color: $blue;
|
|
321
|
+
$popper-background-selected-color: rgba($blue, 0.15);
|