@transferwise/components 0.0.0-experimental-60cb1a1 → 0.0.0-experimental-69a95e1
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/build/avatarLayout/AvatarLayout.js +1 -2
- package/build/avatarLayout/AvatarLayout.js.map +1 -1
- package/build/avatarLayout/AvatarLayout.mjs +1 -2
- package/build/avatarLayout/AvatarLayout.mjs.map +1 -1
- package/build/button/Button.js +2 -1
- package/build/button/Button.js.map +1 -1
- package/build/button/Button.mjs +2 -1
- package/build/button/Button.mjs.map +1 -1
- package/build/index.js +0 -2
- package/build/index.js.map +1 -1
- package/build/index.mjs +0 -1
- package/build/index.mjs.map +1 -1
- package/build/main.css +4 -2
- package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.js +1 -1
- package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.js.map +1 -1
- package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.mjs +1 -1
- package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.mjs.map +1 -1
- package/build/primitives/PrimitiveButton/src/PrimitiveButton.js +2 -1
- package/build/primitives/PrimitiveButton/src/PrimitiveButton.js.map +1 -1
- package/build/primitives/PrimitiveButton/src/PrimitiveButton.mjs +2 -1
- package/build/primitives/PrimitiveButton/src/PrimitiveButton.mjs.map +1 -1
- package/build/styles/avatarLayout/AvatarLayout.css +1 -2
- package/build/styles/button/Button.css +3 -0
- package/build/styles/main.css +4 -2
- package/build/types/avatarLayout/AvatarLayout.d.ts.map +1 -1
- package/build/types/button/Button.d.ts.map +1 -1
- package/build/types/index.d.ts +0 -2
- package/build/types/index.d.ts.map +1 -1
- package/build/types/primitives/PrimitiveButton/src/PrimitiveButton.d.ts.map +1 -1
- package/build/types/uploadInput/uploadButton/getAllowedFileTypes.d.ts.map +1 -1
- package/build/uploadInput/uploadButton/getAllowedFileTypes.js +3 -23
- package/build/uploadInput/uploadButton/getAllowedFileTypes.js.map +1 -1
- package/build/uploadInput/uploadButton/getAllowedFileTypes.mjs +3 -23
- package/build/uploadInput/uploadButton/getAllowedFileTypes.mjs.map +1 -1
- package/package.json +5 -5
- package/src/avatarLayout/AvatarLayout.css +1 -2
- package/src/avatarLayout/AvatarLayout.less +1 -1
- package/src/avatarLayout/AvatarLayout.tsx +0 -1
- package/src/button/Button.css +3 -0
- package/src/button/Button.less +7 -1
- package/src/button/Button.spec.tsx +103 -0
- package/src/button/Button.tsx +2 -1
- package/src/button/Button.vars.less +2 -3
- package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +0 -1
- package/src/index.ts +0 -12
- package/src/main.css +4 -2
- package/src/primitives/PrimitiveAnchor/src/PrimitiveAnchor.tsx +1 -1
- package/src/primitives/PrimitiveButton/src/PrimitiveButton.tsx +3 -4
- package/src/primitives/PrimitiveButton/test/PrimitiveButton.spec.tsx +15 -9
- package/src/uploadInput/UploadInput.tests.story.tsx +5 -5
- package/src/uploadInput/uploadButton/getAllowedFileTypes.spec.ts +0 -12
- package/src/uploadInput/uploadButton/getAllowedFileTypes.ts +7 -33
- package/build/table/Table.js +0 -166
- package/build/table/Table.js.map +0 -1
- package/build/table/Table.messages.js +0 -24
- package/build/table/Table.messages.js.map +0 -1
- package/build/table/Table.messages.mjs +0 -22
- package/build/table/Table.messages.mjs.map +0 -1
- package/build/table/Table.mjs +0 -164
- package/build/table/Table.mjs.map +0 -1
- package/build/table/TableCell.js +0 -86
- package/build/table/TableCell.js.map +0 -1
- package/build/table/TableCell.mjs +0 -84
- package/build/table/TableCell.mjs.map +0 -1
- package/build/table/TableHeader.js +0 -57
- package/build/table/TableHeader.js.map +0 -1
- package/build/table/TableHeader.mjs +0 -55
- package/build/table/TableHeader.mjs.map +0 -1
- package/build/table/TableRow.js +0 -85
- package/build/table/TableRow.js.map +0 -1
- package/build/table/TableRow.mjs +0 -83
- package/build/table/TableRow.mjs.map +0 -1
- package/build/table/TableStatusText.js +0 -54
- package/build/table/TableStatusText.js.map +0 -1
- package/build/table/TableStatusText.mjs +0 -52
- package/build/table/TableStatusText.mjs.map +0 -1
|
@@ -1,28 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
const mimeType = fileType?.split('/');
|
|
8
|
-
if (mimeType?.length > 1) {
|
|
9
|
-
let parsedType = mimeType[1];
|
|
10
|
-
if (parsedType.toLocaleLowerCase() === 'jpeg') {
|
|
11
|
-
parsedType = 'jpg, '.concat(parsedType).toUpperCase();
|
|
12
|
-
}
|
|
13
|
-
return parsedType.toUpperCase();
|
|
14
|
-
}
|
|
15
|
-
return fileType;
|
|
16
|
-
};
|
|
17
|
-
const getAllowedFileTypes = fileTypes => fileTypes.map(fileType => {
|
|
18
|
-
const splittedFileTypes = fileType?.split(',');
|
|
19
|
-
if (splittedFileTypes?.length > 1) {
|
|
20
|
-
// If `fileType` contains `format` and `mime` types, remove mime types, proceed only with format types
|
|
21
|
-
return splittedFileTypes.filter(splittedFileType => !splittedFileType?.includes('/')).map(splittedFileType => parseFileType(splittedFileType)).join(', ');
|
|
22
|
-
}
|
|
23
|
-
// If `fileType` contains only `format` or `mime` type, parse the type
|
|
24
|
-
return parseFileType(fileType);
|
|
25
|
-
});
|
|
3
|
+
const getAllowedFileTypes = fileTypes => fileTypes.map(fileTypeDefinition => fileTypeDefinition.split(',').filter(extension => !extension.includes('/')) // Filter out mime types
|
|
4
|
+
.map(extension => extension.replace('.', '').toUpperCase()) // Remove dot and convert extensions to uppercase to be displayed in the instructions
|
|
5
|
+
.join(', '));
|
|
26
6
|
|
|
27
7
|
module.exports = getAllowedFileTypes;
|
|
28
8
|
//# sourceMappingURL=getAllowedFileTypes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getAllowedFileTypes.js","sources":["../../../src/uploadInput/uploadButton/getAllowedFileTypes.ts"],"sourcesContent":["import { FileType } from '../../common';\n\nconst
|
|
1
|
+
{"version":3,"file":"getAllowedFileTypes.js","sources":["../../../src/uploadInput/uploadButton/getAllowedFileTypes.ts"],"sourcesContent":["import { FileType } from '../../common';\n\nconst getAllowedFileTypes = (fileTypes: readonly FileType[] | readonly string[]): string[] =>\n fileTypes.map((fileTypeDefinition: string) =>\n fileTypeDefinition\n .split(',')\n .filter((extension) => !extension.includes('/')) // Filter out mime types\n .map((extension) => extension.replace('.', '').toUpperCase()) // Remove dot and convert extensions to uppercase to be displayed in the instructions\n .join(', '),\n );\n\nexport default getAllowedFileTypes;\n"],"names":["getAllowedFileTypes","fileTypes","map","fileTypeDefinition","split","filter","extension","includes","replace","toUpperCase","join"],"mappings":";;AAEA,MAAMA,mBAAmB,GAAIC,SAAkD,IAC7EA,SAAS,CAACC,GAAG,CAAEC,kBAA0B,IACvCA,kBAAkB,CACfC,KAAK,CAAC,GAAG,CAAC,CACVC,MAAM,CAAEC,SAAS,IAAK,CAACA,SAAS,CAACC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAAC,CAChDL,GAAG,CAAEI,SAAS,IAAKA,SAAS,CAACE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAACC,WAAW,EAAE,CAAC;AAAC,CAC7DC,IAAI,CAAC,IAAI,CAAC;;;;"}
|
|
@@ -1,26 +1,6 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
const mimeType = fileType?.split('/');
|
|
6
|
-
if (mimeType?.length > 1) {
|
|
7
|
-
let parsedType = mimeType[1];
|
|
8
|
-
if (parsedType.toLocaleLowerCase() === 'jpeg') {
|
|
9
|
-
parsedType = 'jpg, '.concat(parsedType).toUpperCase();
|
|
10
|
-
}
|
|
11
|
-
return parsedType.toUpperCase();
|
|
12
|
-
}
|
|
13
|
-
return fileType;
|
|
14
|
-
};
|
|
15
|
-
const getAllowedFileTypes = fileTypes => fileTypes.map(fileType => {
|
|
16
|
-
const splittedFileTypes = fileType?.split(',');
|
|
17
|
-
if (splittedFileTypes?.length > 1) {
|
|
18
|
-
// If `fileType` contains `format` and `mime` types, remove mime types, proceed only with format types
|
|
19
|
-
return splittedFileTypes.filter(splittedFileType => !splittedFileType?.includes('/')).map(splittedFileType => parseFileType(splittedFileType)).join(', ');
|
|
20
|
-
}
|
|
21
|
-
// If `fileType` contains only `format` or `mime` type, parse the type
|
|
22
|
-
return parseFileType(fileType);
|
|
23
|
-
});
|
|
1
|
+
const getAllowedFileTypes = fileTypes => fileTypes.map(fileTypeDefinition => fileTypeDefinition.split(',').filter(extension => !extension.includes('/')) // Filter out mime types
|
|
2
|
+
.map(extension => extension.replace('.', '').toUpperCase()) // Remove dot and convert extensions to uppercase to be displayed in the instructions
|
|
3
|
+
.join(', '));
|
|
24
4
|
|
|
25
5
|
export { getAllowedFileTypes as default };
|
|
26
6
|
//# sourceMappingURL=getAllowedFileTypes.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getAllowedFileTypes.mjs","sources":["../../../src/uploadInput/uploadButton/getAllowedFileTypes.ts"],"sourcesContent":["import { FileType } from '../../common';\n\nconst
|
|
1
|
+
{"version":3,"file":"getAllowedFileTypes.mjs","sources":["../../../src/uploadInput/uploadButton/getAllowedFileTypes.ts"],"sourcesContent":["import { FileType } from '../../common';\n\nconst getAllowedFileTypes = (fileTypes: readonly FileType[] | readonly string[]): string[] =>\n fileTypes.map((fileTypeDefinition: string) =>\n fileTypeDefinition\n .split(',')\n .filter((extension) => !extension.includes('/')) // Filter out mime types\n .map((extension) => extension.replace('.', '').toUpperCase()) // Remove dot and convert extensions to uppercase to be displayed in the instructions\n .join(', '),\n );\n\nexport default getAllowedFileTypes;\n"],"names":["getAllowedFileTypes","fileTypes","map","fileTypeDefinition","split","filter","extension","includes","replace","toUpperCase","join"],"mappings":"AAEA,MAAMA,mBAAmB,GAAIC,SAAkD,IAC7EA,SAAS,CAACC,GAAG,CAAEC,kBAA0B,IACvCA,kBAAkB,CACfC,KAAK,CAAC,GAAG,CAAC,CACVC,MAAM,CAAEC,SAAS,IAAK,CAACA,SAAS,CAACC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAAC,CAChDL,GAAG,CAAEI,SAAS,IAAKA,SAAS,CAACE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAACC,WAAW,EAAE,CAAC;AAAC,CAC7DC,IAAI,CAAC,IAAI,CAAC;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transferwise/components",
|
|
3
|
-
"version": "0.0.0-experimental-
|
|
3
|
+
"version": "0.0.0-experimental-69a95e1",
|
|
4
4
|
"description": "Neptune React components",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -91,13 +91,13 @@
|
|
|
91
91
|
"rollup": "^4.18.1",
|
|
92
92
|
"rollup-preserve-directives": "^1.1.1",
|
|
93
93
|
"storybook": "^8.2.2",
|
|
94
|
-
"@transferwise/
|
|
95
|
-
"@
|
|
96
|
-
"@
|
|
94
|
+
"@transferwise/neptune-css": "0.0.0-experimental-69a95e1",
|
|
95
|
+
"@wise/components-theming": "1.6.1",
|
|
96
|
+
"@transferwise/less-config": "3.1.0"
|
|
97
97
|
},
|
|
98
98
|
"peerDependencies": {
|
|
99
99
|
"@transferwise/icons": "^3.13.1",
|
|
100
|
-
"@transferwise/neptune-css": "0.0.0-experimental-
|
|
100
|
+
"@transferwise/neptune-css": "0.0.0-experimental-69a95e1",
|
|
101
101
|
"@wise/art": "^2.16",
|
|
102
102
|
"@wise/components-theming": "^1.0.0",
|
|
103
103
|
"react": ">=18",
|
|
@@ -24,8 +24,7 @@
|
|
|
24
24
|
margin-right: calc(var(--np-avatar-layout-size) - var(--np-avatar-size) * 2);
|
|
25
25
|
}
|
|
26
26
|
.np-avatar-layout-horizontal {
|
|
27
|
-
width: calc(var(--np-avatar-size) *
|
|
28
|
-
width: calc(var(--np-avatar-size) * var(--np-avatar-avatars-count) - calc(var(--np-avatar-offset) * calc(var(--np-avatar-avatars-count) - 1)));
|
|
27
|
+
width: calc(var(--np-avatar-size) * 2 - var(--np-avatar-offset));
|
|
29
28
|
height: var(--np-avatar-layout-size);
|
|
30
29
|
}
|
|
31
30
|
.np-avatar-layout-horizontal-mask {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
&-horizontal {
|
|
38
|
-
width: calc(var(--np-avatar-size) *
|
|
38
|
+
width: calc(var(--np-avatar-size) * 2 - var(--np-avatar-offset));
|
|
39
39
|
height: var(--np-avatar-layout-size);
|
|
40
40
|
|
|
41
41
|
&-mask {
|
|
@@ -40,7 +40,6 @@ export default function AvatarLayout({
|
|
|
40
40
|
'--np-avatar-layout-size': `${size}px`,
|
|
41
41
|
'--np-avatar-size': `${avatarSize}px`,
|
|
42
42
|
'--np-avatar-offset': `${isDiagonal ? DIAGONAL_LAYOUT_STYLE_CONFIG[size].offset : HORIZONTAL_LAYOUT_OFFSET[size]}px`,
|
|
43
|
-
'--np-avatar-avatars-count': avatars.length,
|
|
44
43
|
}}
|
|
45
44
|
{...restProps}
|
|
46
45
|
>
|
package/src/button/Button.css
CHANGED
|
@@ -68,10 +68,13 @@
|
|
|
68
68
|
}
|
|
69
69
|
.wds-Button.wds-Button--disabled,
|
|
70
70
|
.wds-Button:disabled {
|
|
71
|
+
filter: none;
|
|
71
72
|
mix-blend-mode: luminosity;
|
|
72
73
|
opacity: 0.45;
|
|
73
74
|
cursor: not-allowed;
|
|
74
75
|
}
|
|
76
|
+
.wds-Button.wds-Button--disabled,
|
|
77
|
+
.wds-Button:disabled,
|
|
75
78
|
.wds-Button.wds-Button--disabled:hover,
|
|
76
79
|
.wds-Button:disabled:hover,
|
|
77
80
|
.wds-Button.wds-Button--disabled:active,
|
package/src/button/Button.less
CHANGED
|
@@ -30,10 +30,16 @@
|
|
|
30
30
|
|
|
31
31
|
&.wds-Button--disabled,
|
|
32
32
|
&:disabled {
|
|
33
|
+
// The declarations below are necessary as design specs for
|
|
34
|
+
// the button's disabled state have changed. This is to be
|
|
35
|
+
// further investigated at a later stage.
|
|
36
|
+
// @see https://transferwise.atlassian.net/browse/DS-7386
|
|
37
|
+
filter: none;
|
|
33
38
|
mix-blend-mode: luminosity;
|
|
34
39
|
opacity: 0.45;
|
|
35
40
|
cursor: not-allowed;
|
|
36
41
|
|
|
42
|
+
&,
|
|
37
43
|
&:hover,
|
|
38
44
|
&:active {
|
|
39
45
|
background-color: var(--Button-background);
|
|
@@ -122,7 +128,7 @@
|
|
|
122
128
|
|
|
123
129
|
|
|
124
130
|
|
|
125
|
-
// Width
|
|
131
|
+
// Width modifiers
|
|
126
132
|
&--block {
|
|
127
133
|
width: 100%;
|
|
128
134
|
}
|
|
@@ -67,6 +67,109 @@ describe('Button', () => {
|
|
|
67
67
|
);
|
|
68
68
|
expect(screen.getByRole('link', { name })).toHaveAttribute('href', href);
|
|
69
69
|
});
|
|
70
|
+
|
|
71
|
+
describe('disabled mode', () => {
|
|
72
|
+
describe('button', () => {
|
|
73
|
+
it('should not be disabled by default', () => {
|
|
74
|
+
render(<Button v2>{name}</Button>);
|
|
75
|
+
const button = screen.getByRole('button');
|
|
76
|
+
expect(button).toBeEnabled();
|
|
77
|
+
expect(button).not.toHaveAttribute('aria-disabled');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should respect disabled mode and set it only via the `disabled` attribute', () => {
|
|
81
|
+
render(
|
|
82
|
+
<Button v2 disabled>
|
|
83
|
+
{name}
|
|
84
|
+
</Button>,
|
|
85
|
+
);
|
|
86
|
+
const button = screen.getByRole('button');
|
|
87
|
+
expect(button).toBeDisabled();
|
|
88
|
+
expect(button).not.toHaveAttribute('aria-disabled');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('anchor', () => {
|
|
93
|
+
it('should not be disabled by default', () => {
|
|
94
|
+
render(
|
|
95
|
+
<Button v2 href="wise.com">
|
|
96
|
+
{name}
|
|
97
|
+
</Button>,
|
|
98
|
+
);
|
|
99
|
+
const button = screen.getByRole('link');
|
|
100
|
+
expect(button).toBeEnabled();
|
|
101
|
+
expect(button).not.toHaveAttribute('aria-disabled');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should respect disabled mode', () => {
|
|
105
|
+
render(
|
|
106
|
+
<Button v2 href="wise.com" disabled>
|
|
107
|
+
{name}
|
|
108
|
+
</Button>,
|
|
109
|
+
);
|
|
110
|
+
const button = screen.getByRole('link');
|
|
111
|
+
expect(button).toHaveAttribute('aria-disabled');
|
|
112
|
+
expect(button).toBeEnabled();
|
|
113
|
+
expect(button).not.toHaveAttribute('href');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe('loading mode', () => {
|
|
119
|
+
describe('button', () => {
|
|
120
|
+
it('should not be loading by default', () => {
|
|
121
|
+
render(<Button v2>{name}</Button>);
|
|
122
|
+
const button = screen.getByRole('button');
|
|
123
|
+
expect(button).toBeEnabled();
|
|
124
|
+
expect(button).not.toHaveAttribute('aria-busy');
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('should respect loading mode', () => {
|
|
128
|
+
render(
|
|
129
|
+
<Button v2 loading>
|
|
130
|
+
{name}
|
|
131
|
+
</Button>,
|
|
132
|
+
);
|
|
133
|
+
const button = screen.getByRole('button');
|
|
134
|
+
expect(button).toHaveAttribute('aria-busy');
|
|
135
|
+
// the `disabled` attribute is not set to keep the button
|
|
136
|
+
// focusable but aria attribute is defined to make it
|
|
137
|
+
// announced properly by the assistive tech
|
|
138
|
+
expect(button).toBeEnabled();
|
|
139
|
+
expect(button).toHaveAttribute('aria-disabled');
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('anchor', () => {
|
|
144
|
+
it('should not be loading by default', () => {
|
|
145
|
+
render(
|
|
146
|
+
<Button v2 href="wise.com">
|
|
147
|
+
{name}
|
|
148
|
+
</Button>,
|
|
149
|
+
);
|
|
150
|
+
const button = screen.getByRole('link');
|
|
151
|
+
expect(button).toBeEnabled();
|
|
152
|
+
expect(button).not.toHaveAttribute('aria-busy');
|
|
153
|
+
expect(button).not.toHaveAttribute('aria-disabled');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should respect loading mode', () => {
|
|
157
|
+
render(
|
|
158
|
+
<Button v2 loading href="wise.com">
|
|
159
|
+
{name}
|
|
160
|
+
</Button>,
|
|
161
|
+
);
|
|
162
|
+
const button = screen.getByRole('link');
|
|
163
|
+
expect(button).toHaveAttribute('aria-busy');
|
|
164
|
+
// the `disabled` attribute is not set to keep the button
|
|
165
|
+
// focusable but aria attribute is defined to make it
|
|
166
|
+
// announced properly by the assistive tech
|
|
167
|
+
expect(button).toBeEnabled();
|
|
168
|
+
expect(button).toHaveAttribute('aria-disabled');
|
|
169
|
+
expect(button).not.toHaveAttribute('href');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
});
|
|
70
173
|
});
|
|
71
174
|
});
|
|
72
175
|
|
package/src/button/Button.tsx
CHANGED
|
@@ -87,7 +87,8 @@ const Button = forwardRef<HTMLButtonElement | HTMLAnchorElement, NewButtonProps>
|
|
|
87
87
|
{...(props as any)}
|
|
88
88
|
href={href}
|
|
89
89
|
className={classNames}
|
|
90
|
-
disabled={disabled}
|
|
90
|
+
disabled={disabled || loading}
|
|
91
|
+
aria-busy={loading || undefined}
|
|
91
92
|
>
|
|
92
93
|
{content}
|
|
93
94
|
</PrimitiveAnchor>
|
|
@@ -39,10 +39,9 @@
|
|
|
39
39
|
--Button-secondary-negative-background-hover: var(--color-sentiment-negative-secondary-hover);
|
|
40
40
|
--Button-secondary-negative-background-active: var(--color-sentiment-negative-secondary-active);
|
|
41
41
|
--Button-secondary-negative-color: var(--color-sentiment-negative-primary);
|
|
42
|
-
}
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
.
|
|
43
|
+
|
|
44
|
+
.np-theme-personal--bright-green & {
|
|
46
45
|
--color-contrast: #FFFFFF;
|
|
47
46
|
--Button-secondary-color: var(--color-interactive-control);
|
|
48
47
|
--Button-secondary-negative-color: var(--color-contrast);
|
|
@@ -9,7 +9,6 @@ exports[`FlowNavigation on mobile renders as expected 1`] = `
|
|
|
9
9
|
class="np-flow-header d-flex flex-wrap align-items-center justify-content-between flex__item--12 np-flow-navigation__content p-x-3 np-flow-navigation--xs-max"
|
|
10
10
|
>
|
|
11
11
|
<button
|
|
12
|
-
aria-disabled="false"
|
|
13
12
|
aria-label="back to previous step"
|
|
14
13
|
aria-live="off"
|
|
15
14
|
class="np-circle d-flex align-items-center justify-content-center np-icon-button np-icon-button-tertiary-default"
|
package/src/index.ts
CHANGED
|
@@ -96,17 +96,6 @@ export type { UploadProps } from './upload';
|
|
|
96
96
|
export type { UploadError, UploadResponse, UploadedFile } from './uploadInput/types';
|
|
97
97
|
export type { WithIdProps } from './withId';
|
|
98
98
|
export type { IconButtonProps } from './iconButton';
|
|
99
|
-
export type {
|
|
100
|
-
TableProps,
|
|
101
|
-
TableRowType,
|
|
102
|
-
TableRowClickableType,
|
|
103
|
-
TableHeaderType,
|
|
104
|
-
TableCellLeading,
|
|
105
|
-
TableCellText,
|
|
106
|
-
TableCellCurrency,
|
|
107
|
-
TableCellStatus,
|
|
108
|
-
TableCellType,
|
|
109
|
-
} from './table';
|
|
110
99
|
|
|
111
100
|
/**
|
|
112
101
|
* Components
|
|
@@ -207,7 +196,6 @@ export { default as Tooltip } from './tooltip';
|
|
|
207
196
|
export { default as Typeahead } from './typeahead';
|
|
208
197
|
export { default as Upload } from './upload';
|
|
209
198
|
export { default as UploadInput } from './uploadInput';
|
|
210
|
-
export { default as Table } from './table';
|
|
211
199
|
|
|
212
200
|
/**
|
|
213
201
|
* Hooks
|
package/src/main.css
CHANGED
|
@@ -531,8 +531,7 @@ div.critical-comms .critical-comms-body {
|
|
|
531
531
|
margin-right: calc(var(--np-avatar-layout-size) - var(--np-avatar-size) * 2);
|
|
532
532
|
}
|
|
533
533
|
.np-avatar-layout-horizontal {
|
|
534
|
-
width: calc(var(--np-avatar-size) *
|
|
535
|
-
width: calc(var(--np-avatar-size) * var(--np-avatar-avatars-count) - calc(var(--np-avatar-offset) * calc(var(--np-avatar-avatars-count) - 1)));
|
|
534
|
+
width: calc(var(--np-avatar-size) * 2 - var(--np-avatar-offset));
|
|
536
535
|
height: var(--np-avatar-layout-size);
|
|
537
536
|
}
|
|
538
537
|
.np-avatar-layout-horizontal-mask {
|
|
@@ -787,10 +786,13 @@ div.critical-comms .critical-comms-body {
|
|
|
787
786
|
}
|
|
788
787
|
.wds-Button.wds-Button--disabled,
|
|
789
788
|
.wds-Button:disabled {
|
|
789
|
+
filter: none;
|
|
790
790
|
mix-blend-mode: luminosity;
|
|
791
791
|
opacity: 0.45;
|
|
792
792
|
cursor: not-allowed;
|
|
793
793
|
}
|
|
794
|
+
.wds-Button.wds-Button--disabled,
|
|
795
|
+
.wds-Button:disabled,
|
|
794
796
|
.wds-Button.wds-Button--disabled:hover,
|
|
795
797
|
.wds-Button:disabled:hover,
|
|
796
798
|
.wds-Button.wds-Button--disabled:active,
|
|
@@ -90,7 +90,7 @@ const PrimitiveAnchor = forwardRef<HTMLAnchorElement, PrimitiveAnchorProps>(
|
|
|
90
90
|
* https://www.scottohara.me/blog/2021/05/28/disabled-links.html
|
|
91
91
|
*/
|
|
92
92
|
const anchorProps = {
|
|
93
|
-
'aria-disabled': disabled,
|
|
93
|
+
'aria-disabled': disabled || undefined,
|
|
94
94
|
className: anchorClasses,
|
|
95
95
|
'data-testid': testId,
|
|
96
96
|
href: disabled ? undefined : href,
|
|
@@ -95,10 +95,9 @@ const PrimitiveButton = forwardRef<HTMLButtonElement, PrimitiveButtonProps>(
|
|
|
95
95
|
* by assistive technologies, set to 'polite' during loading.
|
|
96
96
|
*/
|
|
97
97
|
const buttonProps = {
|
|
98
|
-
'aria-disabled':
|
|
99
|
-
'aria-
|
|
100
|
-
|
|
101
|
-
: props['aria-label'],
|
|
98
|
+
'aria-disabled': loading || undefined,
|
|
99
|
+
'aria-busy': loading || undefined,
|
|
100
|
+
'aria-label': loading ? intl.formatMessage(messages.loadingAriaLabel) : props['aria-label'],
|
|
102
101
|
'aria-live': (loading ? 'polite' : 'off') as 'polite' | 'off' | 'assertive' | undefined,
|
|
103
102
|
className: classNames,
|
|
104
103
|
'data-testid': testId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { screen } from '@testing-library/react';
|
|
2
|
-
import PrimitiveButton from '../src';
|
|
3
|
-
import messages from '../../../i18n/commonMessages/Button.messages';
|
|
4
2
|
import { render } from '../../../test-utils';
|
|
3
|
+
import PrimitiveButton from '../src';
|
|
4
|
+
import allMessages from '../../../i18n';
|
|
5
5
|
|
|
6
6
|
describe('Button', () => {
|
|
7
7
|
const defaultProps = {
|
|
@@ -11,7 +11,7 @@ describe('Button', () => {
|
|
|
11
11
|
const renderButton = (
|
|
12
12
|
props?: Partial<typeof defaultProps>,
|
|
13
13
|
locale = 'en',
|
|
14
|
-
localeMessages =
|
|
14
|
+
localeMessages = allMessages.en,
|
|
15
15
|
) => {
|
|
16
16
|
return render(
|
|
17
17
|
<PrimitiveButton {...defaultProps} {...props} />,
|
|
@@ -50,6 +50,17 @@ describe('Button', () => {
|
|
|
50
50
|
expect(button).toBeDisabled();
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
+
it('disables and announces the button as busy in loading mode', () => {
|
|
54
|
+
const props = {
|
|
55
|
+
...defaultProps,
|
|
56
|
+
loading: true,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
renderButton(props);
|
|
60
|
+
|
|
61
|
+
expect(screen.getByRole('button', { busy: true })).toHaveAttribute('aria-disabled', 'true');
|
|
62
|
+
});
|
|
63
|
+
|
|
53
64
|
it('sets data-testid attribute', () => {
|
|
54
65
|
const props = {
|
|
55
66
|
...defaultProps,
|
|
@@ -98,12 +109,7 @@ describe('Button', () => {
|
|
|
98
109
|
loading: true,
|
|
99
110
|
};
|
|
100
111
|
|
|
101
|
-
|
|
102
|
-
...messages,
|
|
103
|
-
'neptune.Button.loadingAriaLabel': 'cargando',
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
renderButton(props, 'es', spanishMessages);
|
|
112
|
+
renderButton(props, 'es', allMessages.es);
|
|
107
113
|
|
|
108
114
|
const button = screen.getByRole('button');
|
|
109
115
|
expect(button).toHaveAttribute('aria-label', 'cargando');
|
|
@@ -4,7 +4,7 @@ import { Meta, StoryObj } from '@storybook/react';
|
|
|
4
4
|
import { Status } from '../common';
|
|
5
5
|
import UploadInput, { UploadInputProps } from './UploadInput';
|
|
6
6
|
import { UploadedFile, UploadResponse } from './types';
|
|
7
|
-
import { userEvent } from '@storybook/test';
|
|
7
|
+
import { userEvent, within } from '@storybook/test';
|
|
8
8
|
|
|
9
9
|
const meta: Meta<typeof UploadInput> = {
|
|
10
10
|
title: 'Forms/UploadInput/Tests',
|
|
@@ -65,8 +65,8 @@ const createDelayedPromise = async ({
|
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
const props = {
|
|
68
|
-
onUploadFile: async () => createDelayedPromise(),
|
|
69
|
-
onDeleteFile: async () => createDelayedPromise(),
|
|
68
|
+
onUploadFile: async (formData: FormData) => createDelayedPromise(),
|
|
69
|
+
onDeleteFile: async (id: string | number) => createDelayedPromise(),
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
export const UploadInputWithDescriptionFromProps: Story = {
|
|
@@ -268,7 +268,7 @@ export const DeletingTop: Story = {
|
|
|
268
268
|
files: [files[0], files[1], files[2]],
|
|
269
269
|
multiple: true,
|
|
270
270
|
},
|
|
271
|
-
play: async () => {
|
|
271
|
+
play: async ({ canvasElement }) => {
|
|
272
272
|
await userEvent.tab();
|
|
273
273
|
await triggerModalAndConfirm();
|
|
274
274
|
await triggerModalAndConfirm({ isLink: false });
|
|
@@ -282,7 +282,7 @@ export const DeletingBottom: Story = {
|
|
|
282
282
|
files: [files[0], files[1], files[2]],
|
|
283
283
|
multiple: true,
|
|
284
284
|
},
|
|
285
|
-
play: async () => {
|
|
285
|
+
play: async ({ canvasElement }) => {
|
|
286
286
|
await userEvent.tab();
|
|
287
287
|
await userEvent.tab();
|
|
288
288
|
await userEvent.tab();
|
|
@@ -38,16 +38,4 @@ describe('getAllowedFileTypes', () => {
|
|
|
38
38
|
expect(allowedFileTypes).toStrictEqual(['*']);
|
|
39
39
|
});
|
|
40
40
|
});
|
|
41
|
-
|
|
42
|
-
describe('using only mime types', () => {
|
|
43
|
-
const mimeTypes = ['application/json', 'image/jpeg'];
|
|
44
|
-
|
|
45
|
-
beforeAll(() => {
|
|
46
|
-
allowedFileTypes = getAllowedFileTypes(mimeTypes);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('returns the original mime types', () => {
|
|
50
|
-
expect(allowedFileTypes).toStrictEqual(['JSON', 'JPG, JPEG']);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
41
|
});
|
|
@@ -1,38 +1,12 @@
|
|
|
1
1
|
import { FileType } from '../../common';
|
|
2
2
|
|
|
3
|
-
const parseFileType = (fileType: string): string => {
|
|
4
|
-
if (fileType?.includes('.')) {
|
|
5
|
-
return fileType.replace('.', '').toUpperCase();
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const mimeType = fileType?.split('/');
|
|
9
|
-
if (mimeType?.length > 1) {
|
|
10
|
-
let parsedType = mimeType[1];
|
|
11
|
-
|
|
12
|
-
if (parsedType.toLocaleLowerCase() === 'jpeg') {
|
|
13
|
-
parsedType = 'jpg, '.concat(parsedType).toUpperCase();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return parsedType.toUpperCase();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return fileType;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
3
|
const getAllowedFileTypes = (fileTypes: readonly FileType[] | readonly string[]): string[] =>
|
|
23
|
-
fileTypes.map((
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
.map((splittedFileType: string) => parseFileType(splittedFileType))
|
|
31
|
-
.join(', ');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// If `fileType` contains only `format` or `mime` type, parse the type
|
|
35
|
-
return parseFileType(fileType);
|
|
36
|
-
});
|
|
4
|
+
fileTypes.map((fileTypeDefinition: string) =>
|
|
5
|
+
fileTypeDefinition
|
|
6
|
+
.split(',')
|
|
7
|
+
.filter((extension) => !extension.includes('/')) // Filter out mime types
|
|
8
|
+
.map((extension) => extension.replace('.', '').toUpperCase()) // Remove dot and convert extensions to uppercase to be displayed in the instructions
|
|
9
|
+
.join(', '),
|
|
10
|
+
);
|
|
37
11
|
|
|
38
12
|
export default getAllowedFileTypes;
|