@transferwise/components 0.0.0-experimental-cbe9617 → 0.0.0-experimental-26bc819
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/field/Field.js +10 -0
- package/build/field/Field.js.map +1 -1
- package/build/field/Field.mjs +10 -0
- package/build/field/Field.mjs.map +1 -1
- package/build/index.js +2 -0
- package/build/index.js.map +1 -1
- package/build/index.mjs +1 -0
- package/build/index.mjs.map +1 -1
- package/build/inputs/SelectInput.js +5 -10
- package/build/inputs/SelectInput.js.map +1 -1
- package/build/inputs/SelectInput.mjs +6 -11
- package/build/inputs/SelectInput.mjs.map +1 -1
- package/build/inputs/_BottomSheet.js +2 -5
- package/build/inputs/_BottomSheet.js.map +1 -1
- package/build/inputs/_BottomSheet.mjs +3 -6
- package/build/inputs/_BottomSheet.mjs.map +1 -1
- package/build/inputs/_Popover.js +0 -2
- package/build/inputs/_Popover.js.map +1 -1
- package/build/inputs/_Popover.mjs +0 -2
- package/build/inputs/_Popover.mjs.map +1 -1
- package/build/listItem/Prompt/ListItemPrompt.js +10 -0
- package/build/listItem/Prompt/ListItemPrompt.js.map +1 -1
- package/build/listItem/Prompt/ListItemPrompt.mjs +10 -0
- package/build/listItem/Prompt/ListItemPrompt.mjs.map +1 -1
- package/build/main.css +30 -1
- package/build/prompt/ActionPrompt/ActionPrompt.js +123 -0
- package/build/prompt/ActionPrompt/ActionPrompt.js.map +1 -0
- package/build/prompt/ActionPrompt/ActionPrompt.mjs +118 -0
- package/build/prompt/ActionPrompt/ActionPrompt.mjs.map +1 -0
- package/build/prompt/PrimitivePrompt/PrimitivePrompt.js +13 -11
- package/build/prompt/PrimitivePrompt/PrimitivePrompt.js.map +1 -1
- package/build/prompt/PrimitivePrompt/PrimitivePrompt.mjs +14 -12
- package/build/prompt/PrimitivePrompt/PrimitivePrompt.mjs.map +1 -1
- package/build/styles/main.css +30 -1
- package/build/styles/prompt/ActionPrompt/ActionPrompt.css +20 -0
- package/build/styles/prompt/PrimitivePrompt/PrimitivePrompt.css +10 -1
- package/build/typeahead/Typeahead.js +10 -0
- package/build/typeahead/Typeahead.js.map +1 -1
- package/build/typeahead/Typeahead.mjs +10 -0
- package/build/typeahead/Typeahead.mjs.map +1 -1
- package/build/types/index.d.ts +2 -2
- package/build/types/index.d.ts.map +1 -1
- package/build/types/inputs/SelectInput.d.ts.map +1 -1
- package/build/types/inputs/_BottomSheet.d.ts.map +1 -1
- package/build/types/inputs/_Popover.d.ts.map +1 -1
- package/build/types/prompt/ActionPrompt/ActionPrompt.d.ts +26 -0
- package/build/types/prompt/ActionPrompt/ActionPrompt.d.ts.map +1 -0
- package/build/types/prompt/ActionPrompt/ActionPrompt.test.d.ts +2 -0
- package/build/types/prompt/ActionPrompt/ActionPrompt.test.d.ts.map +1 -0
- package/build/types/prompt/ActionPrompt/index.d.ts +3 -0
- package/build/types/prompt/ActionPrompt/index.d.ts.map +1 -0
- package/build/types/prompt/InlinePrompt/InlinePrompt.test.d.ts +2 -0
- package/build/types/prompt/InlinePrompt/InlinePrompt.test.d.ts.map +1 -0
- package/build/types/prompt/PrimitivePrompt/PrimitivePrompt.d.ts.map +1 -1
- package/build/types/prompt/PrimitivePrompt/PrimitivePrompt.test.d.ts +2 -0
- package/build/types/prompt/PrimitivePrompt/PrimitivePrompt.test.d.ts.map +1 -0
- package/build/types/prompt/index.d.ts +2 -0
- package/build/types/prompt/index.d.ts.map +1 -1
- package/package.json +5 -6
- package/src/index.ts +2 -2
- package/src/inputs/SelectInput.spec.tsx +7 -78
- package/src/inputs/SelectInput.tsx +10 -21
- package/src/inputs/_BottomSheet.tsx +4 -7
- package/src/inputs/_Popover.tsx +0 -2
- package/src/main.css +30 -1
- package/src/main.less +1 -0
- package/src/moneyInput/MoneyInput.spec.tsx +7 -26
- package/src/prompt/ActionPrompt/ActionPrompt.css +20 -0
- package/src/prompt/ActionPrompt/ActionPrompt.less +22 -0
- package/src/prompt/ActionPrompt/ActionPrompt.story.tsx +189 -0
- package/src/prompt/ActionPrompt/ActionPrompt.test.tsx +256 -0
- package/src/prompt/ActionPrompt/ActionPrompt.tsx +129 -0
- package/src/prompt/ActionPrompt/index.ts +2 -0
- package/src/prompt/InlinePrompt/{InlinePrompt.spec.tsx → InlinePrompt.test.tsx} +3 -38
- package/src/prompt/PrimitivePrompt/PrimitivePrompt.css +10 -1
- package/src/prompt/PrimitivePrompt/PrimitivePrompt.less +11 -1
- package/src/prompt/PrimitivePrompt/PrimitivePrompt.test.tsx +161 -0
- package/src/prompt/PrimitivePrompt/PrimitivePrompt.tsx +15 -11
- package/src/prompt/index.ts +3 -0
- package/src/ssr.spec.tsx +1 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { AvatarViewProps } from '../../avatarView';
|
|
3
|
+
import { ButtonProps } from '../../button/Button.types';
|
|
4
|
+
import { PrimitivePromptProps } from '../PrimitivePrompt';
|
|
5
|
+
import { BadgeAssetsProps } from '../../badge';
|
|
6
|
+
export type ActionPromptProps = {
|
|
7
|
+
title: ReactNode;
|
|
8
|
+
description?: ReactNode;
|
|
9
|
+
media?: {
|
|
10
|
+
imgSrc?: string;
|
|
11
|
+
avatar?: Pick<AvatarViewProps, 'imgSrc' | 'profileName' | 'profileType'> & {
|
|
12
|
+
asset?: AvatarViewProps['children'];
|
|
13
|
+
badge?: Pick<BadgeAssetsProps, 'flagCode'>;
|
|
14
|
+
};
|
|
15
|
+
'aria-label'?: string;
|
|
16
|
+
};
|
|
17
|
+
actionPrimary: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {
|
|
18
|
+
label: ButtonProps['children'];
|
|
19
|
+
};
|
|
20
|
+
actionSecondary?: Pick<ButtonProps, 'onClick' | 'href' | 'target'> & {
|
|
21
|
+
label: ButtonProps['children'];
|
|
22
|
+
};
|
|
23
|
+
} & Pick<PrimitivePromptProps, 'id' | 'className' | 'data-testid' | 'sentiment' | 'onDismiss'>;
|
|
24
|
+
export declare const ActionPrompt: ({ sentiment, title, description, onDismiss, media, actionPrimary, actionSecondary, id, className, "data-testid": testId, }: ActionPromptProps) => import("react").JSX.Element;
|
|
25
|
+
export default ActionPrompt;
|
|
26
|
+
//# sourceMappingURL=ActionPrompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionPrompt.d.ts","sourceRoot":"","sources":["../../../../src/prompt/ActionPrompt/ActionPrompt.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOlC,OAAmB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAmB,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,aAAa,GAAG,aAAa,CAAC,GAAG;YACzE,KAAK,CAAC,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;YACpC,KAAK,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;SAC5C,CAAC;QACF,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,aAAa,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC,GAAG;QAChE,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;KAChC,CAAC;IACF,eAAe,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC,GAAG;QACnE,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;KAChC,CAAC;CACH,GAAG,IAAI,CAAC,oBAAoB,EAAE,IAAI,GAAG,WAAW,GAAG,aAAa,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC;AAE/F,eAAO,MAAM,YAAY,GAAI,4HAW1B,iBAAiB,gCAiFnB,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionPrompt.test.d.ts","sourceRoot":"","sources":["../../../../src/prompt/ActionPrompt/ActionPrompt.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/prompt/ActionPrompt/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InlinePrompt.test.d.ts","sourceRoot":"","sources":["../../../../src/prompt/InlinePrompt/InlinePrompt.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrimitivePrompt.d.ts","sourceRoot":"","sources":["../../../../src/prompt/PrimitivePrompt/PrimitivePrompt.tsx"],"names":[],"mappings":"AAEA,OAAyB,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAIrE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;8GAE8G;AAC9G,eAAO,MAAM,eAAe,GAAI,6EAQ7B,oBAAoB,
|
|
1
|
+
{"version":3,"file":"PrimitivePrompt.d.ts","sourceRoot":"","sources":["../../../../src/prompt/PrimitivePrompt/PrimitivePrompt.tsx"],"names":[],"mappings":"AAEA,OAAyB,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAIrE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;8GAE8G;AAC9G,eAAO,MAAM,eAAe,GAAI,6EAQ7B,oBAAoB,gCA8BtB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrimitivePrompt.test.d.ts","sourceRoot":"","sources":["../../../../src/prompt/PrimitivePrompt/PrimitivePrompt.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/prompt/index.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/prompt/index.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,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-26bc819",
|
|
4
4
|
"description": "Neptune React components",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@storybook/react-webpack5": "10.3.0-alpha.0",
|
|
57
57
|
"@testing-library/dom": "^10.4.1",
|
|
58
58
|
"@testing-library/jest-dom": "^6.9.1",
|
|
59
|
-
"@testing-library/react": "^16.3.
|
|
59
|
+
"@testing-library/react": "^16.3.1",
|
|
60
60
|
"@testing-library/user-event": "^14.6.1",
|
|
61
61
|
"@transferwise/icons": "^4.0.2",
|
|
62
62
|
"@tsconfig/recommended": "^1.0.13",
|
|
@@ -78,7 +78,6 @@
|
|
|
78
78
|
"jest": "^30.2.0",
|
|
79
79
|
"jest-environment-jsdom": "^29.7.0",
|
|
80
80
|
"jest-fetch-mock": "^3.0.3",
|
|
81
|
-
"jsdom-testing-mocks": "^1.16.0",
|
|
82
81
|
"lodash.times": "^4.3.2",
|
|
83
82
|
"react-intl": "^7.1.11",
|
|
84
83
|
"rollup": "^4.54.0",
|
|
@@ -103,8 +102,8 @@
|
|
|
103
102
|
},
|
|
104
103
|
"dependencies": {
|
|
105
104
|
"@babel/runtime": "^7.28.4",
|
|
106
|
-
"@floating-ui/react": "^0.27.
|
|
107
|
-
"@headlessui/react": "^
|
|
105
|
+
"@floating-ui/react": "^0.27.16",
|
|
106
|
+
"@headlessui/react": "^1.7.19",
|
|
108
107
|
"@popperjs/core": "^2.11.8",
|
|
109
108
|
"@react-aria/focus": "^3.21.3",
|
|
110
109
|
"@react-aria/overlays": "^3.31.0",
|
|
@@ -120,7 +119,7 @@
|
|
|
120
119
|
"merge-props": "^6.0.0",
|
|
121
120
|
"react-popper": "^2.3.0",
|
|
122
121
|
"react-transition-group": "^4.4.5",
|
|
123
|
-
"virtua": "^0.48.
|
|
122
|
+
"virtua": "^0.48.3"
|
|
124
123
|
},
|
|
125
124
|
"publishConfig": {
|
|
126
125
|
"access": "public",
|
package/src/index.ts
CHANGED
|
@@ -35,7 +35,7 @@ export type { HeaderProps } from './header';
|
|
|
35
35
|
export type { EmphasisProps } from './emphasis';
|
|
36
36
|
export type { FieldProps } from './field/Field';
|
|
37
37
|
export type { InfoProps } from './info';
|
|
38
|
-
export type { InlinePromptProps } from './prompt';
|
|
38
|
+
export type { InlinePromptProps, ActionPromptProps } from './prompt';
|
|
39
39
|
export type { InputWithDisplayFormatProps } from './inputWithDisplayFormat';
|
|
40
40
|
export type { InputProps } from './inputs/Input';
|
|
41
41
|
export type { InputGroupProps } from './inputs/InputGroup';
|
|
@@ -171,7 +171,7 @@ export { default as Header } from './header';
|
|
|
171
171
|
export { default as Image } from './image';
|
|
172
172
|
export { default as Info } from './info';
|
|
173
173
|
export { default as InlineAlert } from './inlineAlert';
|
|
174
|
-
export { InlinePrompt } from './prompt';
|
|
174
|
+
export { InlinePrompt, ActionPrompt } from './prompt';
|
|
175
175
|
export { default as InputWithDisplayFormat } from './inputWithDisplayFormat';
|
|
176
176
|
export { Input } from './inputs/Input';
|
|
177
177
|
export { InputGroup } from './inputs/InputGroup';
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { screen, waitFor, within } from '@testing-library/react';
|
|
2
2
|
import { userEvent } from '@testing-library/user-event';
|
|
3
|
-
import { mockAnimationsApi } from 'jsdom-testing-mocks';
|
|
4
3
|
|
|
5
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
render,
|
|
6
|
+
mockMatchMedia,
|
|
7
|
+
mockResizeObserver,
|
|
8
|
+
mockRequestAnimationFrame,
|
|
9
|
+
} from '../test-utils';
|
|
6
10
|
|
|
7
11
|
import { SelectInput, type SelectInputOptionItem, type SelectInputProps } from './SelectInput';
|
|
8
12
|
import { Field } from '../field/Field';
|
|
9
13
|
|
|
10
14
|
mockMatchMedia();
|
|
11
15
|
mockResizeObserver();
|
|
12
|
-
|
|
16
|
+
mockRequestAnimationFrame();
|
|
13
17
|
|
|
14
18
|
describe('SelectInput', () => {
|
|
15
19
|
it('renders placeholder', () => {
|
|
@@ -63,81 +67,6 @@ describe('SelectInput', () => {
|
|
|
63
67
|
expect(footer).toHaveTextContent(/‘ur’$/);
|
|
64
68
|
});
|
|
65
69
|
|
|
66
|
-
it('allows navigating the listbox with cursors', async () => {
|
|
67
|
-
render(
|
|
68
|
-
<SelectInput
|
|
69
|
-
items={[
|
|
70
|
-
{ type: 'option', value: 'GBP' },
|
|
71
|
-
{ type: 'option', value: 'EUR' },
|
|
72
|
-
{ type: 'option', value: 'USD' },
|
|
73
|
-
]}
|
|
74
|
-
renderFooter={({ queryNormalized: normalizedQuery }) => (
|
|
75
|
-
<button type="button">Footer button</button>
|
|
76
|
-
)}
|
|
77
|
-
filterable
|
|
78
|
-
/>,
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
// opened the dropbox, with search focused
|
|
82
|
-
await userEvent.tab();
|
|
83
|
-
await userEvent.keyboard(' ');
|
|
84
|
-
expect(screen.getByRole('combobox')).toHaveFocus();
|
|
85
|
-
|
|
86
|
-
// search still focused but listbox can be navigated via keyboard
|
|
87
|
-
await userEvent.keyboard('{ArrowDown}');
|
|
88
|
-
expect(screen.getByRole('combobox')).toHaveFocus();
|
|
89
|
-
expect(screen.getByRole('option', { name: 'EUR' })).toHaveClass(
|
|
90
|
-
'np-select-input-option-container--active',
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
// tab moves focus to listbox
|
|
94
|
-
await userEvent.tab();
|
|
95
|
-
expect(screen.getByRole('listbox')).toHaveFocus();
|
|
96
|
-
expect(screen.getByRole('combobox')).not.toHaveFocus();
|
|
97
|
-
|
|
98
|
-
// arrows still navigate within listbox
|
|
99
|
-
await userEvent.keyboard('{ArrowDown}');
|
|
100
|
-
expect(screen.getByRole('option', { name: 'USD' })).toHaveClass(
|
|
101
|
-
'np-select-input-option-container--active',
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
// tab moves focus to footer but highlighted option is retained
|
|
105
|
-
await userEvent.tab();
|
|
106
|
-
expect(screen.getByRole('listbox')).not.toHaveFocus();
|
|
107
|
-
expect(screen.getByRole('combobox')).not.toHaveFocus();
|
|
108
|
-
expect(screen.getByText('Footer button')).toHaveFocus();
|
|
109
|
-
expect(screen.getByRole('option', { name: 'USD' })).toHaveClass(
|
|
110
|
-
'np-select-input-option-container--active',
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
// shift+tab moves focus back to listbox
|
|
114
|
-
await userEvent.tab({ shift: true });
|
|
115
|
-
expect(screen.getByRole('listbox')).toHaveFocus();
|
|
116
|
-
expect(screen.getByRole('combobox')).not.toHaveFocus();
|
|
117
|
-
expect(screen.getByText('Footer button')).not.toHaveFocus();
|
|
118
|
-
|
|
119
|
-
// previously highlighted option is still active within listbox
|
|
120
|
-
expect(screen.getByRole('option', { name: 'USD' })).toHaveClass(
|
|
121
|
-
'np-select-input-option-container--active',
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
// arrows continue to navigate within listbox
|
|
125
|
-
await userEvent.keyboard('{ArrowUp}');
|
|
126
|
-
expect(screen.getByRole('option', { name: 'EUR' })).toHaveClass(
|
|
127
|
-
'np-select-input-option-container--active',
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
// shift+tab moves focus back to search input
|
|
131
|
-
await userEvent.tab({ shift: true });
|
|
132
|
-
expect(screen.getByRole('combobox')).toHaveFocus();
|
|
133
|
-
|
|
134
|
-
// arrows continue to navigate within listbox
|
|
135
|
-
await userEvent.keyboard('{ArrowUp}');
|
|
136
|
-
expect(screen.getByRole('option', { name: 'GBP' })).toHaveClass(
|
|
137
|
-
'np-select-input-option-container--active',
|
|
138
|
-
);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
70
|
it('shows item selected via mouse', async () => {
|
|
142
71
|
const handleClose = jest.fn();
|
|
143
72
|
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Listbox as ListboxBase,
|
|
3
|
-
ListboxButton,
|
|
4
|
-
ListboxOption,
|
|
5
|
-
ListboxOptions,
|
|
6
|
-
} from '@headlessui/react';
|
|
1
|
+
import { Listbox as ListboxBase } from '@headlessui/react';
|
|
7
2
|
import { Check, ChevronDown, Cross, CrossCircle } from '@transferwise/icons';
|
|
8
3
|
import { clsx } from 'clsx';
|
|
9
4
|
import mergeProps from 'merge-props';
|
|
@@ -432,8 +427,8 @@ export function SelectInput<T = string, M extends boolean = false>({
|
|
|
432
427
|
<ListboxBase
|
|
433
428
|
name={name}
|
|
434
429
|
multiple={multiple}
|
|
435
|
-
defaultValue={defaultValue
|
|
436
|
-
value={controlledValue
|
|
430
|
+
defaultValue={defaultValue}
|
|
431
|
+
value={controlledValue}
|
|
437
432
|
by={compareValues}
|
|
438
433
|
disabled={disabled}
|
|
439
434
|
onChange={
|
|
@@ -581,7 +576,7 @@ export function SelectInputTriggerButton<T extends SelectInputTriggerButtonEleme
|
|
|
581
576
|
);
|
|
582
577
|
|
|
583
578
|
return (
|
|
584
|
-
<
|
|
579
|
+
<ListboxBase.Button
|
|
585
580
|
ref={ref}
|
|
586
581
|
as={PolymorphicWithOverrides}
|
|
587
582
|
role="combobox"
|
|
@@ -622,13 +617,8 @@ const SelectInputOptionsContainer = forwardRef(function SelectInputOptionsContai
|
|
|
622
617
|
return;
|
|
623
618
|
}
|
|
624
619
|
|
|
625
|
-
//
|
|
626
|
-
if (event.key === 'Tab') {
|
|
627
|
-
return;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
// Prevent absorbing Escape early
|
|
631
|
-
if (event.key === 'Escape') {
|
|
620
|
+
// Prevent absorbing actions early
|
|
621
|
+
if (event.key === 'Escape' || event.key === 'Tab') {
|
|
632
622
|
onKeyDown?.({
|
|
633
623
|
...event,
|
|
634
624
|
preventDefault: () => {},
|
|
@@ -827,8 +817,7 @@ function SelectInputOptions<T = string>({
|
|
|
827
817
|
};
|
|
828
818
|
|
|
829
819
|
return (
|
|
830
|
-
<
|
|
831
|
-
modal
|
|
820
|
+
<ListboxBase.Options
|
|
832
821
|
as={SelectInputOptionsContainer}
|
|
833
822
|
static
|
|
834
823
|
className="np-select-input-options-container"
|
|
@@ -985,7 +974,7 @@ function SelectInputOptions<T = string>({
|
|
|
985
974
|
</footer>
|
|
986
975
|
) : null}
|
|
987
976
|
</section>
|
|
988
|
-
</
|
|
977
|
+
</ListboxBase.Options>
|
|
989
978
|
);
|
|
990
979
|
}
|
|
991
980
|
|
|
@@ -1094,7 +1083,7 @@ function SelectInputOption<T = string>({ value, disabled, children }: SelectInpu
|
|
|
1094
1083
|
const itemsCount = useContext(SelectInputItemsCountContext);
|
|
1095
1084
|
const itemPosition = useContext(SelectInputItemPositionContext);
|
|
1096
1085
|
return (
|
|
1097
|
-
<
|
|
1086
|
+
<ListboxBase.Option
|
|
1098
1087
|
as="div"
|
|
1099
1088
|
value={value}
|
|
1100
1089
|
aria-setsize={itemsCount}
|
|
@@ -1120,7 +1109,7 @@ function SelectInputOption<T = string>({ value, disabled, children }: SelectInpu
|
|
|
1120
1109
|
/>
|
|
1121
1110
|
</>
|
|
1122
1111
|
)}
|
|
1123
|
-
</
|
|
1112
|
+
</ListboxBase.Option>
|
|
1124
1113
|
);
|
|
1125
1114
|
}
|
|
1126
1115
|
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
useInteractions,
|
|
7
7
|
useRole,
|
|
8
8
|
} from '@floating-ui/react';
|
|
9
|
-
import { Transition
|
|
9
|
+
import { Transition } from '@headlessui/react';
|
|
10
10
|
import { FocusScope } from '@react-aria/focus';
|
|
11
11
|
import { ThemeProvider, useTheme } from '@wise/components-theming';
|
|
12
12
|
import { clsx } from 'clsx';
|
|
@@ -73,7 +73,6 @@ export function BottomSheet({
|
|
|
73
73
|
<FloatingPortal>
|
|
74
74
|
<ThemeProvider theme="personal" screenMode={theme === 'personal' ? screenMode : 'light'}>
|
|
75
75
|
<Transition
|
|
76
|
-
as="div"
|
|
77
76
|
show={open}
|
|
78
77
|
className="np-bottom-sheet-v2-container"
|
|
79
78
|
beforeEnter={() => {
|
|
@@ -81,8 +80,7 @@ export function BottomSheet({
|
|
|
81
80
|
}}
|
|
82
81
|
afterLeave={onCloseEnd}
|
|
83
82
|
>
|
|
84
|
-
<
|
|
85
|
-
as="div"
|
|
83
|
+
<Transition.Child
|
|
86
84
|
className="np-bottom-sheet-v2-backdrop"
|
|
87
85
|
enterFrom="np-bottom-sheet-v2-backdrop--closed"
|
|
88
86
|
leaveTo="np-bottom-sheet-v2-backdrop--closed"
|
|
@@ -94,9 +92,8 @@ export function BottomSheet({
|
|
|
94
92
|
<Fragment
|
|
95
93
|
key={floatingKey} // Force inner state invalidation on open
|
|
96
94
|
>
|
|
97
|
-
<
|
|
95
|
+
<Transition.Child
|
|
98
96
|
ref={refs.setFloating}
|
|
99
|
-
as="div"
|
|
100
97
|
className="np-bottom-sheet-v2-content"
|
|
101
98
|
enterFrom="np-bottom-sheet-v2-content--closed"
|
|
102
99
|
leaveTo="np-bottom-sheet-v2-content--closed"
|
|
@@ -124,7 +121,7 @@ export function BottomSheet({
|
|
|
124
121
|
{children}
|
|
125
122
|
</div>
|
|
126
123
|
</div>
|
|
127
|
-
</
|
|
124
|
+
</Transition.Child>
|
|
128
125
|
</Fragment>
|
|
129
126
|
</FloatingFocusManager>
|
|
130
127
|
</FocusScope>
|
package/src/inputs/_Popover.tsx
CHANGED
|
@@ -51,7 +51,6 @@ export function Popover({
|
|
|
51
51
|
onCloseEnd,
|
|
52
52
|
}: PopoverProps) {
|
|
53
53
|
const { refs, floatingStyles, context } = useFloating<Element>({
|
|
54
|
-
strategy: 'fixed',
|
|
55
54
|
placement,
|
|
56
55
|
middleware: [
|
|
57
56
|
offset(8),
|
|
@@ -93,7 +92,6 @@ export function Popover({
|
|
|
93
92
|
<FloatingPortal>
|
|
94
93
|
<ThemeProvider theme="personal" screenMode={theme === 'personal' ? screenMode : 'light'}>
|
|
95
94
|
<Transition
|
|
96
|
-
as="div"
|
|
97
95
|
show={open}
|
|
98
96
|
leave="transition-opacity"
|
|
99
97
|
leaveTo="opacity-0"
|
package/src/main.css
CHANGED
|
@@ -5339,6 +5339,8 @@ html:not([dir="rtl"]) .np-navigation-option {
|
|
|
5339
5339
|
border-radius: 10px;
|
|
5340
5340
|
border-radius: var(--radius-small);
|
|
5341
5341
|
display: flex;
|
|
5342
|
+
gap: 16px;
|
|
5343
|
+
gap: var(--Prompt-gap, var(--size-16));
|
|
5342
5344
|
word-wrap: break-word;
|
|
5343
5345
|
padding: 8px;
|
|
5344
5346
|
padding: var(--Prompt-padding, var(--padding-x-small));
|
|
@@ -5354,6 +5356,9 @@ html:not([dir="rtl"]) .np-navigation-option {
|
|
|
5354
5356
|
grid-template-columns: auto 1fr;
|
|
5355
5357
|
width: 100%;
|
|
5356
5358
|
}
|
|
5359
|
+
.wds-prompt__content-wrapper--with-dismiss {
|
|
5360
|
+
grid-template-columns: auto 1fr auto;
|
|
5361
|
+
}
|
|
5357
5362
|
.wds-prompt__media-wrapper {
|
|
5358
5363
|
align-self: flex-start;
|
|
5359
5364
|
padding-top: calc(4px - 1px);
|
|
@@ -5369,12 +5374,16 @@ html:not([dir="rtl"]) .np-navigation-option {
|
|
|
5369
5374
|
gap: 8px;
|
|
5370
5375
|
gap: var(--Prompt-actions-gap, var(--size-8));
|
|
5371
5376
|
grid-column-start: 2;
|
|
5377
|
+
grid-column-end: 3;
|
|
5372
5378
|
}
|
|
5373
|
-
@media (max-width:
|
|
5379
|
+
@media (max-width: 767px) {
|
|
5374
5380
|
.wds-prompt__actions-wrapper {
|
|
5375
5381
|
grid-column: span 2;
|
|
5376
5382
|
width: 100%;
|
|
5377
5383
|
}
|
|
5384
|
+
.wds-prompt__content-wrapper--with-dismiss .wds-prompt__actions-wrapper {
|
|
5385
|
+
grid-column: span 3;
|
|
5386
|
+
}
|
|
5378
5387
|
}
|
|
5379
5388
|
.wds-inline-prompt {
|
|
5380
5389
|
--Prompt-gap: calc(var(--size-12) / 2);
|
|
@@ -7423,3 +7432,23 @@ html:not([dir="rtl"]) .np-navigation-option {
|
|
|
7423
7432
|
.np-list-item__action {
|
|
7424
7433
|
flex-shrink: 0;
|
|
7425
7434
|
}
|
|
7435
|
+
.wds-action-prompt {
|
|
7436
|
+
--Prompt-padding: var(--size-16);
|
|
7437
|
+
--Prompt-actions-gap: var(--size-8);
|
|
7438
|
+
--Prompt-gap: var(--size-10) var(--size-16);
|
|
7439
|
+
}
|
|
7440
|
+
.wds-action-prompt--media-image {
|
|
7441
|
+
width: 48px;
|
|
7442
|
+
width: var(--size-48);
|
|
7443
|
+
height: 48px;
|
|
7444
|
+
height: var(--size-48);
|
|
7445
|
+
-o-object-fit: contain;
|
|
7446
|
+
object-fit: contain;
|
|
7447
|
+
}
|
|
7448
|
+
@media (max-width: 767px) {
|
|
7449
|
+
.wds-action-prompt--with-two-actions .wds-prompt__actions-wrapper .wds-Button {
|
|
7450
|
+
flex: 1 1 calc(50% - (var(--Prompt-actions-gap) / 2));
|
|
7451
|
+
min-width: -moz-fit-content;
|
|
7452
|
+
min-width: fit-content;
|
|
7453
|
+
}
|
|
7454
|
+
}
|
package/src/main.less
CHANGED
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
@import "./progress/Progress.less";
|
|
87
87
|
@import "./progressBar/ProgressBar.less";
|
|
88
88
|
@import "./legacylistItem/LegacyListItem.less";
|
|
89
|
+
@import "./prompt/ActionPrompt/ActionPrompt.less";
|
|
89
90
|
|
|
90
91
|
// List all less files in src in alphabetical order: find -s src -type f -name '*.less' ! -name 'main.less'
|
|
91
92
|
// Make sure you are not referencing main.less itself in this file!
|
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import { mockAnimationsApi } from 'jsdom-testing-mocks';
|
|
2
1
|
import {
|
|
3
2
|
mockMatchMedia,
|
|
3
|
+
mockRequestAnimationFrame,
|
|
4
4
|
mockResizeObserver,
|
|
5
5
|
render,
|
|
6
6
|
screen,
|
|
7
7
|
userEvent,
|
|
8
|
-
waitFor,
|
|
9
|
-
within,
|
|
10
8
|
} from '../test-utils';
|
|
11
9
|
|
|
12
10
|
import { MoneyInput, CurrencyItem, CurrencyOptionItem, Field } from '..';
|
|
13
11
|
import { MoneyInputPropsWithInputAttributes } from './MoneyInput';
|
|
12
|
+
import { within } from '@testing-library/react';
|
|
14
13
|
import messages from './MoneyInput.messages';
|
|
15
14
|
|
|
16
15
|
mockMatchMedia();
|
|
17
16
|
mockResizeObserver();
|
|
18
|
-
|
|
17
|
+
mockRequestAnimationFrame();
|
|
19
18
|
|
|
20
19
|
describe('Money Input', () => {
|
|
21
20
|
const popularCurrencies: CurrencyOptionItem[] = [
|
|
@@ -115,30 +114,12 @@ describe('Money Input', () => {
|
|
|
115
114
|
it('calls onCurrencyChange when the user selects a different currency', async () => {
|
|
116
115
|
customRender();
|
|
117
116
|
await openDropdown();
|
|
118
|
-
await userEvent.keyboard('eur');
|
|
119
|
-
|
|
120
|
-
expect(screen.getAllByRole('option')).toHaveLength(1);
|
|
121
|
-
});
|
|
122
|
-
await userEvent.keyboard('{Enter}');
|
|
123
|
-
|
|
124
|
-
await waitFor(() => {
|
|
125
|
-
expect(initialProps.onCurrencyChange).toHaveBeenCalledTimes(1);
|
|
126
|
-
});
|
|
117
|
+
await userEvent.keyboard('eur{Enter}');
|
|
118
|
+
expect(initialProps.onCurrencyChange).toHaveBeenCalledTimes(1);
|
|
127
119
|
expect(initialProps.onCurrencyChange).toHaveBeenCalledWith(popularCurrencies[0]);
|
|
128
|
-
|
|
129
|
-
await waitFor(() => {
|
|
130
|
-
expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
|
|
131
|
-
});
|
|
132
120
|
await openDropdown();
|
|
133
|
-
await userEvent.keyboard('gbp');
|
|
134
|
-
|
|
135
|
-
expect(screen.getAllByRole('option')).toHaveLength(1);
|
|
136
|
-
});
|
|
137
|
-
await userEvent.keyboard('{Enter}');
|
|
138
|
-
|
|
139
|
-
await waitFor(() => {
|
|
140
|
-
expect(initialProps.onCurrencyChange).toHaveBeenCalledTimes(2);
|
|
141
|
-
});
|
|
121
|
+
await userEvent.keyboard('gbp{Enter}');
|
|
122
|
+
expect(initialProps.onCurrencyChange).toHaveBeenCalledTimes(2);
|
|
142
123
|
expect(initialProps.onCurrencyChange).toHaveBeenCalledWith(popularCurrencies[2]);
|
|
143
124
|
});
|
|
144
125
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.wds-action-prompt {
|
|
2
|
+
--Prompt-padding: var(--size-16);
|
|
3
|
+
--Prompt-actions-gap: var(--size-8);
|
|
4
|
+
--Prompt-gap: var(--size-10) var(--size-16);
|
|
5
|
+
}
|
|
6
|
+
.wds-action-prompt--media-image {
|
|
7
|
+
width: 48px;
|
|
8
|
+
width: var(--size-48);
|
|
9
|
+
height: 48px;
|
|
10
|
+
height: var(--size-48);
|
|
11
|
+
-o-object-fit: contain;
|
|
12
|
+
object-fit: contain;
|
|
13
|
+
}
|
|
14
|
+
@media (max-width: 767px) {
|
|
15
|
+
.wds-action-prompt--with-two-actions .wds-prompt__actions-wrapper .wds-Button {
|
|
16
|
+
flex: 1 1 calc(50% - (var(--Prompt-actions-gap) / 2));
|
|
17
|
+
min-width: -moz-fit-content;
|
|
18
|
+
min-width: fit-content;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.wds-action-prompt {
|
|
2
|
+
--Prompt-padding: var(--size-16);
|
|
3
|
+
--Prompt-actions-gap: var(--size-8);
|
|
4
|
+
--Prompt-gap: var(--size-10) var(--size-16);
|
|
5
|
+
|
|
6
|
+
&--media-image {
|
|
7
|
+
width: var(--size-48);
|
|
8
|
+
height: var(--size-48);
|
|
9
|
+
object-fit: contain;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
&--with-two-actions {
|
|
13
|
+
@media (--screen-sm-max) {
|
|
14
|
+
.wds-prompt__actions-wrapper {
|
|
15
|
+
.wds-Button {
|
|
16
|
+
flex: 1 1 calc(50% - (var(--Prompt-actions-gap) / 2));
|
|
17
|
+
min-width: fit-content;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|