@transferwise/components 46.135.1 → 46.135.3
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/avatarWrapper/AvatarWrapper.js.map +1 -1
- package/build/avatarWrapper/AvatarWrapper.mjs.map +1 -1
- package/build/common/panel/Panel.js +49 -54
- package/build/common/panel/Panel.js.map +1 -1
- package/build/common/panel/Panel.mjs +54 -59
- package/build/common/panel/Panel.mjs.map +1 -1
- package/build/listItem/ListItem.js +2 -2
- package/build/listItem/ListItem.js.map +1 -1
- package/build/listItem/ListItem.mjs +2 -2
- package/build/listItem/ListItem.mjs.map +1 -1
- package/build/main.css +4 -3
- package/build/select/Select.js +1 -1
- package/build/select/Select.js.map +1 -1
- package/build/select/Select.mjs +1 -1
- package/build/select/Select.mjs.map +1 -1
- package/build/styles/main.css +4 -3
- package/build/styles/modal/Modal.css +2 -2
- package/build/styles/select/Select.css +2 -1
- package/build/tooltip/Tooltip.js +29 -50
- package/build/tooltip/Tooltip.js.map +1 -1
- package/build/tooltip/Tooltip.mjs +30 -51
- package/build/tooltip/Tooltip.mjs.map +1 -1
- package/build/types/common/panel/Panel.d.ts.map +1 -1
- package/build/types/tooltip/Tooltip.d.ts.map +1 -1
- package/package.json +9 -11
- package/src/actionButton/ActionButton.story.tsx +4 -4
- package/src/actionButton/ActionButton.test.story.tsx +4 -4
- package/src/avatarWrapper/AvatarWrapper.tsx +3 -3
- package/src/common/circle/Circle.story.tsx +3 -3
- package/src/common/panel/Panel.tsx +56 -49
- package/src/iconButton/IconButton.story.tsx +5 -6
- package/src/iconButton/IconButton.test.story.tsx +8 -8
- package/src/icons/Icons.story.tsx +381 -0
- package/src/listItem/ListItem.test.tsx +24 -0
- package/src/listItem/ListItem.tsx +2 -2
- package/src/listItem/_stories/ListItem.context.test.story.tsx +63 -0
- package/src/listItem/_stories/ListItem.scenarios.story.tsx +3 -3
- package/src/main.css +4 -3
- package/src/modal/Modal.css +2 -2
- package/src/modal/Modal.less +1 -1
- package/src/moneyInput/MoneyInput.story.tsx +2 -2
- package/src/navigationOption/NavigationOption.story.tsx +3 -3
- package/src/overlayHeader/OverlayHeader.story.tsx +2 -2
- package/src/prompt/ActionPrompt/ActionPrompt.story.tsx +3 -3
- package/src/prompt/ActionPrompt/ActionPrompt.test.story.tsx +3 -3
- package/src/prompt/InfoPrompt/InfoPrompt.accessibility.docs.mdx +1 -1
- package/src/prompt/InfoPrompt/InfoPrompt.story.tsx +3 -3
- package/src/prompt/InlinePrompt/InlinePrompt.accessibility.docs.mdx +1 -1
- package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +5 -5
- package/src/prompt/InlinePrompt/InlinePrompt.test.story.tsx +2 -2
- package/src/select/Select.css +2 -1
- package/src/select/Select.less +6 -5
- package/src/select/Select.story.tsx +3 -3
- package/src/select/Select.test.story.tsx +59 -0
- package/src/select/Select.tsx +1 -1
- package/src/select/option/Option.test.tsx +3 -3
- package/src/summary/Summary.story.tsx +5 -5
- package/src/summary/Summary.test.story.tsx +2 -2
- package/src/tooltip/Tooltip.tsx +26 -45
|
@@ -64,7 +64,7 @@ Custom media icons should include their own accessibility attributes. Use the `t
|
|
|
64
64
|
<InfoPrompt
|
|
65
65
|
sentiment="success"
|
|
66
66
|
description="Your travel account is ready!"
|
|
67
|
-
media={{ asset: <
|
|
67
|
+
media={{ asset: <Suitcase title="Travel feature" /> }}
|
|
68
68
|
/>
|
|
69
69
|
|
|
70
70
|
<InfoPrompt
|
|
@@ -2,7 +2,7 @@ import type { ReactElement } from 'react';
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
4
4
|
import { action } from 'storybook/actions';
|
|
5
|
-
import { Confetti, GiftBox, Star,
|
|
5
|
+
import { Confetti, GiftBox, Star, Suitcase, Briefcase, Plane } from '@transferwise/icons';
|
|
6
6
|
import { lorem10, lorem20 } from '../../test-utils';
|
|
7
7
|
import Button from '../../button';
|
|
8
8
|
import Title from '../../title';
|
|
@@ -90,7 +90,7 @@ const MEDIA_OPTIONS: Record<string, { asset: ReactElement } | undefined> = {
|
|
|
90
90
|
star: { asset: <Star title="Starred" /> },
|
|
91
91
|
confetti: { asset: <Confetti size={24} title="Celebration" /> },
|
|
92
92
|
giftbox: { asset: <GiftBox title="Gift" /> },
|
|
93
|
-
travel: { asset: <
|
|
93
|
+
travel: { asset: <Suitcase title="Travel" /> },
|
|
94
94
|
briefcase: { asset: <Briefcase title="Business" /> },
|
|
95
95
|
plane: { asset: <Plane title="Travel" /> },
|
|
96
96
|
};
|
|
@@ -297,7 +297,7 @@ export const MediaTypes: StoryObj<InfoPromptProps> = {
|
|
|
297
297
|
<InfoPrompt
|
|
298
298
|
sentiment="success"
|
|
299
299
|
description="Your travel account is ready!"
|
|
300
|
-
media={{ asset: <
|
|
300
|
+
media={{ asset: <Suitcase title="Travel" /> }}
|
|
301
301
|
/>
|
|
302
302
|
<InfoPrompt
|
|
303
303
|
sentiment="warning"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
3
3
|
import { action } from 'storybook/actions';
|
|
4
|
-
import { Clock, Taxi,
|
|
4
|
+
import { Clock, Taxi, Suitcase } from '@transferwise/icons';
|
|
5
5
|
import { lorem5 } from '../../test-utils';
|
|
6
6
|
import Link from '../../link';
|
|
7
7
|
import { InlinePrompt, InlinePromptProps } from './InlinePrompt';
|
|
@@ -233,7 +233,7 @@ export const IconOverrides: StoryObj<PreviewStoryArgs> = {
|
|
|
233
233
|
<InlinePrompt {...args} media={<Clock title="Processing: " />} sentiment="warning">
|
|
234
234
|
The account verification is taking longer than usual.
|
|
235
235
|
</InlinePrompt>
|
|
236
|
-
<InlinePrompt {...args} media={<
|
|
236
|
+
<InlinePrompt {...args} media={<Suitcase title="Activated: " />} sentiment="positive">
|
|
237
237
|
Your travel account is set up and ready to use.
|
|
238
238
|
</InlinePrompt>
|
|
239
239
|
<InlinePrompt {...args} media={<Taxi title="Taxi addon: " />} sentiment="proposition">
|
|
@@ -256,13 +256,13 @@ export const SizingStrategies: StoryObj<PreviewStoryArgs> = {
|
|
|
256
256
|
render: (args: PreviewStoryArgs) => {
|
|
257
257
|
return (
|
|
258
258
|
<>
|
|
259
|
-
<InlinePrompt {...args} media={<
|
|
259
|
+
<InlinePrompt {...args} media={<Suitcase />} sentiment="positive" width="full">
|
|
260
260
|
This prompt will take the full width of its container.
|
|
261
261
|
</InlinePrompt>
|
|
262
|
-
<InlinePrompt {...args} media={<
|
|
262
|
+
<InlinePrompt {...args} media={<Suitcase />} sentiment="positive">
|
|
263
263
|
This prompt will hug its content.
|
|
264
264
|
</InlinePrompt>
|
|
265
|
-
<InlinePrompt {...args} media={<
|
|
265
|
+
<InlinePrompt {...args} media={<Suitcase />} sentiment="positive">
|
|
266
266
|
This prompt is configured to hug its content, but since the content is long enough to span
|
|
267
267
|
across multiple lines, it will expand to the full width of its container. And no, you
|
|
268
268
|
should not put pages of text here in the first place, but we recognise that some
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StoryObj } from '@storybook/react-webpack5';
|
|
2
|
-
import {
|
|
2
|
+
import { Suitcase } from '@transferwise/icons';
|
|
3
3
|
import { InlinePrompt } from './InlinePrompt';
|
|
4
4
|
import { withVariantConfig } from '../../../.storybook/helpers';
|
|
5
5
|
|
|
@@ -13,7 +13,7 @@ type Story = StoryObj<typeof InlinePrompt>;
|
|
|
13
13
|
|
|
14
14
|
export const TinyScreen: Story = {
|
|
15
15
|
render: () => (
|
|
16
|
-
<InlinePrompt sentiment="positive" media={<
|
|
16
|
+
<InlinePrompt sentiment="positive" media={<Suitcase />}>
|
|
17
17
|
Your travel money account is now active and ready to use for international transactions.
|
|
18
18
|
</InlinePrompt>
|
|
19
19
|
),
|
package/src/select/Select.css
CHANGED
|
@@ -123,14 +123,15 @@
|
|
|
123
123
|
max-width: calc(100% - 32px);
|
|
124
124
|
}
|
|
125
125
|
.np-dropdown-menu-desktop {
|
|
126
|
-
max-height: 70vh;
|
|
127
126
|
max-height: 70svh;
|
|
127
|
+
max-height: var(--np-panel-available-height, 70svh);
|
|
128
128
|
min-width: 160px;
|
|
129
129
|
max-width: calc(100vw - 32px);
|
|
130
130
|
}
|
|
131
131
|
@media (min-height: 592px) {
|
|
132
132
|
.np-dropdown-menu-desktop {
|
|
133
133
|
max-height: 592px;
|
|
134
|
+
max-height: var(--np-panel-available-height, 592px);
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
.np-dropdown-menu {
|
package/src/select/Select.less
CHANGED
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
|
|
82
82
|
// Override some of Button component styles
|
|
83
83
|
.btn {
|
|
84
|
-
&:not(.disabled
|
|
84
|
+
&:not(.disabled, :disabled, .btn-loading) {
|
|
85
85
|
color: var(--color-content-primary);
|
|
86
86
|
|
|
87
87
|
&:hover {
|
|
@@ -108,15 +108,14 @@
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
.np-dropdown-menu-desktop {
|
|
111
|
-
max-height:
|
|
112
|
-
max-height: 70svh;
|
|
111
|
+
max-height: var(--np-panel-available-height, 70svh);
|
|
113
112
|
min-width: 160px;
|
|
114
113
|
max-width: ~"calc(100vw - 32px)";
|
|
115
114
|
}
|
|
116
115
|
|
|
117
116
|
@media (min-height: 592px) {
|
|
118
117
|
.np-dropdown-menu-desktop {
|
|
119
|
-
max-height: 592px;
|
|
118
|
+
max-height: var(--np-panel-available-height, 592px);
|
|
120
119
|
}
|
|
121
120
|
}
|
|
122
121
|
|
|
@@ -270,7 +269,9 @@
|
|
|
270
269
|
/* stylelint-disable-next-line no-duplicate-selectors */
|
|
271
270
|
.np-select .np-dropdown-toggle {
|
|
272
271
|
background-color: unset;
|
|
273
|
-
transition:
|
|
272
|
+
transition:
|
|
273
|
+
background-color 0.3s ease-in-out,
|
|
274
|
+
box-shadow 0.3s ease-in-out;
|
|
274
275
|
border: none;
|
|
275
276
|
box-shadow: inset 0 0 0 1px var(--color-interactive-secondary);
|
|
276
277
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
-
import { Person
|
|
2
|
+
import { Person, Globe as GlobeIcon } from '@transferwise/icons';
|
|
3
3
|
import { useState } from 'react';
|
|
4
4
|
import Select, { SelectItem, SelectOptionItem } from './Select';
|
|
5
5
|
|
|
@@ -75,7 +75,7 @@ export const Basic: Story = {
|
|
|
75
75
|
{ value: 2, label: 'A disabled thing', disabled: true },
|
|
76
76
|
{ separator: true },
|
|
77
77
|
{ header: 'Icons' },
|
|
78
|
-
{ value: 3, label: 'Profile', icon: <
|
|
78
|
+
{ value: 3, label: 'Profile', icon: <Person /> },
|
|
79
79
|
{
|
|
80
80
|
value: 4,
|
|
81
81
|
label: 'USD',
|
|
@@ -312,7 +312,7 @@ export const AdvancedSearch: Story = {
|
|
|
312
312
|
{ value: 2, label: 'A disabled thing', disabled: true },
|
|
313
313
|
{ separator: true },
|
|
314
314
|
{ header: 'Icons' },
|
|
315
|
-
{ value: 3, label: 'Profile', icon: <
|
|
315
|
+
{ value: 3, label: 'Profile', icon: <Person /> },
|
|
316
316
|
{ value: 4, label: 'Globe', icon: <GlobeIcon /> },
|
|
317
317
|
{ header: 'Currencies' },
|
|
318
318
|
{ value: 5, label: 'British pound', currency: 'gbp' },
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
+
import { userEvent, within } from 'storybook/test';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { withVariantConfig } from '../../.storybook/helpers';
|
|
6
|
+
import Select, { SelectOptionItem } from './Select';
|
|
7
|
+
|
|
8
|
+
const meta = {
|
|
9
|
+
title: 'Forms/Select/Tests',
|
|
10
|
+
component: Select,
|
|
11
|
+
tags: ['!autodocs', '!manifest'],
|
|
12
|
+
} satisfies Meta<typeof Select>;
|
|
13
|
+
export default meta;
|
|
14
|
+
|
|
15
|
+
type Story = StoryObj<typeof Select>;
|
|
16
|
+
|
|
17
|
+
const options: SelectOptionItem[] = Array.from({ length: 10 }, (_, i) => ({
|
|
18
|
+
value: i + 1,
|
|
19
|
+
label: `Option ${i + 1}`,
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Visual regression story: Select placed at the bottom of the viewport so the dropdown
|
|
24
|
+
* flips to the top when opened. The play function opens the dropdown automatically.
|
|
25
|
+
*/
|
|
26
|
+
export const DropdownFlipsToTop: Story = {
|
|
27
|
+
render: function Render() {
|
|
28
|
+
const [selected, setSelected] = useState<SelectOptionItem>(options[0]);
|
|
29
|
+
return (
|
|
30
|
+
<div
|
|
31
|
+
style={{
|
|
32
|
+
display: 'flex',
|
|
33
|
+
flexDirection: 'column',
|
|
34
|
+
justifyContent: 'flex-end',
|
|
35
|
+
minHeight: '50vh',
|
|
36
|
+
}}
|
|
37
|
+
>
|
|
38
|
+
<Select
|
|
39
|
+
id="flip-test-select"
|
|
40
|
+
size="md"
|
|
41
|
+
block
|
|
42
|
+
options={options}
|
|
43
|
+
selected={selected}
|
|
44
|
+
onChange={(option) => {
|
|
45
|
+
if (option && 'value' in option) {
|
|
46
|
+
setSelected(option as SelectOptionItem);
|
|
47
|
+
}
|
|
48
|
+
}}
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
play: async ({ canvasElement }) => {
|
|
54
|
+
const canvas = within(canvasElement);
|
|
55
|
+
const trigger = canvas.getByRole('button', { name: /Option 1/i });
|
|
56
|
+
await userEvent.click(trigger);
|
|
57
|
+
},
|
|
58
|
+
...withVariantConfig(['default']),
|
|
59
|
+
};
|
package/src/select/Select.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, screen } from '@testing-library/react';
|
|
3
|
-
import { Person
|
|
3
|
+
import { Person } from '@transferwise/icons';
|
|
4
4
|
|
|
5
5
|
import Option, { Props as OptionProps } from './Option';
|
|
6
6
|
|
|
@@ -31,7 +31,7 @@ describe('Option', () => {
|
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
it('should render the given icon', () => {
|
|
34
|
-
renderOption({ icon: <
|
|
34
|
+
renderOption({ icon: <Person /> });
|
|
35
35
|
const optionElement = screen.getByTestId('test-option');
|
|
36
36
|
expect(optionElement.querySelector('svg')).toBeInTheDocument();
|
|
37
37
|
});
|
|
@@ -43,7 +43,7 @@ describe('Option', () => {
|
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
it('should override the currency flag with the given icon', () => {
|
|
46
|
-
renderOption({ currency: 'USD', icon: <
|
|
46
|
+
renderOption({ currency: 'USD', icon: <Person /> });
|
|
47
47
|
const optionElement = screen.getByTestId('test-option');
|
|
48
48
|
expect(optionElement.querySelector('svg')).toBeInTheDocument();
|
|
49
49
|
expect(optionElement.querySelectorAll('svg')).toHaveLength(1);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { action } from 'storybook/actions';
|
|
3
|
-
import {
|
|
3
|
+
import { House } from '@transferwise/icons';
|
|
4
4
|
import { Status } from '../common';
|
|
5
5
|
import { InfoPresentation } from '../info';
|
|
6
6
|
import Summary, { type Props as SummaryProps } from './Summary';
|
|
@@ -32,7 +32,7 @@ export const Basic = (args: SummaryProps) => {
|
|
|
32
32
|
}}
|
|
33
33
|
as="li"
|
|
34
34
|
description={description}
|
|
35
|
-
icon={<
|
|
35
|
+
icon={<House size={24} />}
|
|
36
36
|
title="Verify your address"
|
|
37
37
|
status={Status.NOT_DONE}
|
|
38
38
|
/>
|
|
@@ -51,7 +51,7 @@ export const Basic = (args: SummaryProps) => {
|
|
|
51
51
|
'aria-label': 'Please click here to know more about your address update status',
|
|
52
52
|
onClick: action('Summary Info clicked'),
|
|
53
53
|
}}
|
|
54
|
-
icon={<
|
|
54
|
+
icon={<House size={24} />}
|
|
55
55
|
title="You verified your address"
|
|
56
56
|
status={Status.DONE}
|
|
57
57
|
/>
|
|
@@ -72,7 +72,7 @@ export const Basic = (args: SummaryProps) => {
|
|
|
72
72
|
'aria-label': 'Please click here to know more about your address update status',
|
|
73
73
|
onClick: action('Summary Info clicked'),
|
|
74
74
|
}}
|
|
75
|
-
icon={<
|
|
75
|
+
icon={<House size={24} />}
|
|
76
76
|
title="We’re verifying your address"
|
|
77
77
|
status={Status.PENDING}
|
|
78
78
|
/>
|
|
@@ -85,7 +85,7 @@ export const Basic = (args: SummaryProps) => {
|
|
|
85
85
|
}}
|
|
86
86
|
as="li"
|
|
87
87
|
description={description}
|
|
88
|
-
icon={<
|
|
88
|
+
icon={<House size={24} />}
|
|
89
89
|
title="We’re verifying your address"
|
|
90
90
|
status={Status.PENDING}
|
|
91
91
|
/>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { House } from '@transferwise/icons';
|
|
2
2
|
import { Status } from '../common';
|
|
3
3
|
import Summary, { type SummaryProps } from '.';
|
|
4
4
|
|
|
@@ -16,7 +16,7 @@ export const LongText = () => {
|
|
|
16
16
|
'aria-label': ' Click here to change address',
|
|
17
17
|
},
|
|
18
18
|
as: 'li',
|
|
19
|
-
icon: <
|
|
19
|
+
icon: <House size={24} />,
|
|
20
20
|
status: Status.NOT_DONE,
|
|
21
21
|
info: {
|
|
22
22
|
title: 'Title',
|
package/src/tooltip/Tooltip.tsx
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
import {
|
|
2
|
+
arrow as arrowMiddleware,
|
|
3
|
+
autoUpdate,
|
|
4
|
+
flip,
|
|
5
|
+
offset,
|
|
6
|
+
useFloating,
|
|
7
|
+
} from '@floating-ui/react';
|
|
2
8
|
import { clsx } from 'clsx';
|
|
3
9
|
import {
|
|
4
10
|
AriaAttributes,
|
|
11
|
+
CSSProperties,
|
|
5
12
|
PropsWithChildren,
|
|
6
13
|
ReactElement,
|
|
7
14
|
ReactNode,
|
|
8
15
|
cloneElement,
|
|
9
|
-
useEffect,
|
|
10
16
|
useId,
|
|
11
17
|
useRef,
|
|
12
18
|
useState,
|
|
13
19
|
} from 'react';
|
|
14
|
-
import { usePopper } from 'react-popper';
|
|
15
20
|
|
|
16
21
|
import { CommonProps, Position } from '../common';
|
|
17
22
|
import {
|
|
@@ -36,48 +41,30 @@ const Tooltip = ({
|
|
|
36
41
|
className,
|
|
37
42
|
}: TooltipProps) => {
|
|
38
43
|
const [open, setOpen] = useState(false);
|
|
39
|
-
const
|
|
40
|
-
const [arrowElement, setArrowElement] = useState(null);
|
|
41
|
-
const [popperElement, setPopperElement] = useState(null);
|
|
44
|
+
const arrowRef = useRef<HTMLDivElement | null>(null);
|
|
42
45
|
|
|
43
46
|
const fallbackId = useId();
|
|
44
47
|
const tooltipId = id ?? fallbackId;
|
|
45
|
-
const modifiers = [];
|
|
46
|
-
|
|
47
|
-
modifiers.push({
|
|
48
|
-
name: 'arrow',
|
|
49
|
-
options: {
|
|
50
|
-
element: arrowElement,
|
|
51
|
-
options: {
|
|
52
|
-
padding: 8, // 8px from the edges of the popper
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
// This lets you displace a popper element from its reference element.
|
|
57
|
-
modifiers.push({ name: 'offset', options: { offset: [0, 16] } });
|
|
58
|
-
modifiers.push({
|
|
59
|
-
name: 'flip',
|
|
60
|
-
options: {
|
|
61
|
-
fallbackPlacements: Position.TOP,
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
48
|
|
|
65
|
-
const {
|
|
49
|
+
const { refs, floatingStyles, placement, middlewareData } = useFloating({
|
|
66
50
|
placement: position,
|
|
67
|
-
|
|
51
|
+
middleware: [
|
|
52
|
+
offset(16),
|
|
53
|
+
flip({ fallbackPlacements: [Position.TOP] }),
|
|
54
|
+
arrowMiddleware({ element: arrowRef, padding: 8 }),
|
|
55
|
+
],
|
|
56
|
+
whileElementsMounted: open ? autoUpdate : undefined,
|
|
57
|
+
open,
|
|
68
58
|
});
|
|
69
59
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
forceUpdate();
|
|
75
|
-
}
|
|
76
|
-
}, [open]);
|
|
60
|
+
const arrowStyle: CSSProperties = {
|
|
61
|
+
...(middlewareData.arrow?.x != null ? { left: middlewareData.arrow.x } : {}),
|
|
62
|
+
...(middlewareData.arrow?.y != null ? { top: middlewareData.arrow.y } : {}),
|
|
63
|
+
};
|
|
77
64
|
|
|
78
65
|
return (
|
|
79
66
|
<span
|
|
80
|
-
ref={
|
|
67
|
+
ref={refs.setReference}
|
|
81
68
|
className="tw-tooltip-container"
|
|
82
69
|
onMouseOver={() => setOpen(true)}
|
|
83
70
|
onFocus={() => setOpen(true)}
|
|
@@ -90,28 +77,22 @@ const Tooltip = ({
|
|
|
90
77
|
})
|
|
91
78
|
: null}
|
|
92
79
|
<div
|
|
93
|
-
|
|
94
|
-
ref={setPopperElement}
|
|
80
|
+
ref={refs.setFloating}
|
|
95
81
|
className={clsx(
|
|
96
82
|
'np-tooltip',
|
|
97
83
|
'np-panel',
|
|
98
84
|
open ? `np-panel--open np-tooltip--open` : null,
|
|
99
85
|
className,
|
|
100
86
|
)}
|
|
101
|
-
style={
|
|
102
|
-
{
|
|
87
|
+
style={floatingStyles}
|
|
88
|
+
data-popper-placement={placement}
|
|
103
89
|
aria-hidden={!open}
|
|
104
90
|
role="tooltip"
|
|
105
91
|
id={`${tooltipId}-tooltip`}
|
|
106
92
|
>
|
|
107
93
|
<div className="np-panel__content tooltip-inner">
|
|
108
94
|
{label}
|
|
109
|
-
<div
|
|
110
|
-
// @ts-expect-error
|
|
111
|
-
ref={setArrowElement}
|
|
112
|
-
className={clsx('np-panel__arrow')}
|
|
113
|
-
style={styles.arrow}
|
|
114
|
-
/>
|
|
95
|
+
<div ref={arrowRef} className={clsx('np-panel__arrow')} style={arrowStyle} />
|
|
115
96
|
</div>
|
|
116
97
|
</div>
|
|
117
98
|
</span>
|