@transferwise/components 0.0.0-experimental-5d1d6d8 → 0.0.0-experimental-1a9f157

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 (81) hide show
  1. package/build/avatar/Avatar.js +2 -0
  2. package/build/avatar/Avatar.js.map +1 -1
  3. package/build/avatar/Avatar.mjs +2 -0
  4. package/build/avatar/Avatar.mjs.map +1 -1
  5. package/build/badge/Badge.js +1 -0
  6. package/build/badge/Badge.js.map +1 -1
  7. package/build/badge/Badge.mjs +1 -0
  8. package/build/badge/Badge.mjs.map +1 -1
  9. package/build/circularButton/CircularButton.js +1 -1
  10. package/build/circularButton/CircularButton.js.map +1 -1
  11. package/build/circularButton/CircularButton.mjs +1 -1
  12. package/build/circularButton/CircularButton.mjs.map +1 -1
  13. package/build/common/bottomSheet/BottomSheet.js +1 -3
  14. package/build/common/bottomSheet/BottomSheet.js.map +1 -1
  15. package/build/common/bottomSheet/BottomSheet.mjs +1 -3
  16. package/build/common/bottomSheet/BottomSheet.mjs.map +1 -1
  17. package/build/common/circle/Circle.js +19 -3
  18. package/build/common/circle/Circle.js.map +1 -1
  19. package/build/common/circle/Circle.mjs +19 -3
  20. package/build/common/circle/Circle.mjs.map +1 -1
  21. package/build/common/responsivePanel/ResponsivePanel.js +1 -7
  22. package/build/common/responsivePanel/ResponsivePanel.js.map +1 -1
  23. package/build/common/responsivePanel/ResponsivePanel.mjs +1 -7
  24. package/build/common/responsivePanel/ResponsivePanel.mjs.map +1 -1
  25. package/build/main.css +6 -22
  26. package/build/popover/Popover.js +1 -6
  27. package/build/popover/Popover.js.map +1 -1
  28. package/build/popover/Popover.mjs +2 -7
  29. package/build/popover/Popover.mjs.map +1 -1
  30. package/build/statusIcon/StatusIcon.js +4 -4
  31. package/build/statusIcon/StatusIcon.js.map +1 -1
  32. package/build/statusIcon/StatusIcon.mjs +4 -4
  33. package/build/statusIcon/StatusIcon.mjs.map +1 -1
  34. package/build/styles/circularButton/CircularButton.css +2 -2
  35. package/build/styles/common/circle/Circle.css +4 -0
  36. package/build/styles/main.css +6 -22
  37. package/build/styles/statusIcon/StatusIcon.css +0 -20
  38. package/build/types/avatar/Avatar.d.ts.map +1 -1
  39. package/build/types/common/bottomSheet/BottomSheet.d.ts +1 -1
  40. package/build/types/common/bottomSheet/BottomSheet.d.ts.map +1 -1
  41. package/build/types/common/circle/Circle.d.ts +9 -1
  42. package/build/types/common/circle/Circle.d.ts.map +1 -1
  43. package/build/types/common/responsivePanel/ResponsivePanel.d.ts.map +1 -1
  44. package/build/types/popover/Popover.d.ts +4 -6
  45. package/build/types/popover/Popover.d.ts.map +1 -1
  46. package/build/types/statusIcon/StatusIcon.d.ts +6 -2
  47. package/build/types/statusIcon/StatusIcon.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/src/avatar/Avatar.spec.tsx +3 -1
  50. package/src/avatar/Avatar.tsx +2 -0
  51. package/src/avatarWrapper/__snapshots__/AvatarWrapper.spec.tsx.snap +11 -11
  52. package/src/badge/Badge.spec.tsx +3 -1
  53. package/src/badge/Badge.tsx +1 -1
  54. package/src/circularButton/CircularButton.css +2 -2
  55. package/src/circularButton/CircularButton.less +1 -1
  56. package/src/circularButton/CircularButton.tsx +1 -1
  57. package/src/circularButton/__snapshots__/CircularButton.spec.tsx.snap +20 -20
  58. package/src/common/bottomSheet/BottomSheet.tsx +2 -4
  59. package/src/common/circle/Circle.css +4 -0
  60. package/src/common/circle/Circle.less +8 -0
  61. package/src/common/circle/Circle.tsx +36 -3
  62. package/src/common/responsivePanel/ResponsivePanel.tsx +3 -13
  63. package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +4 -4
  64. package/src/main.css +6 -22
  65. package/src/overlayHeader/OverlayHeader.spec.tsx +3 -1
  66. package/src/overlayHeader/__snapshots__/OverlayHeader.spec.tsx.snap +2 -2
  67. package/src/popover/Popover.spec.tsx +21 -64
  68. package/src/popover/Popover.story.tsx +42 -54
  69. package/src/popover/Popover.tsx +5 -12
  70. package/src/popover/__snapshots__/Popover.spec.tsx.snap +0 -2
  71. package/src/promoCard/PromoCard.spec.tsx +3 -1
  72. package/src/radio/Radio.rtl.spec.tsx +2 -1
  73. package/src/radio/__snapshots__/Radio.rtl.spec.tsx.snap +2 -2
  74. package/src/statusIcon/StatusIcon.css +0 -20
  75. package/src/statusIcon/StatusIcon.less +0 -17
  76. package/src/statusIcon/StatusIcon.spec.tsx +3 -21
  77. package/src/statusIcon/StatusIcon.story.tsx +31 -8
  78. package/src/statusIcon/StatusIcon.tsx +11 -6
  79. package/build/types/constants.d.ts +0 -11
  80. package/build/types/constants.d.ts.map +0 -1
  81. package/src/constants.ts +0 -11
