@transferwise/components 46.72.2 → 46.74.0

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.
Files changed (41) hide show
  1. package/build/alert/Alert.js +12 -3
  2. package/build/alert/Alert.js.map +1 -1
  3. package/build/alert/Alert.mjs +12 -3
  4. package/build/alert/Alert.mjs.map +1 -1
  5. package/build/common/bottomSheet/BottomSheet.js +3 -1
  6. package/build/common/bottomSheet/BottomSheet.js.map +1 -1
  7. package/build/common/bottomSheet/BottomSheet.mjs +3 -1
  8. package/build/common/bottomSheet/BottomSheet.mjs.map +1 -1
  9. package/build/common/constants.js +15 -0
  10. package/build/common/constants.js.map +1 -0
  11. package/build/common/constants.mjs +13 -0
  12. package/build/common/constants.mjs.map +1 -0
  13. package/build/common/responsivePanel/ResponsivePanel.js +7 -1
  14. package/build/common/responsivePanel/ResponsivePanel.js.map +1 -1
  15. package/build/common/responsivePanel/ResponsivePanel.mjs +7 -1
  16. package/build/common/responsivePanel/ResponsivePanel.mjs.map +1 -1
  17. package/build/popover/Popover.js +6 -1
  18. package/build/popover/Popover.js.map +1 -1
  19. package/build/popover/Popover.mjs +7 -2
  20. package/build/popover/Popover.mjs.map +1 -1
  21. package/build/types/alert/Alert.d.ts.map +1 -1
  22. package/build/types/common/bottomSheet/BottomSheet.d.ts +1 -1
  23. package/build/types/common/bottomSheet/BottomSheet.d.ts.map +1 -1
  24. package/build/types/common/constants.d.ts +11 -0
  25. package/build/types/common/constants.d.ts.map +1 -0
  26. package/build/types/common/index.d.ts +2 -0
  27. package/build/types/common/responsivePanel/ResponsivePanel.d.ts.map +1 -1
  28. package/build/types/popover/Popover.d.ts +6 -4
  29. package/build/types/popover/Popover.d.ts.map +1 -1
  30. package/package.json +1 -1
  31. package/src/alert/Alert.spec.story.tsx +87 -0
  32. package/src/alert/Alert.story.tsx +36 -6
  33. package/src/alert/Alert.tsx +20 -4
  34. package/src/common/bottomSheet/BottomSheet.tsx +4 -2
  35. package/src/common/constants.ts +11 -0
  36. package/src/common/index.js +2 -0
  37. package/src/common/responsivePanel/ResponsivePanel.tsx +13 -3
  38. package/src/popover/Popover.spec.tsx +64 -21
  39. package/src/popover/Popover.story.tsx +54 -42
  40. package/src/popover/Popover.tsx +12 -5
  41. package/src/popover/__snapshots__/Popover.spec.tsx.snap +2 -0
@@ -1,54 +1,66 @@
1
1
  import { action } from '@storybook/addon-actions';
2
- import { select } from '@storybook/addon-knobs';
3
2
 
4
3
  import Button from '../button';
5
4
  import { Position } from '../common';
6
5
 
7
6
  import Popover from './Popover';
7
+ import { Meta, StoryObj } from '@storybook/react';
8
+
9
+ type Story = StoryObj<typeof Popover>;
10
+
11
+ const Content = () => (
12
+ <>
13
+ You’ll get this rate as long as we receive your 10 EUR within the next 51 hours.
14
+ <div>
15
+ <a href="test1">Test 1</a>
16
+ </div>
17
+ <div>
18
+ <a href="test1">Test 2</a>
19
+ </div>
20
+ <div>
21
+ <a href="test1">Test 3</a>
22
+ </div>
23
+ </>
24
+ );
8
25
 
9
26
  export default {
10
27
  component: Popover,
11
28
  title: 'Dialogs/Popover',
12
- };
29
+ tags: ['autodocs'],
30
+ args: {
31
+ preferredPlacement: Position.BOTTOM,
32
+ title: 'Guaranteed rate',
33
+ content: <Content />,
34
+ children: <Button onClick={action(`I'm also triggered`)}>Click here to Open Popover!</Button>,
35
+ },
36
+ argTypes: {
37
+ preferredPlacement: {
38
+ control: 'select',
39
+ options: [Position.TOP, Position.RIGHT, Position.BOTTOM, Position.LEFT],
40
+ },
41
+ },
42
+ } satisfies Meta<typeof Popover>;
13
43
 
