@axinom/mosaic-ui 0.55.0-rc.1 → 0.55.0-rc.11
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/DynamicDataList/helpers/useColumnDefs.d.ts +1 -1
- package/dist/components/DynamicDataList/helpers/useColumnDefs.d.ts.map +1 -1
- 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/SingleLineText/SingleLineText.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/DynamicDataList.spec.tsx +1 -5
- package/src/components/DynamicDataList/DynamicDataList.tsx +1 -1
- 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/DynamicDataList/helpers/useColumnDefs.ts +4 -2
- package/src/components/FormElements/FileUploadControl/FileUploadControl.scss +2 -3
- package/src/components/FormElements/FileUploadControl/FileUploadControl.stories.tsx +0 -1
- package/src/components/FormElements/FileUploadControl/FileUploadControl.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/SingleLineText/SingleLineText.tsx +23 -7
- 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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axinom/mosaic-ui",
|
|
3
|
-
"version": "0.55.0-rc.
|
|
3
|
+
"version": "0.55.0-rc.11",
|
|
4
4
|
"description": "UI components for building Axinom Mosaic applications",
|
|
5
5
|
"author": "Axinom",
|
|
6
6
|
"license": "PROPRIETARY",
|
|
@@ -32,9 +32,10 @@
|
|
|
32
32
|
"build-storybook": "storybook build"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@axinom/mosaic-core": "^0.4.28-rc.
|
|
35
|
+
"@axinom/mosaic-core": "^0.4.28-rc.11",
|
|
36
36
|
"@faker-js/faker": "^7.4.0",
|
|
37
37
|
"@geoffcox/react-splitter": "^2.1.2",
|
|
38
|
+
"@mui/base": "5.0.0-beta.40",
|
|
38
39
|
"@popperjs/core": "^2.11.8",
|
|
39
40
|
"clsx": "^1.1.0",
|
|
40
41
|
"lodash": "^4.17.21",
|
|
@@ -106,5 +107,5 @@
|
|
|
106
107
|
"publishConfig": {
|
|
107
108
|
"access": "public"
|
|
108
109
|
},
|
|
109
|
-
"gitHead": "
|
|
110
|
+
"gitHead": "45f7a689961673ef06813544d1f2af49f7e352ee"
|
|
110
111
|
}
|
|
@@ -177,22 +177,18 @@ describe('DynamicDataList', () => {
|
|
|
177
177
|
const wrapper = shallow(<DynamicDataList {...defaultProps} />);
|
|
178
178
|
|
|
179
179
|
const header = wrapper.find(DynamicListHeader);
|
|
180
|
-
const container = wrapper.find('.container');
|
|
181
180
|
|
|
182
181
|
expect(header.exists()).toBe(true);
|
|
183
|
-
expect(container.hasClass('noHeader')).toBe(false);
|
|
184
182
|
});
|
|
185
183
|
|
|
186
|
-
it(`hides header row if 'showHeader' is false
|
|
184
|
+
it(`hides header row if 'showHeader' is false`, () => {
|
|
187
185
|
const wrapper = shallow(
|
|
188
186
|
<DynamicDataList {...defaultProps} showHeader={false} />,
|
|
189
187
|
);
|
|
190
188
|
|
|
191
189
|
const header = wrapper.find(DynamicListHeader);
|
|
192
|
-
const container = wrapper.find('.container');
|
|
193
190
|
|
|
194
191
|
expect(header.exists()).toBe(false);
|
|
195
|
-
expect(container.hasClass('noHeader')).toBe(true);
|
|
196
192
|
});
|
|
197
193
|
|
|
198
194
|
it(`sets 'positionKey' prop for DynamicListRow`, () => {
|
|
@@ -145,6 +145,7 @@ export const DynamicDataList = <T extends Data>({
|
|
|
145
145
|
columns,
|
|
146
146
|
allowReordering,
|
|
147
147
|
allowNewData,
|
|
148
|
+
allowEditing,
|
|
148
149
|
allowRowDragging,
|
|
149
150
|
positionPropertyName,
|
|
150
151
|
!!inlineMenuActions,
|
|
@@ -298,7 +299,6 @@ export const DynamicDataList = <T extends Data>({
|
|
|
298
299
|
<div
|
|
299
300
|
className={clsx(
|
|
300
301
|
classes.container,
|
|
301
|
-
{ [classes.noHeader]: !showHeader },
|
|
302
302
|
'dynamic-data-list-container',
|
|
303
303
|
className,
|
|
304
304
|
)}
|
|
@@ -44,12 +44,17 @@ describe('createSelectRenderer', () => {
|
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
it(`sets 'select' value to current value`, () => {
|
|
47
|
-
const
|
|
48
|
-
const wrapper = mount(
|
|
47
|
+
const mockOptions = [{ value: 'test-value', label: 'Test Value' }];
|
|
48
|
+
const wrapper = mount(
|
|
49
|
+
<RendererWrapper
|
|
50
|
+
currentValue={mockOptions[0].value}
|
|
51
|
+
options={mockOptions}
|
|
52
|
+
/>,
|
|
53
|
+
);
|
|
49
54
|
|
|
50
|
-
const
|
|
55
|
+
const input = wrapper.find('[role="combobox"]');
|
|
51
56
|
|
|
52
|
-
expect(
|
|
57
|
+
expect(input.prop('value')).toBe(mockOptions[0].label);
|
|
53
58
|
});
|
|
54
59
|
|
|
55
60
|
it(`emits 'onValueChange' with the new value when a new option has been selected`, () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { ChangeEvent } from 'react';
|
|
2
2
|
import { DynamicListDataEntryRenderer } from '../../../../DynamicDataList/DynamicDataList.model';
|
|
3
3
|
import { Select } from '../../../../FormElements';
|
|
4
4
|
import { CreateSelectRendererConfig } from '../renderers.model';
|
|
@@ -33,7 +33,7 @@ export const createSelectRenderer = ({
|
|
|
33
33
|
onValueChange(defaultValue);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const onChangeHandler = (e:
|
|
36
|
+
const onChangeHandler = (e: ChangeEvent<HTMLInputElement>): void => {
|
|
37
37
|
onValueChange(transform(e.currentTarget.value)); // emit onChange with transformed value
|
|
38
38
|
};
|
|
39
39
|
|
|
@@ -12,6 +12,7 @@ export const useColumnDefs = function <T extends Data>(
|
|
|
12
12
|
columns: DynamicListColumn<T>[],
|
|
13
13
|
allowReordering: boolean,
|
|
14
14
|
allowNewData: boolean,
|
|
15
|
+
allowEditing: boolean,
|
|
15
16
|
allowRowDragging: boolean,
|
|
16
17
|
positionKey?: keyof T,
|
|
17
18
|
showInlineMenu?: boolean,
|
|
@@ -30,7 +31,7 @@ export const useColumnDefs = function <T extends Data>(
|
|
|
30
31
|
allowReordering,
|
|
31
32
|
allowRowDragging,
|
|
32
33
|
positionKey,
|
|
33
|
-
allowNewData || showInlineMenu,
|
|
34
|
+
allowNewData || showInlineMenu || allowEditing,
|
|
34
35
|
),
|
|
35
36
|
);
|
|
36
37
|
|
|
@@ -43,13 +44,14 @@ export const useColumnDefs = function <T extends Data>(
|
|
|
43
44
|
allowReordering,
|
|
44
45
|
allowRowDragging,
|
|
45
46
|
positionKey,
|
|
46
|
-
allowNewData || showInlineMenu,
|
|
47
|
+
allowNewData || showInlineMenu || allowEditing,
|
|
47
48
|
),
|
|
48
49
|
);
|
|
49
50
|
if (!isResized) {
|
|
50
51
|
setColumnSizes(orgColumnSizes);
|
|
51
52
|
}
|
|
52
53
|
}, [
|
|
54
|
+
allowEditing,
|
|
53
55
|
allowNewData,
|
|
54
56
|
allowReordering,
|
|
55
57
|
allowRowDragging,
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
display: grid;
|
|
54
54
|
align-content: center;
|
|
55
55
|
color: var(--input-disabled-font-color, $input-disabled-font-color);
|
|
56
|
-
border: 1px
|
|
56
|
+
border: 1px dashed var(--file-upload-input, $file-upload-input);
|
|
57
57
|
background-color: var(
|
|
58
58
|
--read-only-text-background-color,
|
|
59
59
|
$read-only-text-background-color
|
|
@@ -80,13 +80,12 @@
|
|
|
80
80
|
display: grid;
|
|
81
81
|
align-content: center;
|
|
82
82
|
text-align: center;
|
|
83
|
-
border: 1px dashed var(--
|
|
83
|
+
border: 1px dashed var(--file-upload-input, $file-upload-input);
|
|
84
84
|
grid-column: 1 / span 2;
|
|
85
85
|
height: 100px;
|
|
86
86
|
width: 650px;
|
|
87
87
|
z-index: 9999;
|
|
88
88
|
|
|
89
|
-
background-color: white;
|
|
90
89
|
transition: box-shadow 0.15s ease-in-out 0s;
|
|
91
90
|
|
|
92
91
|
&:hover {
|
|
@@ -34,7 +34,7 @@ export const FileUploadControl: React.FC<FileUploadProps> = ({
|
|
|
34
34
|
onFileSelected,
|
|
35
35
|
error,
|
|
36
36
|
id = 'file',
|
|
37
|
-
placeholder,
|
|
37
|
+
placeholder = 'Browse or drag your file here',
|
|
38
38
|
value,
|
|
39
39
|
accept,
|
|
40
40
|
className = '',
|
|
@@ -138,7 +138,7 @@ export const FileUploadControl: React.FC<FileUploadProps> = ({
|
|
|
138
138
|
<div className={clsx(classes.content)}>
|
|
139
139
|
{dragging && !disabled ? (
|
|
140
140
|
<div className={clsx(classes.dropTarget)} onDrop={handleDrop}>
|
|
141
|
-
|
|
141
|
+
Drag & Drop your file here
|
|
142
142
|
</div>
|
|
143
143
|
) : (
|
|
144
144
|
<>
|
|
@@ -1,79 +1,128 @@
|
|
|
1
1
|
@import '../../../styles/common.scss';
|
|
2
2
|
|
|
3
|
-
@function svg-arrow-glyph($color) {
|
|
4
|
-
@return url('data:image/svg+xml;utf8,<svg stroke="' + $color + '" version="1.1" xmlns="http://www.w3.org/2000/svg" width="40px" height="20px" viewBox="0 0 40 40"><path vector-effect="non-scaling-stroke" fill="none" stroke-width="2" d="M38.5,9.5L20,30.5L1.5,9.5" /></svg>');
|
|
5
|
-
}
|
|
6
|
-
|
|
7
3
|
.container {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
appearance: none;
|
|
12
|
-
cursor: pointer;
|
|
13
|
-
color: var(--input-color, $input-color);
|
|
14
|
-
border: 1px solid var(--input-border-color, $input-border-color);
|
|
15
|
-
width: max-content;
|
|
16
|
-
outline: none;
|
|
17
|
-
font-size: var(--label-font-size, $label-font-size);
|
|
18
|
-
max-width: $select-max-width;
|
|
4
|
+
.inputWrapper {
|
|
5
|
+
position: relative;
|
|
6
|
+
max-width: var(--input-max-width, $input-max-width);
|
|
19
7
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
background-repeat: no-repeat;
|
|
25
|
-
background-position-y: center;
|
|
26
|
-
background-position-x: 100%;
|
|
8
|
+
.button {
|
|
9
|
+
position: absolute;
|
|
10
|
+
right: 0;
|
|
11
|
+
top: 0;
|
|
27
12
|
|
|
28
|
-
|
|
13
|
+
svg {
|
|
14
|
+
height: 50%;
|
|
15
|
+
* {
|
|
16
|
+
stroke: var(
|
|
17
|
+
--popper-trigger-button-color,
|
|
18
|
+
$popper-trigger-button-color
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
29
22
|
|
|
30
|
-
|
|
23
|
+
&:disabled {
|
|
24
|
+
svg * {
|
|
25
|
+
stroke: var(--select-arrow-color, $select-disabled-arrow-color);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
input {
|
|
31
|
+
color: var(--input-color, $input-color);
|
|
32
|
+
border: 1px solid var(--input-border-color, $input-border-color);
|
|
33
|
+
padding: 0 48px 0 12px;
|
|
34
|
+
display: inline-block;
|
|
35
|
+
font-size: var(--label-font-size, $label-font-size);
|
|
36
|
+
outline: none;
|
|
37
|
+
height: 50px;
|
|
38
|
+
width: 100%;
|
|
39
|
+
transition: box-shadow 0.15s ease-in-out 0s;
|
|
33
40
|
|
|
34
|
-
|
|
41
|
+
&::placeholder {
|
|
42
|
+
color: var(--input-placeholder-color, $input-placeholder-color);
|
|
43
|
+
}
|
|
35
44
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
&.hasError {
|
|
46
|
+
border: 1px solid
|
|
47
|
+
var(--input-invalid-border-color, $input-invalid-border-color);
|
|
48
|
+
}
|
|
40
49
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
&:disabled {
|
|
51
|
+
background-color: var(
|
|
52
|
+
--input-disabled-background-color,
|
|
53
|
+
$input-disabled-background-color
|
|
54
|
+
);
|
|
55
|
+
color: var(--input-disabled-font-color, $input-disabled-font-color);
|
|
56
|
+
border-color: var(
|
|
57
|
+
--input-disabled-border-color,
|
|
58
|
+
$input-disabled-border-color
|
|
59
|
+
);
|
|
60
|
+
}
|
|
46
61
|
|
|
47
|
-
|
|
62
|
+
&:hover:enabled,
|
|
63
|
+
&:focus {
|
|
64
|
+
border-color: var(--input-hover-color, $input-hover-color);
|
|
65
|
+
box-shadow: 0 0 0 2px var(--input-hover-color, $input-hover-color);
|
|
48
66
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
67
|
+
&.hasError {
|
|
68
|
+
border-color: var(
|
|
69
|
+
--input-invalid-border-color,
|
|
70
|
+
$input-invalid-border-color
|
|
71
|
+
);
|
|
72
|
+
box-shadow: 0 0 0 2px
|
|
73
|
+
var(--input-invalid-hover-color, $input-invalid-hover-color);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
&:disabled {
|
|
77
|
+
border-color: var(
|
|
78
|
+
--input-disabled-border-color,
|
|
79
|
+
$input-disabled-border-color
|
|
80
|
+
);
|
|
81
|
+
box-shadow: none;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
56
84
|
}
|
|
57
85
|
}
|
|
86
|
+
}
|
|
58
87
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
88
|
+
.popperContent {
|
|
89
|
+
ul {
|
|
90
|
+
display: grid;
|
|
91
|
+
row-gap: 1px;
|
|
92
|
+
background-color: var(--popper-background-color, $popper-background-color);
|
|
93
|
+
padding: 0px;
|
|
94
|
+
margin-top: 1px;
|
|
95
|
+
margin-bottom: 1px;
|
|
96
|
+
border: 1px solid var(--popper-border-color, $popper-border-color);
|
|
97
|
+
overflow-y: auto;
|
|
98
|
+
max-height: 509px;
|
|
99
|
+
|
|
100
|
+
li {
|
|
101
|
+
display: grid;
|
|
102
|
+
place-items: center left;
|
|
103
|
+
height: 50px;
|
|
104
|
+
font-size: var(--popper-item-font-size, $popper-item-font-size);
|
|
105
|
+
color: var(--popper-text-color, $popper-text-color);
|
|
106
|
+
background-color: white;
|
|
107
|
+
padding: 0 12px;
|
|
108
|
+
list-style: none;
|
|
109
|
+
cursor: default;
|
|
66
110
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
111
|
+
&:hover {
|
|
112
|
+
cursor: pointer;
|
|
113
|
+
background-color: var(
|
|
114
|
+
--popper-background-selected-color,
|
|
115
|
+
$popper-background-selected-color
|
|
116
|
+
);
|
|
117
|
+
}
|
|
71
118
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
119
|
+
&[aria-selected='true'],
|
|
120
|
+
&[class='Mui-focused Mui-focusVisible'] {
|
|
121
|
+
background-color: var(
|
|
122
|
+
--popper-background-selected-color,
|
|
123
|
+
$popper-background-selected-color
|
|
124
|
+
);
|
|
125
|
+
}
|
|
77
126
|
}
|
|
78
127
|
}
|
|
79
128
|
}
|
|
@@ -1,95 +1,104 @@
|
|
|
1
|
-
import { shallow } from 'enzyme';
|
|
1
|
+
import { mount, shallow } from 'enzyme';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { Select } from './Select';
|
|
4
4
|
|
|
5
|
+
const mockLabel = 'mockLabel';
|
|
6
|
+
|
|
7
|
+
const mockOptions = [
|
|
8
|
+
{
|
|
9
|
+
value: '1',
|
|
10
|
+
label: 'One',
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
value: '2',
|
|
14
|
+
label: 'Two',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
value: '3',
|
|
18
|
+
label: 'Three',
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
|
|
5
22
|
describe('Select', () => {
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
document.body.innerHTML = '';
|
|
25
|
+
});
|
|
26
|
+
|
|
6
27
|
it('renders the component without crashing', () => {
|
|
7
|
-
const wrapper = shallow(<Select name=
|
|
28
|
+
const wrapper = shallow(<Select name="test-name" options={[]} />);
|
|
8
29
|
|
|
9
30
|
expect(wrapper).toBeTruthy();
|
|
10
31
|
});
|
|
11
32
|
|
|
12
33
|
it('displays a label', () => {
|
|
13
|
-
const
|
|
14
|
-
|
|
34
|
+
const wrapper = shallow(
|
|
35
|
+
<Select name="test-name" label={mockLabel} options={[]} />,
|
|
36
|
+
);
|
|
15
37
|
|
|
16
|
-
const label = wrapper.dive().find('label');
|
|
38
|
+
const label = wrapper.dive().find('[data-test-id="form-field-label"]');
|
|
17
39
|
|
|
18
40
|
expect(label.text()).toBe(mockLabel);
|
|
19
41
|
});
|
|
20
42
|
|
|
21
|
-
it('
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
disabled: true,
|
|
26
|
-
id: 'test-id',
|
|
27
|
-
name: 'test-name',
|
|
28
|
-
onBlur: () => null,
|
|
29
|
-
onChange: () => null,
|
|
30
|
-
onFocus: () => null,
|
|
31
|
-
} as Record<string, unknown>;
|
|
32
|
-
|
|
33
|
-
const wrapper = shallow(<Select name="test-name" {...mockProps} />);
|
|
43
|
+
it('the given value must be filled in input', () => {
|
|
44
|
+
const wrapper = mount(
|
|
45
|
+
<Select name={'test-name'} options={mockOptions} value="2" />,
|
|
46
|
+
);
|
|
34
47
|
|
|
35
|
-
const
|
|
48
|
+
const input = wrapper.find('[role="combobox"]');
|
|
36
49
|
|
|
37
|
-
expect(
|
|
50
|
+
expect(input.prop('value')).toEqual(mockOptions[1].label);
|
|
38
51
|
});
|
|
39
52
|
|
|
40
|
-
it('
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
const mockValueUpdated = 'updated-test-value';
|
|
44
|
-
const wrapper = shallow(
|
|
45
|
-
<Select name="test-name" value={mockValue} onChange={spy} />,
|
|
53
|
+
it('the popper must be rendered on input click', () => {
|
|
54
|
+
const wrapper = mount(
|
|
55
|
+
<Select name={'test-name'} options={mockOptions} value="2" />,
|
|
46
56
|
);
|
|
57
|
+
const input = wrapper.find('[role="combobox"]');
|
|
58
|
+
input.simulate('mousedown');
|
|
47
59
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
expect(select.prop('value')).toEqual(mockValue);
|
|
51
|
-
|
|
52
|
-
select.simulate('change', { target: { value: mockValueUpdated } });
|
|
53
|
-
|
|
54
|
-
expect(spy).toHaveBeenCalledTimes(1);
|
|
55
|
-
expect(spy).toHaveBeenCalledWith({ target: { value: mockValueUpdated } });
|
|
60
|
+
const popper = document.querySelector('[role="tooltip"]');
|
|
61
|
+
expect(popper).not.toBeNull();
|
|
56
62
|
});
|
|
57
63
|
|
|
58
64
|
it('raises change, blur, and focus events', () => {
|
|
59
65
|
const changeSpy = jest.fn();
|
|
60
66
|
const blurSpy = jest.fn();
|
|
61
67
|
const focusSpy = jest.fn();
|
|
62
|
-
const wrapper =
|
|
68
|
+
const wrapper = mount(
|
|
63
69
|
<Select
|
|
64
70
|
name={'test-name'}
|
|
65
71
|
onChange={changeSpy}
|
|
66
72
|
onBlur={blurSpy}
|
|
67
73
|
onFocus={focusSpy}
|
|
74
|
+
options={mockOptions}
|
|
68
75
|
/>,
|
|
69
76
|
);
|
|
70
77
|
|
|
71
|
-
const
|
|
78
|
+
const input = wrapper.find('[role="combobox"]');
|
|
79
|
+
input.simulate('mousedown');
|
|
80
|
+
const firstOption = document.querySelector('[role="option"]');
|
|
81
|
+
firstOption?.dispatchEvent(new Event('click', { bubbles: true }));
|
|
72
82
|
|
|
73
|
-
select.simulate('change');
|
|
74
83
|
expect(changeSpy).toHaveBeenCalledTimes(1);
|
|
75
84
|
|
|
76
|
-
|
|
85
|
+
input.simulate('blur');
|
|
77
86
|
expect(blurSpy).toHaveBeenCalledTimes(1);
|
|
78
87
|
|
|
79
|
-
|
|
88
|
+
input.simulate('focus');
|
|
80
89
|
expect(focusSpy).toHaveBeenCalledTimes(1);
|
|
81
90
|
});
|
|
82
91
|
|
|
83
92
|
it('applies error styling and renders error message when an error is passed', () => {
|
|
84
93
|
const mockErrorMessage = 'test-error-message';
|
|
85
94
|
const wrapper = shallow(
|
|
86
|
-
<Select name={'test-name'} error={mockErrorMessage} />,
|
|
95
|
+
<Select name={'test-name'} error={mockErrorMessage} options={[]} />,
|
|
87
96
|
);
|
|
88
97
|
|
|
89
|
-
const errorMsg = wrapper.dive().find('
|
|
90
|
-
const
|
|
98
|
+
const errorMsg = wrapper.dive().find('[data-test-id="form-field-error"]');
|
|
99
|
+
const input = wrapper.find('[role="combobox"]');
|
|
91
100
|
|
|
92
101
|
expect(errorMsg.text()).toBe(mockErrorMessage);
|
|
93
|
-
expect(
|
|
102
|
+
expect(input.hasClass('hasError')).toBe(true);
|
|
94
103
|
});
|
|
95
104
|
});
|
|
@@ -6,14 +6,7 @@ import { createGroups } from '../../../helpers/storybook';
|
|
|
6
6
|
import { Select } from './Select';
|
|
7
7
|
|
|
8
8
|
const groups = createGroups({
|
|
9
|
-
Behavior: [
|
|
10
|
-
'autoFocus',
|
|
11
|
-
'disabled',
|
|
12
|
-
'inlineMode',
|
|
13
|
-
'name',
|
|
14
|
-
'id',
|
|
15
|
-
'addEmptyOption',
|
|
16
|
-
],
|
|
9
|
+
Behavior: ['autoFocus', 'disabled', 'inlineMode', 'name', 'id'],
|
|
17
10
|
Content: ['label', 'options', 'error', 'tooltipContent', 'value'],
|
|
18
11
|
Styling: ['className'],
|
|
19
12
|
Events: ['onChange', 'onBlur', 'onFocus'],
|
|
@@ -26,6 +19,7 @@ const meta: Meta<typeof Select> = {
|
|
|
26
19
|
...groups,
|
|
27
20
|
},
|
|
28
21
|
};
|
|
22
|
+
|
|
29
23
|
export default meta;
|
|
30
24
|
|
|
31
25
|
export const Main: StoryObj<typeof Select> = {
|
|
@@ -37,14 +31,18 @@ export const Main: StoryObj<typeof Select> = {
|
|
|
37
31
|
{ value: '2', label: 'Two' },
|
|
38
32
|
{ value: '3', label: 'Three' },
|
|
39
33
|
{ value: '4', label: 'Four' },
|
|
34
|
+
{ value: '5', label: 'Five' },
|
|
35
|
+
{ value: '6', label: 'Six' },
|
|
36
|
+
{ value: '7', label: 'Seven' },
|
|
37
|
+
{ value: '8', label: 'Eight' },
|
|
38
|
+
{ value: '9', label: 'Nine' },
|
|
39
|
+
{ value: '10', label: 'Ten' },
|
|
40
40
|
],
|
|
41
41
|
tooltipContent: faker.lorem.paragraph(2),
|
|
42
|
-
addEmptyOption: false,
|
|
43
42
|
},
|
|
44
43
|
render: (args) =>
|
|
45
44
|
React.createElement(() => {
|
|
46
45
|
const [value, setValue] = useState(args.value);
|
|
47
|
-
|
|
48
46
|
return (
|
|
49
47
|
<Select
|
|
50
48
|
{...args}
|