@@ -1,66 +1,54 @@
1
1
  import { action } from '@storybook/addon-actions';
2
+ import { select } from '@storybook/addon-knobs';
2
3
 
3
4
  import Button from '../button';
4
5
  import { Position } from '../common';
5
6
 
6
7
  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
- );
25
8
 
26
9
  export default {
27
10
  component: Popover,
28
11
  title: 'Dialogs/Popover',
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>;
12
+ };
43
13
 
44
- export const Basic: Story = {};
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
+ );
45
29
 
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>;
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
+ };
@@ -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, useId } from 'react';
3
+ import { useRef, useState, cloneElement, useEffect, isValidElement } from 'react';
4
4
 
5
5
  import { Position, Typography } from '../common';
6
6
  import ResponsivePanel from '../common/responsivePanel';
@@ -23,13 +23,11 @@ export type PopoverPreferredPlacement =
23
23
 
24
24
  export interface PopoverProps {
25
25
  children?: React.ReactNode;
26
- title?: React.ReactNode;
27
- /** Screen-reader-friendly title. Must be provided if `title` prop is not set. */
28
- 'aria-label'?: string;
29
- preferredPlacement?: PopoverPreferredPlacement;
26
+ className?: string;
30
27
  content: React.ReactNode;
28
+ preferredPlacement?: PopoverPreferredPlacement;
31
29
  onClose?: () => void;
32
- className?: string;
30
+ title?: React.ReactNode;
33
31
  }
34
32
 
