@transferwise/components 0.0.0-experimental-9442a3d → 0.0.0-experimental-6fb3b67
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/dateInput/DateInput.js +2 -2
- package/build/dateInput/DateInput.js.map +1 -1
- package/build/dateInput/DateInput.mjs +2 -2
- package/build/dateInput/DateInput.mjs.map +1 -1
- package/build/inputs/_BottomSheet.js +29 -1
- package/build/inputs/_BottomSheet.js.map +1 -1
- package/build/inputs/_BottomSheet.mjs +30 -2
- package/build/inputs/_BottomSheet.mjs.map +1 -1
- package/build/main.css +20 -5
- package/build/phoneNumberInput/PhoneNumberInput.js +1 -1
- package/build/phoneNumberInput/PhoneNumberInput.js.map +1 -1
- package/build/phoneNumberInput/PhoneNumberInput.mjs +1 -1
- package/build/phoneNumberInput/PhoneNumberInput.mjs.map +1 -1
- package/build/styles/inputs/Input.css +5 -0
- package/build/styles/inputs/SelectInput.css +15 -5
- package/build/styles/inputs/TextArea.css +5 -0
- package/build/styles/main.css +20 -5
- package/build/types/inputs/_BottomSheet.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/DisabledComponents.story.tsx +156 -0
- package/src/common/bottomSheet/BottomSheet.test.story.tsx +94 -0
- package/src/dateInput/DateInput.tsx +2 -2
- package/src/inputs/Input.css +5 -0
- package/src/inputs/SelectInput.css +15 -5
- package/src/inputs/SelectInput.spec.tsx +33 -0
- package/src/inputs/SelectInput.test.story.tsx +83 -0
- package/src/inputs/TextArea.css +5 -0
- package/src/inputs/_BottomSheet.less +15 -3
- package/src/inputs/_BottomSheet.tsx +19 -3
- package/src/inputs/_common.less +5 -0
- package/src/main.css +20 -5
- package/src/moneyInput/MoneyInput.test.story.tsx +101 -0
- package/src/phoneNumberInput/PhoneNumberInput.tsx +1 -1
|
@@ -291,7 +291,7 @@ const DateInput = ({
|
|
|
291
291
|
<div className="col-sm-3 tw-date--day">
|
|
292
292
|
<label>
|
|
293
293
|
<Body type={Typography.BODY_DEFAULT}>{dayLabel}</Body>
|
|
294
|
-
<div className={`input-group input-group-${size}`}>
|
|
294
|
+
<div className={`input-group input-group-${size} ${disabled ? 'disabled' : ''}`}>
|
|
295
295
|
<Input
|
|
296
296
|
ref={dayRef}
|
|
297
297
|
id={`${id}:day`}
|
|
@@ -319,7 +319,7 @@ const DateInput = ({
|
|
|
319
319
|
<div className="col-sm-4 tw-date--year">
|
|
320
320
|
<label>
|
|
321
321
|
<Body type={Typography.BODY_DEFAULT}>{yearLabel}</Body>
|
|
322
|
-
<div className={`input-group input-group-${size}`}>
|
|
322
|
+
<div className={`input-group input-group-${size} ${disabled ? 'disabled' : ''}`}>
|
|
323
323
|
<Input
|
|
324
324
|
ref={yearRef}
|
|
325
325
|
id={`${id}:year`}
|
package/src/inputs/Input.css
CHANGED
|
@@ -18,6 +18,11 @@
|
|
|
18
18
|
transition-duration: 300ms;
|
|
19
19
|
/* TODO: Remove these overrides once `.form-control` isn’t used anymore */
|
|
20
20
|
}
|
|
21
|
+
.disabled .np-form-control,
|
|
22
|
+
:disabled .np-form-control {
|
|
23
|
+
opacity: 1;
|
|
24
|
+
opacity: initial;
|
|
25
|
+
}
|
|
21
26
|
.np-form-control:focus-visible {
|
|
22
27
|
outline: none;
|
|
23
28
|
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
.wds-select-input-scroll-freeze {
|
|
2
|
+
scroll-behavior: unset !important;
|
|
3
|
+
height: 100vh;
|
|
4
|
+
}
|
|
5
|
+
.wds-select-input-scroll-freeze body {
|
|
6
|
+
height: 100vh;
|
|
7
|
+
}
|
|
1
8
|
.np-bottom-sheet-v2-container {
|
|
2
9
|
position: relative;
|
|
3
10
|
z-index: 1060;
|
|
@@ -11,6 +18,8 @@
|
|
|
11
18
|
transition-property: opacity;
|
|
12
19
|
transition-timing-function: ease-out;
|
|
13
20
|
transition-duration: 300ms;
|
|
21
|
+
will-change: transform;
|
|
22
|
+
min-height: 100vh;
|
|
14
23
|
}
|
|
15
24
|
.np-bottom-sheet-v2-backdrop--closed {
|
|
16
25
|
opacity: 0;
|
|
@@ -18,7 +27,7 @@
|
|
|
18
27
|
.np-bottom-sheet-v2 {
|
|
19
28
|
position: fixed;
|
|
20
29
|
inset: 0px;
|
|
21
|
-
bottom: env(
|
|
30
|
+
bottom: env(safe-area-inset-bottom, 0);
|
|
22
31
|
margin-left: 8px;
|
|
23
32
|
margin-left: var(--size-8);
|
|
24
33
|
margin-right: 8px;
|
|
@@ -28,18 +37,19 @@
|
|
|
28
37
|
display: flex;
|
|
29
38
|
flex-direction: column;
|
|
30
39
|
justify-content: flex-end;
|
|
40
|
+
height: calc(100vh - 64px - 40px);
|
|
41
|
+
height: calc(100vh - var(--size-64) - 40px);
|
|
31
42
|
}
|
|
32
43
|
.np-bottom-sheet-v2-content {
|
|
33
44
|
display: flex;
|
|
34
45
|
flex-direction: column;
|
|
35
46
|
overflow: auto;
|
|
36
|
-
border-
|
|
37
|
-
|
|
38
|
-
border-top-right-radius: 32px;
|
|
39
|
-
/* TODO: Tokenize */
|
|
47
|
+
border-radius: 32px;
|
|
48
|
+
border-radius: var(--size-32);
|
|
40
49
|
background-color: #ffffff;
|
|
41
50
|
background-color: var(--color-background-elevated);
|
|
42
51
|
box-shadow: 0 0 40px rgba(69, 71, 69, 0.2);
|
|
52
|
+
will-change: transform;
|
|
43
53
|
}
|
|
44
54
|
.np-bottom-sheet-v2-content:focus {
|
|
45
55
|
outline: none;
|
|
@@ -3,13 +3,21 @@ import { userEvent } from '@testing-library/user-event';
|
|
|
3
3
|
|
|
4
4
|
import { render, mockMatchMedia, mockResizeObserver } from '../test-utils';
|
|
5
5
|
|
|
6
|
+
import { useScreenSize } from '../common/hooks/useScreenSize';
|
|
6
7
|
import { SelectInput, type SelectInputOptionItem, type SelectInputProps } from './SelectInput';
|
|
7
8
|
import { Field } from '../field/Field';
|
|
8
9
|
|
|
9
10
|
mockMatchMedia();
|
|
10
11
|
mockResizeObserver();
|
|
12
|
+
jest.mock('../common/hooks/useScreenSize');
|
|
11
13
|
|
|
12
14
|
describe('SelectInput', () => {
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
(useScreenSize as jest.Mock).mockReturnValue(true);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
afterEach(jest.clearAllMocks);
|
|
20
|
+
|
|
13
21
|
it('renders placeholder', () => {
|
|
14
22
|
render(
|
|
15
23
|
<SelectInput
|
|
@@ -309,4 +317,29 @@ describe('SelectInput', () => {
|
|
|
309
317
|
expect(listBox).not.toHaveAttribute('aria-labelledby');
|
|
310
318
|
});
|
|
311
319
|
});
|
|
320
|
+
|
|
321
|
+
describe('smooth scroll reset', () => {
|
|
322
|
+
const options: SelectInputOptionItem[] = [
|
|
323
|
+
{ type: 'option', value: 'Banana' },
|
|
324
|
+
{ type: 'option', value: 'Orange' },
|
|
325
|
+
{ type: 'option', value: 'Olive' },
|
|
326
|
+
];
|
|
327
|
+
|
|
328
|
+
beforeEach(() => {
|
|
329
|
+
(useScreenSize as jest.Mock).mockReturnValue(false);
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
afterEach(jest.clearAllMocks);
|
|
333
|
+
|
|
334
|
+
it('toggles scroll-resetting class', async () => {
|
|
335
|
+
render(<SelectInput items={options} />);
|
|
336
|
+
expect(document.documentElement).not.toHaveClass('wds-select-input-scroll-freeze');
|
|
337
|
+
|
|
338
|
+
await userEvent.click(screen.getByRole('combobox'));
|
|
339
|
+
expect(document.documentElement).toHaveClass('wds-select-input-scroll-freeze');
|
|
340
|
+
|
|
341
|
+
await userEvent.click(document.documentElement);
|
|
342
|
+
expect(document.documentElement).not.toHaveClass('wds-select-input-scroll-freeze');
|
|
343
|
+
});
|
|
344
|
+
});
|
|
312
345
|
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
+
import { fn, type Mock, userEvent, within } from 'storybook/test';
|
|
3
|
+
import { allModes } from '../../.storybook/modes';
|
|
4
|
+
import { lorem5, lorem500 } from '../test-utils';
|
|
5
|
+
import { Field } from '../field/Field';
|
|
6
|
+
import Body from '../body';
|
|
7
|
+
import { SelectInput, type SelectInputProps } from './SelectInput';
|
|
8
|
+
|
|
9
|
+
const meta = {
|
|
10
|
+
title: 'Forms/SelectInput/tests',
|
|
11
|
+
component: SelectInput,
|
|
12
|
+
args: {
|
|
13
|
+
onFilterChange: fn() satisfies Mock,
|
|
14
|
+
onChange: fn() satisfies Mock,
|
|
15
|
+
onClose: fn() satisfies Mock,
|
|
16
|
+
onOpen: fn() satisfies Mock,
|
|
17
|
+
},
|
|
18
|
+
tags: ['!autodocs'],
|
|
19
|
+
} satisfies Meta<typeof SelectInput>;
|
|
20
|
+
export default meta;
|
|
21
|
+
|
|
22
|
+
type Story<T, M extends boolean = false> = StoryObj<SelectInputProps<T, M>>;
|
|
23
|
+
|
|
24
|
+
const wait = async (duration = 500) =>
|
|
25
|
+
new Promise<void>((resolve) => {
|
|
26
|
+
setTimeout(resolve, duration);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* This test ensures that when the SelectInput is used within a scrollable page,
|
|
31
|
+
* opening the dropdown does not cause any unwanted scrolling or layout shifts.
|
|
32
|
+
* Expected preview should start with green bar at the top, with yellow section
|
|
33
|
+
* not in the viewport.
|
|
34
|
+
*
|
|
35
|
+
* NB: This test is disabled in Chromatic as there's no obvious way to control <html/> element of a snapshot.
|
|
36
|
+
*/
|
|
37
|
+
export const SmoothScrollReset: Story<string> = {
|
|
38
|
+
args: {
|
|
39
|
+
items: Array.from({ length: 15 }).map((_, id) => ({
|
|
40
|
+
type: 'option',
|
|
41
|
+
value: `option ${id + 1}`,
|
|
42
|
+
})),
|
|
43
|
+
placeholder: 'Select option',
|
|
44
|
+
},
|
|
45
|
+
decorators: [
|
|
46
|
+
(Story) => (
|
|
47
|
+
<>
|
|
48
|
+
<style>{`html { scroll-behavior: smooth; }`}</style>
|
|
49
|
+
<div>
|
|
50
|
+
<div
|
|
51
|
+
className="d-flex align-items-center justify-content-center"
|
|
52
|
+
style={{
|
|
53
|
+
backgroundColor: 'var(--color-bright-yellow)',
|
|
54
|
+
height: 400,
|
|
55
|
+
}}
|
|
56
|
+
>
|
|
57
|
+
This block should not be in the viewport.
|
|
58
|
+
</div>
|
|
59
|
+
<div style={{ height: 10, backgroundColor: 'var(--color-bright-green)' }} />
|
|
60
|
+
<Field id="el1" label={lorem5}>
|
|
61
|
+
<Story />
|
|
62
|
+
</Field>
|
|
63
|
+
<Body as="p">{lorem500}</Body>
|
|
64
|
+
</div>
|
|
65
|
+
</>
|
|
66
|
+
),
|
|
67
|
+
],
|
|
68
|
+
play: async ({ canvasElement }) => {
|
|
69
|
+
document.documentElement.scrollTop = 400;
|
|
70
|
+
await wait();
|
|
71
|
+
const canvas = within(canvasElement);
|
|
72
|
+
const triggerButton = canvas.getByRole('combobox');
|
|
73
|
+
await userEvent.click(triggerButton);
|
|
74
|
+
},
|
|
75
|
+
globals: {
|
|
76
|
+
viewport: { value: allModes.largeMobile.viewport, isRotated: false },
|
|
77
|
+
},
|
|
78
|
+
parameters: {
|
|
79
|
+
chromatic: {
|
|
80
|
+
disableSnapshot: true,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
};
|
package/src/inputs/TextArea.css
CHANGED
|
@@ -18,6 +18,11 @@
|
|
|
18
18
|
transition-duration: 300ms;
|
|
19
19
|
/* TODO: Remove these overrides once `.form-control` isn’t used anymore */
|
|
20
20
|
}
|
|
21
|
+
.disabled .np-form-control,
|
|
22
|
+
:disabled .np-form-control {
|
|
23
|
+
opacity: 1;
|
|
24
|
+
opacity: initial;
|
|
25
|
+
}
|
|
21
26
|
.np-form-control:focus-visible {
|
|
22
27
|
outline: none;
|
|
23
28
|
}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
.wds-select-input-scroll-freeze {
|
|
2
|
+
scroll-behavior: unset !important;
|
|
3
|
+
height: 100vh;
|
|
4
|
+
|
|
5
|
+
body{
|
|
6
|
+
height: 100vh;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
1
10
|
.np-bottom-sheet-v2-container {
|
|
2
11
|
position: relative;
|
|
3
12
|
z-index: 1060;
|
|
@@ -11,6 +20,8 @@
|
|
|
11
20
|
transition-property: opacity;
|
|
12
21
|
transition-timing-function: ease-out;
|
|
13
22
|
transition-duration: 300ms;
|
|
23
|
+
will-change: transform;
|
|
24
|
+
min-height: 100vh;
|
|
14
25
|
|
|
15
26
|
&--closed {
|
|
16
27
|
opacity: 0;
|
|
@@ -20,23 +31,24 @@
|
|
|
20
31
|
.np-bottom-sheet-v2 {
|
|
21
32
|
position: fixed;
|
|
22
33
|
inset: 0px;
|
|
23
|
-
bottom: env(
|
|
34
|
+
bottom: env(safe-area-inset-bottom, 0);
|
|
24
35
|
margin-left: var(--size-8);
|
|
25
36
|
margin-right: var(--size-8);
|
|
26
37
|
margin-top: var(--size-64);
|
|
27
38
|
display: flex;
|
|
28
39
|
flex-direction: column;
|
|
29
40
|
justify-content: flex-end;
|
|
41
|
+
height: calc(100vh - var(--size-64) - 40px);
|
|
30
42
|
}
|
|
31
43
|
|
|
32
44
|
.np-bottom-sheet-v2-content {
|
|
33
45
|
display: flex;
|
|
34
46
|
flex-direction: column;
|
|
35
47
|
overflow: auto;
|
|
36
|
-
border-
|
|
37
|
-
border-top-right-radius: 32px; /* TODO: Tokenize */
|
|
48
|
+
border-radius: var(--size-32);
|
|
38
49
|
background-color: var(--color-background-elevated);
|
|
39
50
|
box-shadow: 0 0 40px rgb(69 71 69 / 0.2);
|
|
51
|
+
will-change: transform;
|
|
40
52
|
|
|
41
53
|
&:focus {
|
|
42
54
|
outline: none;
|
|
@@ -10,12 +10,11 @@ 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';
|
|
13
|
-
import { Fragment, useState } from 'react';
|
|
13
|
+
import { Fragment, useEffect, useState } from 'react';
|
|
14
14
|
|
|
15
|
-
import { CloseButton } from '../common
|
|
15
|
+
import { CloseButton , Size } from '../common';
|
|
16
16
|
import { useVirtualKeyboard } from '../common/hooks/useVirtualKeyboard';
|
|
17
17
|
import { PreventScroll } from '../common/preventScroll/PreventScroll';
|
|
18
|
-
import { Size } from '../common/propsValues/size';
|
|
19
18
|
|
|
20
19
|
export interface BottomSheetProps {
|
|
21
20
|
open: boolean;
|
|
@@ -33,6 +32,19 @@ export interface BottomSheetProps {
|
|
|
33
32
|
onCloseEnd?: () => void;
|
|
34
33
|
}
|
|
35
34
|
|
|
35
|
+
/**
|
|
36
|
+
* App pages set scroll-behavior to 'smooth' which causes mobile Safari to
|
|
37
|
+
* slow-scroll and glitch. This function temporarily disables that behaviour
|
|
38
|
+
* while the BottomSheet is open. It complements <PreventScroll />.
|
|
39
|
+
*/
|
|
40
|
+
const freezeScroll = (shouldFreeze = true) => {
|
|
41
|
+
if (shouldFreeze) {
|
|
42
|
+
document.documentElement.classList.add('wds-select-input-scroll-freeze');
|
|
43
|
+
} else {
|
|
44
|
+
document.documentElement.classList.remove('wds-select-input-scroll-freeze');
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
36
48
|
export function BottomSheet({
|
|
37
49
|
open,
|
|
38
50
|
renderTrigger,
|
|
@@ -54,6 +66,10 @@ export function BottomSheet({
|
|
|
54
66
|
},
|
|
55
67
|
});
|
|
56
68
|
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
freezeScroll(open);
|
|
71
|
+
}, [open]);
|
|
72
|
+
|
|
57
73
|
const dismiss = useDismiss(context);
|
|
58
74
|
const role = useRole(context);
|
|
59
75
|
const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, role]);
|
package/src/inputs/_common.less
CHANGED
package/src/main.css
CHANGED
|
@@ -2660,6 +2660,11 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
|
|
|
2660
2660
|
transition-duration: 300ms;
|
|
2661
2661
|
/* TODO: Remove these overrides once `.form-control` isn’t used anymore */
|
|
2662
2662
|
}
|
|
2663
|
+
.disabled .np-form-control,
|
|
2664
|
+
:disabled .np-form-control {
|
|
2665
|
+
opacity: 1;
|
|
2666
|
+
opacity: initial;
|
|
2667
|
+
}
|
|
2663
2668
|
.np-form-control:focus-visible {
|
|
2664
2669
|
outline: none;
|
|
2665
2670
|
}
|
|
@@ -3519,6 +3524,13 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
|
|
|
3519
3524
|
padding-inline-start: 8px;
|
|
3520
3525
|
padding-inline-start: var(--size-8);
|
|
3521
3526
|
}
|
|
3527
|
+
.wds-select-input-scroll-freeze {
|
|
3528
|
+
scroll-behavior: unset !important;
|
|
3529
|
+
height: 100vh;
|
|
3530
|
+
}
|
|
3531
|
+
.wds-select-input-scroll-freeze body {
|
|
3532
|
+
height: 100vh;
|
|
3533
|
+
}
|
|
3522
3534
|
.np-bottom-sheet-v2-container {
|
|
3523
3535
|
position: relative;
|
|
3524
3536
|
z-index: 1060;
|
|
@@ -3532,6 +3544,8 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
|
|
|
3532
3544
|
transition-property: opacity;
|
|
3533
3545
|
transition-timing-function: ease-out;
|
|
3534
3546
|
transition-duration: 300ms;
|
|
3547
|
+
will-change: transform;
|
|
3548
|
+
min-height: 100vh;
|
|
3535
3549
|
}
|
|
3536
3550
|
.np-bottom-sheet-v2-backdrop--closed {
|
|
3537
3551
|
opacity: 0;
|
|
@@ -3539,7 +3553,7 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
|
|
|
3539
3553
|
.np-bottom-sheet-v2 {
|
|
3540
3554
|
position: fixed;
|
|
3541
3555
|
inset: 0px;
|
|
3542
|
-
bottom: env(
|
|
3556
|
+
bottom: env(safe-area-inset-bottom, 0);
|
|
3543
3557
|
margin-left: 8px;
|
|
3544
3558
|
margin-left: var(--size-8);
|
|
3545
3559
|
margin-right: 8px;
|
|
@@ -3549,18 +3563,19 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
|
|
|
3549
3563
|
display: flex;
|
|
3550
3564
|
flex-direction: column;
|
|
3551
3565
|
justify-content: flex-end;
|
|
3566
|
+
height: calc(100vh - 64px - 40px);
|
|
3567
|
+
height: calc(100vh - var(--size-64) - 40px);
|
|
3552
3568
|
}
|
|
3553
3569
|
.np-bottom-sheet-v2-content {
|
|
3554
3570
|
display: flex;
|
|
3555
3571
|
flex-direction: column;
|
|
3556
3572
|
overflow: auto;
|
|
3557
|
-
border-
|
|
3558
|
-
|
|
3559
|
-
border-top-right-radius: 32px;
|
|
3560
|
-
/* TODO: Tokenize */
|
|
3573
|
+
border-radius: 32px;
|
|
3574
|
+
border-radius: var(--size-32);
|
|
3561
3575
|
background-color: #ffffff;
|
|
3562
3576
|
background-color: var(--color-background-elevated);
|
|
3563
3577
|
box-shadow: 0 0 40px rgba(69, 71, 69, 0.2);
|
|
3578
|
+
will-change: transform;
|
|
3564
3579
|
}
|
|
3565
3580
|
.np-bottom-sheet-v2-content:focus {
|
|
3566
3581
|
outline: none;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
+
import { userEvent, within } from 'storybook/test';
|
|
3
|
+
import { allModes } from '../../.storybook/modes';
|
|
4
|
+
import { lorem500 } from '../test-utils';
|
|
5
|
+
import { Field } from '../field/Field';
|
|
6
|
+
import Body from '../body';
|
|
7
|
+
import MoneyInput from './MoneyInput';
|
|
8
|
+
|
|
9
|
+
const meta = {
|
|
10
|
+
title: 'Forms/MoneyInput/tests',
|
|
11
|
+
component: MoneyInput,
|
|
12
|
+
args: {
|
|
13
|
+
amount: 1000,
|
|
14
|
+
id: 'moneyInput',
|
|
15
|
+
currencies: [
|
|
16
|
+
{
|
|
17
|
+
value: 'EUR',
|
|
18
|
+
label: 'EUR',
|
|
19
|
+
note: 'Euro',
|
|
20
|
+
currency: 'eur',
|
|
21
|
+
searchable: 'Spain, Germany, France, Austria',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
value: 'GBP',
|
|
25
|
+
label: 'GBP',
|
|
26
|
+
note: 'British pound',
|
|
27
|
+
currency: 'gbp',
|
|
28
|
+
searchable: 'England, Scotland, Wales',
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
selectedCurrency: {
|
|
32
|
+
value: 'EUR',
|
|
33
|
+
label: 'EUR',
|
|
34
|
+
note: 'Euro',
|
|
35
|
+
currency: 'eur',
|
|
36
|
+
searchable: 'Spain, Germany, France, Austria',
|
|
37
|
+
},
|
|
38
|
+
searchPlaceholder: '',
|
|
39
|
+
onAmountChange: () => {},
|
|
40
|
+
onCurrencyChange: () => {},
|
|
41
|
+
},
|
|
42
|
+
tags: ['!autodocs'],
|
|
43
|
+
} satisfies Meta<typeof MoneyInput>;
|
|
44
|
+
export default meta;
|
|
45
|
+
|
|
46
|
+
type Story = StoryObj<typeof MoneyInput>;
|
|
47
|
+
|
|
48
|
+
const wait = async (duration = 500) =>
|
|
49
|
+
new Promise<void>((resolve) => {
|
|
50
|
+
setTimeout(resolve, duration);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* This test ensures that when the SelectInput is used within a scrollable page,
|
|
55
|
+
* opening the dropdown does not cause any unwanted scrolling or layout shifts.
|
|
56
|
+
* Expected preview should start with green bar at the top, with yellow section
|
|
57
|
+
* not in the viewport.
|
|
58
|
+
*
|
|
59
|
+
* NB: This test is disabled in Chromatic as there's no obvious way to control <html/> element of a snapshot.
|
|
60
|
+
*/
|
|
61
|
+
export const SmoothScrollReset: Story = {
|
|
62
|
+
decorators: [
|
|
63
|
+
(Story) => (
|
|
64
|
+
<>
|
|
65
|
+
<style>{`html { scroll-behavior: smooth; }`}</style>
|
|
66
|
+
<div>
|
|
67
|
+
<div
|
|
68
|
+
className="d-flex align-items-center justify-content-center"
|
|
69
|
+
style={{
|
|
70
|
+
backgroundColor: 'var(--color-bright-yellow)',
|
|
71
|
+
height: 400,
|
|
72
|
+
}}
|
|
73
|
+
>
|
|
74
|
+
This block should not be in the viewport.
|
|
75
|
+
</div>
|
|
76
|
+
<div style={{ height: 10, backgroundColor: 'var(--color-bright-green)' }} />
|
|
77
|
+
<Field id="el1" label="Select currency">
|
|
78
|
+
<Story />
|
|
79
|
+
</Field>
|
|
80
|
+
<Body as="p">{lorem500}</Body>
|
|
81
|
+
</div>
|
|
82
|
+
</>
|
|
83
|
+
),
|
|
84
|
+
],
|
|
85
|
+
play: async ({ canvasElement }) => {
|
|
86
|
+
await wait();
|
|
87
|
+
document.documentElement.scrollTop = 400;
|
|
88
|
+
await wait();
|
|
89
|
+
const canvas = within(canvasElement);
|
|
90
|
+
const triggerButton = canvas.getByRole('combobox');
|
|
91
|
+
await userEvent.click(triggerButton);
|
|
92
|
+
},
|
|
93
|
+
globals: {
|
|
94
|
+
viewport: { value: allModes.largeMobile.viewport, isRotated: false },
|
|
95
|
+
},
|
|
96
|
+
parameters: {
|
|
97
|
+
chromatic: {
|
|
98
|
+
disableSnapshot: true,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
};
|
|
@@ -245,7 +245,7 @@ const PhoneNumberInput = ({
|
|
|
245
245
|
{formatMessage(messages.phoneNumberLabel)}
|
|
246
246
|
</label>
|
|
247
247
|
<div className="tw-telephone__number-input">
|
|
248
|
-
<div className={`input-group input-group-${size}`}>
|
|
248
|
+
<div className={`input-group input-group-${size} ${disabled ? 'disabled' : ''}`}>
|
|
249
249
|
<Input
|
|
250
250
|
ref={phoneNumberInputRef}
|
|
251
251
|
id={ids.phoneNumber.input}
|