14
- export const Basic = () => {
15
- const preferredPlacement = select(
16
- 'preferredPlacement',
17
- [
18
- Position.TOP,
19
- Position.RIGHT,
20
- Position.BOTTOM,
21
- Position.LEFT,
22
- Position.LEFT_TOP,
23
- Position.RIGHT_TOP,
24
- Position.BOTTOM_RIGHT,
25
- Position.BOTTOM_LEFT,
26
- ],
27
- Position.TOP,
28
- );
44
+ export const Basic: Story = {};
29
45
 
30
- return (
31
- <div className="text-xs-center">
32
- <Popover
33
- content={
34
- <>
35
- You’ll get this rate as long as we receive your 10 EUR within the next 51 hours.
36
- <div>
37
- <a href="test1">Test 1</a>
38
- </div>
39
- <div>
40
- <a href="test1">Test 2</a>
41
- </div>
42
- <div>
43
- <a href="test1">Test 3</a>
44
- </div>
45
- </>
46
- }
47
- preferredPlacement={preferredPlacement}
48
- title="Guaranteed rate"
49
- >
50
- <Button onClick={action(`I'm also triggered`)}>Click here to Open Popover!</Button>
51
- </Popover>
52
- </div>
53
- );
54
- };
46
+ /**
47
+ * While it might be easier for sighted users to associate the content
48
+ * of a `Popover` with the surrounding and trigger content, it's likely
49
+ * much harder for people relying on the assistive-tech.
50
+ *
51
+ * For that reason, the `Popover` must always have an accessible name
52
+ * if `title` prop is set, the component will use it automatically,
53
+ * otherwise `aria-label` must be provided instead.
54
+ *
55
+ * **NB:** If both props are provided, then screen readers will prioritise
56
+ * `aria-label` over `title`.
57
+ */
58
+ export const WithoutVisibleTitle: Story = {
59
+ args: {
60
+ preferredPlacement: Position.BOTTOM,
61
+ title: undefined,
62
+ 'aria-label': 'Guaranteed rate',
63
+ content: <Content />,
64
+ children: <Button onClick={action(`I'm also triggered`)}>Click here to Open Popover!</Button>,
65
+ },
66
+ } satisfies Meta<typeof Popover>;
@@ -1,6 +1,6 @@
1
1
  import { useTheme } from '@wise/components-theming';
2
2
  import { clsx } from 'clsx';
3
- import { useRef, useState, cloneElement, useEffect, isValidElement } from 'react';
3
+ import { useRef, useState, cloneElement, useEffect, isValidElement, useId } from 'react';
4
4
 
5
5
  import { Position, Typography } from '../common';
6
6
  import ResponsivePanel from '../common/responsivePanel';
@@ -23,11 +23,13 @@ export type PopoverPreferredPlacement =
23
23
 
24
24
  export interface PopoverProps {
25
25
  children?: React.ReactNode;
26
- className?: string;
27
- content: React.ReactNode;
26
+ title?: React.ReactNode;
27
+ /** Screen-reader-friendly title. Must be provided if `title` prop is not set. */
28
+ 'aria-label'?: string;
28
29
  preferredPlacement?: PopoverPreferredPlacement;
30
+ content: React.ReactNode;
29
31
  onClose?: () => void;
30
- title?: React.ReactNode;
32
+ className?: string;
31
33
  }
32
34
 
33
35
  function resolvePlacement(preferredPlacement: PopoverPreferredPlacement) {
@@ -50,7 +52,10 @@ export default function Popover({
50
52
  preferredPlacement = Position.RIGHT,
51
53
  title,
52
54
  onClose,
55
+ 'aria-label': ariaLabel,
53
56
  }: PopoverProps) {
57
+ const titleId = useId();
58
+
54
59
  const resolvedPlacement = resolvePlacement(preferredPlacement);
55
60
  useEffect(() => {
56
61
  if (resolvedPlacement !== preferredPlacement) {
@@ -81,6 +86,8 @@ export default function Popover({
81
86
  : children}
82
87
  </span>
83
88
  <ResponsivePanel
89
+ aria-label={ariaLabel}
90
+ aria-labelledby={title && !ariaLabel ? titleId : undefined}
84
91
  open={open}
85
92
  anchorRef={anchorReference}
86
93
  position={resolvedPlacement}
@@ -90,7 +97,7 @@ export default function Popover({
90
97
  >
91
98
  <div className="np-popover__content np-text-default-body">
92
99
  {title && (
93
- <Title type={Typography.TITLE_BODY} className="m-b-1">
100
+ <Title type={Typography.TITLE_BODY} id={titleId} className="m-b-1">
94
101
  {title}
95
102
  </Title>
96
103
  )}
@@ -2,6 +2,7 @@
2
2
 
3
3
  exports[`Popover on desktop renders when is open 1`] = `
4
4
  <div
5
+ aria-labelledby=":r0:"
5
6
  class="np-panel np-panel--open np-popover__container"
6
7
  data-popper-escaped="true"
7
8
  data-popper-placement="right"
@@ -17,6 +18,7 @@ exports[`Popover on desktop renders when is open 1`] = `
17
18
  >
18
19
  <h4
19
20
  class="np-text-title-body m-b-1"
21
+ id=":r0:"
20
22
  >
21
23
  title
22
24
  </h4>