35
33
  function resolvePlacement(preferredPlacement: PopoverPreferredPlacement) {
@@ -52,10 +50,7 @@ export default function Popover({
52
50
  preferredPlacement = Position.RIGHT,
53
51
  title,
54
52
  onClose,
55
- 'aria-label': ariaLabel,
56
53
  }: PopoverProps) {
57
- const titleId = useId();
58
-
59
54
  const resolvedPlacement = resolvePlacement(preferredPlacement);
60
55
  useEffect(() => {
61
56
  if (resolvedPlacement !== preferredPlacement) {
@@ -86,8 +81,6 @@ export default function Popover({
86
81
  : children}
87
82
  </span>
88
83
  <ResponsivePanel
89
- aria-label={ariaLabel}
90
- aria-labelledby={title && !ariaLabel ? titleId : undefined}
91
84
  open={open}
92
85
  anchorRef={anchorReference}
93
86
  position={resolvedPlacement}
@@ -97,7 +90,7 @@ export default function Popover({
97
90
  >
98
91
  <div className="np-popover__content np-text-default-body">
99
92
  {title && (
100
- <Title type={Typography.TITLE_BODY} id={titleId} className="m-b-1">
93
+ <Title type={Typography.TITLE_BODY} className="m-b-1">
101
94
  {title}
102
95
  </Title>
103
96
  )}
@@ -2,7 +2,6 @@
2
2
 
3
3
  exports[`Popover on desktop renders when is open 1`] = `
4
4
  <div
5
- aria-labelledby=":r0:"
6
5
  class="np-panel np-panel--open np-popover__container"
7
6
  data-popper-escaped="true"
8
7
  data-popper-placement="right"
@@ -18,7 +17,6 @@ exports[`Popover on desktop renders when is open 1`] = `
18
17
  >
19
18
  <h4
20
19
  class="np-text-title-body m-b-1"
21
- id=":r0:"
22
20
  >
23
21
  title
24
22
  </h4>
@@ -1,8 +1,10 @@
1
- import { render, fireEvent, screen } from '@testing-library/react';
1
+ import { render, fireEvent, screen, mockMatchMedia } from '../test-utils';
2
2
  import React from 'react';
3
3
 
4
4
  import PromoCard, { PromoCardProps, PromoCardCheckedProps, PromoCardLinkProps } from './PromoCard';
5
5
 
6
+ mockMatchMedia();
7
+
6
8
  describe('PromoCard', () => {
7
9
  const defaultProps = {
8
10
  title: 'Test Title',
@@ -1,8 +1,9 @@
1
1
  import Avatar, { AvatarType } from '../avatar';
2
- import { render } from '../test-utils';
2
+ import { render, mockMatchMedia } from '../test-utils';
3
3
 
4
4
  import Radio from '.';
5
5
 
6
+ mockMatchMedia();
6
7
  jest.mock('../common/hooks');
7
8
 
8
9
  describe('Radio', () => {
@@ -35,11 +35,11 @@ exports[`Radio shows the avatar when supplied 1`] = `
35
35
  >
36
36
  <div
37
37
  class="np-circle d-flex align-items-center justify-content-center tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
38
- style="--circle-size: 48px;"
38
+ style="--circle-size: 48px; --circle-icon-size: 24px;"
39
39
  >
40
40
  <div
41
41
  class="np-circle d-flex align-items-center justify-content-center tw-avatar__content"
42
- style="--circle-size: 48px;"
42
+ style="--circle-size: 48px; --circle-icon-size: 24px;"
43
43
  >
44
44
  HD
45
45
  </div>
@@ -1,9 +1,3 @@
1
- .status-icon > svg {
2
- height: 32px;
3
- height: var(--size-32);
4
- width: 32px;
5
- width: var(--size-32);
6
- }
7
1
  .status-circle .light {
8
2
  color: var(--color-contrast);
9
3
  }
@@ -19,20 +13,6 @@
19
13
  .np-theme-personal .status-circle.pending .status-icon {
20
14
  color: var(--color-dark);
21
15
  }
22
- .status-circle-sm .status-icon > svg {
23
- height: 14px;
24
- height: var(--size-14);
25
- width: 14px;
26
- width: var(--size-14);
27
- }
28
- @media (max-width: 320px) {
29
- .status-circle-sm .status-icon > svg {
30
- width: 24px;
31
- width: var(--size-24);
32
- height: 24px;
33
- height: var(--size-24);
34
- }
35
- }
36
16
  .status-circle.negative,
37
17
  .status-circle.error {
38
18
  background-color: var(--color-sentiment-negative);
@@ -1,8 +1,3 @@
1
- .status-icon > svg {
2
- height: var(--size-32);
3
- width: var(--size-32);
4
- }
5
-
6
1
  .status-circle {
7
2
  .light {
8
3
  color: var(--color-contrast);
@@ -22,18 +17,6 @@
22
17
  }
23
18
  }
24
19
  }
25
-
26
- &-sm {
27
- .status-icon > svg {
28
- height: var(--size-14);
29
- width: var(--size-14);
30
-
31
- @media (--screen-400-zoom) {
32
- width: var(--size-24);
33
- height: var(--size-24);
34
- }
35
- }
36
- }
37
20
  }
38
21
 
39
22
  .status-circle.negative,
@@ -1,15 +1,12 @@
1
- import { Sentiment, Size, SizeLarge, SizeMedium, SizeSmall } from '../common';
1
+ import { Sentiment, Size } from '../common';
2
2
  import { render, cleanup, screen, mockMatchMedia } from '../test-utils';
3
3
 
4
- import StatusIcon from '.';
4
+ import StatusIcon, { type StatusIconProps } from '.';
5
5
 
6
6
  mockMatchMedia();
7
7
 
8
8
  describe('StatusIcon', () => {
9
- const renderStatusIcon = (props?: {
10
- sentiment?: Sentiment;
11
- size?: SizeLarge | SizeMedium | SizeSmall;
12
- }) => {
9
+ const renderStatusIcon = (props?: StatusIconProps) => {
13
10
  return render(
14
11
  <StatusIcon
15
12
  sentiment={props?.sentiment || Sentiment.NEUTRAL}
@@ -25,23 +22,8 @@ describe('StatusIcon', () => {
25
22
 
26
23
  expect(screen.getByTestId('status-icon')).toHaveClass('neutral');
27
24
  expect(screen.getByTestId('status-icon')).toHaveClass('status-circle');
28
- expect(screen.getByTestId('status-icon')).toHaveClass('status-circle-md');
29
25
  });
30
26
 
31
- it.each([
32
- [Size.SMALL as const, 'status-circle-sm'],
33
- [Size.MEDIUM as const, 'status-circle-md'],
34
- [Size.LARGE as const, 'status-circle-lg'],
35
- ])(
36
- "if prop 'size' equals '%s' is passed, renders the status icon with class '%s'",
37
- (size, expectedClass) => {
38
- renderStatusIcon({ size });
39
-
40
- expect(screen.getByTestId('status-icon')).toHaveClass(expectedClass);
41
- cleanup();
42
- },
43
- );
44
-
45
27
  it.each([
46
28
  [Sentiment.NEGATIVE, Sentiment.NEGATIVE],
47
29
  [Sentiment.NEUTRAL, Sentiment.NEUTRAL],
@@ -1,6 +1,6 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
2
 
3
- import { Size, Sentiment } from '../common';
3
+ import { Sentiment, Size } from '../common';
4
4
 
5
5
  import StatusIcon from './StatusIcon';
6
6
 
@@ -11,22 +11,45 @@ export default {
11
11
 
12
12
  type Story = StoryObj<typeof StatusIcon>;
13
13
 
14
- export const Basic: Story = {
15
- render: (args) => (
16
- <span style={{ display: 'flex' }}>
17
- <StatusIcon {...args} />
14
+ export const Variants: Story = {
15
+ render: () => (
16
+ <span style={{ display: 'flex', justifyContent: 'space-between', maxWidth: '400px' }}>
17
+ {[
18
+ Sentiment.POSITIVE,
19
+ Sentiment.NEGATIVE,
20
+ Sentiment.WARNING,
21
+ Sentiment.NEUTRAL,
22
+ Sentiment.PENDING,
23
+ ].map((sentiment) => {
24
+ return (
25
+ <span
26
+ key={sentiment}
27
+ style={{
28
+ display: 'flex',
29
+ justifyContent: 'space-between',
30
+ flexDirection: 'column',
31
+ minHeight: '150px',
32
+ alignItems: 'center',
33
+ }}
34
+ >
35
+ {([16, 24, 32, 40, 48, 56, 72] as const).map((size) => {
36
+ return <StatusIcon key={size} size={size} sentiment={sentiment} />;
37
+ })}
38
+ </span>
39
+ );
40
+ })}
18
41
  </span>
19
42
  ),
20
43
  };
21
44
 
22
- export const Variants: Story = {
23
- render: () => (
45
+ export const LegacySizes: Story = {
46
+ render: (args) => (
24
47
  <span style={{ display: 'flex', justifyContent: 'space-between', maxWidth: '400px' }}>
25
48
  {[
26
49
  Sentiment.POSITIVE,
27
50
  Sentiment.NEGATIVE,
28
- Sentiment.NEUTRAL,
29
51
  Sentiment.WARNING,
52
+ Sentiment.NEUTRAL,
30
53
  Sentiment.PENDING,
31
54
  ].map((sentiment) => {
32
55
  return (
@@ -5,9 +5,14 @@ import { SizeSmall, SizeMedium, SizeLarge, Sentiment, Size, Breakpoint } from '.
5
5
  import Circle, { CircleProps } from '../common/circle';
6
6
  import { useMedia } from '../common/hooks/useMedia';
7
7
 
8
+ /**
9
+ * @deprecated use `16 | 24 | 32 | 40 | 48 | 56 | 72` component instead
10
+ */
11
+ type LegacySizes = SizeSmall | SizeMedium | SizeLarge;
12
+
8
13
  export type StatusIconProps = {
9
- sentiment: `${Sentiment}`;
10
- size: SizeSmall | SizeMedium | SizeLarge;
14
+ sentiment?: `${Sentiment}`;
15
+ size?: LegacySizes | 16 | 24 | 32 | 40 | 48 | 56 | 72;
11
16
  };
12
17
 
13
18
  const iconTypeMap = {
@@ -27,17 +32,17 @@ const mapLegacySize = {
27
32
  [String(Size.LARGE)]: 48,
28
33
  } satisfies Record<string, CircleProps['size']>;
29
34
 
30
- const StatusIcon = ({ sentiment = 'neutral', size: sizeProp = 'md' }: StatusIconProps) => {
35
+ const StatusIcon = ({ sentiment = 'neutral', size: sizeProp = 40 }: StatusIconProps) => {
31
36
  const Icon = iconTypeMap[sentiment];
32
37
  const iconColor = sentiment === 'warning' || sentiment === 'pending' ? 'dark' : 'light';
33
38
  const isTinyViewport = useMedia(`(max-width: ${Breakpoint.ZOOM_400}px)`);
34
- const size = sizeProp === Size.SMALL && isTinyViewport ? 32 : mapLegacySize[sizeProp];
39
+ const size = mapLegacySize[sizeProp] ?? sizeProp;
35
40
  return (
36
41
  <Circle
37
42
  as="span"
38
- size={size}
43
+ size={isTinyViewport && size < 40 ? 32 : size}
39
44
  data-testid="status-icon"
40
- className={clsx('status-circle', `status-circle-${sizeProp}`, sentiment)}
45
+ className={clsx('status-circle', sentiment)}
41
46
  >
42
47
  <Icon className={clsx('status-icon', iconColor)} />
43
48
  </Circle>
@@ -1,11 +0,0 @@
1
- /**
2
- * This file holds repository-wide constants that are reusable by more than 1 component.
3
- */
4
- /**
5
- * A delay [ms] after which it's OK to update a live region content,
6
- * taking under consideration delayed programmatic refocusing
7
- * of triggering components (e.g., SelectInput) and Accessibility
8
- * Tree updates that prevent the screen reader announcements.
9
- */
10
- export declare const WDS_LIVE_REGION_DELAY_MS = 175;
11
- //# sourceMappingURL=constants.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,MAAM,CAAC"}
package/src/constants.ts DELETED
@@ -1,11 +0,0 @@
1
- /**
2
- * This file holds repository-wide constants that are reusable by more than 1 component.
3
- */
4
-
5
- /**
6
- * A delay [ms] after which it's OK to update a live region content,
7
- * taking under consideration delayed programmatic refocusing
8
- * of triggering components (e.g., SelectInput) and Accessibility
9
- * Tree updates that prevent the screen reader announcements.
10
- */
11
- export const WDS_LIVE_REGION_DELAY_MS = 175;