@transferwise/components 46.161.3 → 46.162.1

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 (45) hide show
  1. package/build/FlowNavigation/FlowNavigation.js +24 -7
  2. package/build/FlowNavigation/FlowNavigation.js.map +1 -1
  3. package/build/FlowNavigation/FlowNavigation.mjs +24 -7
  4. package/build/FlowNavigation/FlowNavigation.mjs.map +1 -1
  5. package/build/Provider/Provider.js +6 -10
  6. package/build/Provider/Provider.js.map +1 -1
  7. package/build/Provider/Provider.mjs +6 -10
  8. package/build/Provider/Provider.mjs.map +1 -1
  9. package/build/index.js +0 -2
  10. package/build/index.js.map +1 -1
  11. package/build/index.mjs +0 -1
  12. package/build/index.mjs.map +1 -1
  13. package/build/types/Body/Body.d.ts +2 -2
  14. package/build/types/FlowNavigation/FlowNavigation.d.ts +4 -1
  15. package/build/types/FlowNavigation/FlowNavigation.d.ts.map +1 -1
  16. package/build/types/IconButton/IconButton.d.ts +1 -1
  17. package/build/types/MoneyInput/MoneyInput.d.ts +1 -1
  18. package/build/types/MoneyInput/MoneyInput.d.ts.map +1 -1
  19. package/build/types/Provider/Provider.d.ts.map +1 -1
  20. package/build/types/Provider/index.d.ts +0 -2
  21. package/build/types/Provider/index.d.ts.map +1 -1
  22. package/build/types/Title/Title.d.ts +2 -2
  23. package/build/types/Upload/Steps/UploadImageStep/UploadImageStep.d.ts +1 -1
  24. package/build/types/UploadInput/UploadItem/UploadItemLink.d.ts +1 -1
  25. package/build/types/index.d.ts +2 -2
  26. package/build/types/index.d.ts.map +1 -1
  27. package/package.json +1 -1
  28. package/src/FlowNavigation/FlowNavigation.tsx +16 -9
  29. package/src/FlowNavigation/_stories/FlowNavigation.story.tsx +108 -0
  30. package/src/FlowNavigation/_stories/FlowNavigation.test.story.tsx +68 -17
  31. package/src/Provider/Provider.tsx +8 -11
  32. package/src/Provider/index.ts +0 -2
  33. package/src/index.ts +2 -2
  34. package/build/Provider/Language/LanguageProvider.js +0 -20
  35. package/build/Provider/Language/LanguageProvider.js.map +0 -1
  36. package/build/Provider/Language/LanguageProvider.mjs +0 -17
  37. package/build/Provider/Language/LanguageProvider.mjs.map +0 -1
  38. package/build/types/Provider/Language/LanguageProvider.d.ts +0 -7
  39. package/build/types/Provider/Language/LanguageProvider.d.ts.map +0 -1
  40. package/build/types/Provider/Language/index.d.ts +0 -3
  41. package/build/types/Provider/Language/index.d.ts.map +0 -1
  42. package/src/Icons/_stories/Icons.story.tsx +0 -389
  43. package/src/Provider/Language/LanguageProvider.test.tsx +0 -22
  44. package/src/Provider/Language/LanguageProvider.tsx +0 -11
  45. package/src/Provider/Language/index.ts +0 -2
@@ -14,6 +14,7 @@ import messages from './FlowNavigation.messages';
14
14
  import AnimatedLabel from './AnimatedLabel';
15
15
  import IconButton from '../IconButton';
16
16
  import { ArrowLeft } from '@transferwise/icons';
17
+ import { CriticalBanner, CriticalBannerProps } from '../Prompt';
17
18
 
18
19
  const defaultLogo = <Logo />;
19
20
 
@@ -31,6 +32,8 @@ export interface FlowNavigationProps {
31
32
  onGoBack?: () => void;
32
33
  /** Steps to be displayed in stepper. If not provided, the stepper won't show. */
33
34
  steps?: readonly Step[];
35
+ /** Optional critical banner data, to be displayed above the flow navigation. */
36
+ banner?: CriticalBannerProps | null;
34
37
  /**
35
38
  * Controls whether the bottom border is displayed.
36
39
  * @default true
@@ -46,6 +49,7 @@ const FlowNavigation = ({
46
49
  onClose,
47
50
  onGoBack,
48
51
  steps,
52
+ banner = null,
49
53
  showBottomBorder = true,
50
54
  }: FlowNavigationProps) => {
51
55
  const intl = useIntl();
@@ -112,15 +116,18 @@ const FlowNavigation = ({
112
116
  );
113
117
 
114
118
  return (
115
- <Container
116
- size="fluid"
117
- className={clsx('np-flow-navigation', {
118
- 'np-flow-navigation--border-bottom': showBottomBorder,
119
- 'np-flow-navigation--no-steps': !hasSteps || done,
120
- })}
121
- >
122
- {flowHeaderContent}
123
- </Container>
119
+ <>
120
+ {banner && <CriticalBanner {...banner} />}
121
+ <Container
122
+ size="fluid"
123
+ className={clsx('np-flow-navigation', {
124
+ 'np-flow-navigation--border-bottom': showBottomBorder,
125
+ 'np-flow-navigation--no-steps': !hasSteps || done,
126
+ })}
127
+ >
128
+ {flowHeaderContent}
129
+ </Container>
130
+ </>
124
131
  );
125
132
  };
126
133
 
@@ -538,3 +538,111 @@ export const BorderControl: Story = {
538
538
  );
539
539
  },
540
540
  };
541
+
542
+ export const WithCriticalBanner: Story = {
543
+ args: {
544
+ profileType: ProfileType.PERSONAL,
545
+ showCloseButton: true,
546
+ showMobileBackButton: true,
547
+ avatarURL: '../tapestry-01.png',
548
+ },
549
+ parameters: {
550
+ chromatic: {
551
+ viewports,
552
+ },
553
+ padding: '0',
554
+ },
555
+ render: (args) => {
556
+ const [activeStep, setActiveStep] = useState(2);
557
+
558
+ const steps = [
559
+ {
560
+ label: 'Recipient',
561
+ onClick: () => setActiveStep(0),
562
+ },
563
+ {
564
+ label: 'Amount',
565
+ hoverLabel: (
566
+ <>
567
+ You send 100 GBP <br />
568
+ You get 99.39 GBP{' '}
569
+ </>
570
+ ),
571
+ ...(activeStep > 1 && { onClick: () => setActiveStep(1) }),
572
+ },
573
+ {
574
+ label: 'Review',
575
+ ...(activeStep > 2 && { onClick: () => setActiveStep(2) }),
576
+ },
577
+ {
578
+ label: 'Pay',
579
+ ...(activeStep > 3 && { onClick: () => setActiveStep(3) }),
580
+ },
581
+ ];
582
+
583
+ return (
584
+ <>
585
+ {/* With critical banner - negative sentiment */}
586
+ <FlowNavigation
587
+ avatar={<AvatarView profileType={args.profileType} />}
588
+ logo={<Logo />}
589
+ activeStep={activeStep}
590
+ steps={steps}
591
+ banner={{
592
+ sentiment: 'negative',
593
+ title: 'Action required',
594
+ description: 'Please verify your identity to continue with this transfer.',
595
+ action: {
596
+ label: 'Verify now',
597
+ onClick: () => console.log('Verify clicked'),
598
+ },
599
+ }}
600
+ onClose={args.showCloseButton ? () => {} : undefined}
601
+ onGoBack={
602
+ args.showMobileBackButton
603
+ ? () => setActiveStep(activeStep > 0 ? activeStep - 1 : 0)
604
+ : undefined
605
+ }
606
+ />
607
+
608
+ <Container size="narrow" className="m-y-5">
609
+ <Body className="text-xs-center">
610
+ <Display type={Typography.DISPLAY_SMALL}>Critical Banner Examples</Display>
611
+ </Body>
612
+ </Container>
613
+
614
+ {/* With critical banner - warning sentiment */}
615
+ <FlowNavigation
616
+ avatar={<AvatarView profileType={args.profileType} />}
617
+ logo={<Logo />}
618
+ activeStep={activeStep}
619
+ steps={steps}
620
+ banner={{
621
+ sentiment: 'warning',
622
+ title: 'Rate expires soon',
623
+ description:
624
+ 'Your guaranteed rate will expire in 2 hours. Complete your transfer to lock it in.',
625
+ action: {
626
+ label: 'Continue',
627
+ onClick: () => console.log('Continue clicked'),
628
+ },
629
+ actionSecondary: {
630
+ label: 'Cancel transfer',
631
+ onClick: () => console.log('Cancel clicked'),
632
+ },
633
+ }}
634
+ onClose={args.showCloseButton ? () => {} : undefined}
635
+ onGoBack={
636
+ args.showMobileBackButton
637
+ ? () => setActiveStep(activeStep > 0 ? activeStep - 1 : 0)
638
+ : undefined
639
+ }
640
+ />
641
+
642
+ <Container size="narrow" className="m-y-3">
643
+ <Body>Example content below the navigation</Body>
644
+ </Container>
645
+ </>
646
+ );
647
+ },
648
+ };
@@ -3,6 +3,7 @@ import { Meta, StoryObj } from '@storybook/react-webpack5';
3
3
  import AvatarView from '../../AvatarView';
4
4
  import { ProfileType } from '../../common';
5
5
  import Logo from '../../Logo';
6
+ import { withVariantConfig } from '../../../.storybook/helpers';
6
7
  import { allModes } from '../../../.storybook/modes';
7
8
 
8
9
  import FlowNavigation, { FlowNavigationProps } from '../FlowNavigation';
@@ -45,23 +46,6 @@ export const EmptySteps: Story = {
45
46
  };
46
47
 
47
48
  export const LongLabel: Story = {
48
- parameters: {
49
- chromatic: {
50
- viewports: [360],
51
- },
52
- viewport: {
53
- options: {
54
- narrow: {
55
- name: '360px',
56
- styles: { width: '360px', height: '600px' },
57
- type: 'mobile',
58
- },
59
- },
60
- },
61
- },
62
- globals: {
63
- viewport: 'narrow',
64
- },
65
49
  render: () => (
66
50
  <FlowNavigation
67
51
  {...baseProps}
@@ -75,4 +59,71 @@ export const LongLabel: Story = {
75
59
  activeStep={2}
76
60
  />
77
61
  ),
62
+ ...withVariantConfig(['mobile']),
63
+ };
64
+
65
+ export const CriticalBannerMobile: Story = {
66
+ render: () => (
67
+ <>
68
+ <FlowNavigation
69
+ {...baseProps}
70
+ steps={[
71
+ { label: 'Amount', hoverLabel: '100 GBP', onClick: noop },
72
+ { label: 'You', hoverLabel: 'Elena Durante', onClick: noop },
73
+ { label: 'Recipient', hoverLabel: 'Daniele Tomboro', onClick: noop },
74
+ { label: 'Review', onClick: noop },
75
+ { label: 'Pay', onClick: noop },
76
+ ]}
77
+ activeStep={2}
78
+ banner={{
79
+ sentiment: 'negative',
80
+ title: 'Action required',
81
+ description: 'Please verify your identity to continue with this transfer.',
82
+ action: {
83
+ label: 'Verify now',
84
+ onClick: noop,
85
+ },
86
+ }}
87
+ />
88
+ <FlowNavigation
89
+ {...baseProps}
90
+ steps={[
91
+ { label: 'Amount', hoverLabel: '100 GBP', onClick: noop },
92
+ { label: 'You', hoverLabel: 'Elena Durante', onClick: noop },
93
+ { label: 'Recipient', hoverLabel: 'Daniele Tomboro', onClick: noop },
94
+ { label: 'Review', onClick: noop },
95
+ { label: 'Pay', onClick: noop },
96
+ ]}
97
+ activeStep={1}
98
+ banner={{
99
+ sentiment: 'warning',
100
+ title: 'Rate expires soon',
101
+ description:
102
+ 'Your guaranteed rate will expire in 2 hours. Complete your transfer to lock it in.',
103
+ action: {
104
+ label: 'Continue',
105
+ onClick: noop,
106
+ },
107
+ actionSecondary: {
108
+ label: 'Cancel',
109
+ onClick: noop,
110
+ },
111
+ }}
112
+ />
113
+ <FlowNavigation
114
+ {...baseProps}
115
+ steps={[
116
+ { label: 'Amount', hoverLabel: '100 GBP', onClick: noop },
117
+ { label: 'You', hoverLabel: 'Elena Durante', onClick: noop },
118
+ { label: 'Recipient', hoverLabel: 'Daniele Tomboro', onClick: noop },
119
+ ]}
120
+ activeStep={0}
121
+ banner={{
122
+ sentiment: 'neutral',
123
+ description: 'This is a neutral informational banner without a title.',
124
+ }}
125
+ />
126
+ </>
127
+ ),
128
+ ...withVariantConfig(['mobile']),
78
129
  };
@@ -4,7 +4,6 @@ import { adjustLocale, DEFAULT_LOCALE, getDirectionFromLocale } from '../common'
4
4
  import en from '../i18n/en.json';
5
5
 
6
6
  import { DirectionProvider } from './Direction';
7
- import { LanguageProvider } from './Language';
8
7
 
9
8
  export interface ProviderProps {
10
9
  i18n: Pick<ResolvedIntlConfig, 'locale' | 'messages'> &
@@ -30,16 +29,14 @@ export default function Provider({ i18n, children }: ProviderProps) {
30
29
 
31
30
  return (
32
31
  <DirectionProvider direction={getDirectionFromLocale(locale)}>
33
- <LanguageProvider locale={locale}>
34
- <IntlProvider
35
- defaultLocale={DEFAULT_LOCALE}
36
- locale={intlConfig.locale}
37
- messages={intlConfig.messages}
38
- defaultRichTextElements={defaultRichTextElements}
39
- >
40
- {children}
41
- </IntlProvider>
42
- </LanguageProvider>
32
+ <IntlProvider
33
+ defaultLocale={DEFAULT_LOCALE}
34
+ locale={intlConfig.locale}
35
+ messages={intlConfig.messages}
36
+ defaultRichTextElements={defaultRichTextElements}
37
+ >
38
+ {children}
39
+ </IntlProvider>
43
40
  </DirectionProvider>
44
41
  );
45
42
  }
@@ -1,6 +1,4 @@
1
1
  export { DirectionProvider } from './Direction';
2
2
  export type { DirectionProviderProps } from './Direction';
3
- export { LanguageProvider } from './Language';
4
- export type { LanguageProviderProps } from './Language';
5
3
  export { default } from './Provider';
6
4
  export type { ProviderProps } from './Provider';
package/src/index.ts CHANGED
@@ -123,7 +123,7 @@ export type {
123
123
  PromoCardProps,
124
124
  } from './PromoCard';
125
125
  export type { PromoCardGroupProps } from './PromoCard';
126
- export type { DirectionProviderProps, LanguageProviderProps, ProviderProps } from './Provider';
126
+ export type { DirectionProviderProps, ProviderProps } from './Provider';
127
127
  export type { RadioProps } from './Radio';
128
128
  export type { RadioGroupProps, RadioGroupRadio } from './RadioGroup';
129
129
  export type { RadioOptionProps } from './_deprecated/RadioOption';
@@ -272,7 +272,7 @@ export { default as ProcessIndicator } from './ProcessIndicator';
272
272
  export { default as Progress } from './Progress';
273
273
  export { default as ProgressBar } from './ProgressBar';
274
274
  export { default as PromoCard, PromoCardGroup } from './PromoCard';
275
- export { DirectionProvider, LanguageProvider, default as Provider } from './Provider';
275
+ export { DirectionProvider, default as Provider } from './Provider';
276
276
  export { default as Radio } from './Radio';
277
277
  export { default as RadioGroup } from './RadioGroup';
278
278
  export { default as RadioOption } from './_deprecated/RadioOption';
@@ -1,20 +0,0 @@
1
- 'use strict';
2
-
3
- var React = require('react');
4
- var index = require('../../common/Locale/index.js');
5
- var jsxRuntime = require('react/jsx-runtime');
6
-
7
- const LanguageContext = /*#__PURE__*/React.createContext(index.DEFAULT_LOCALE);
8
- const LanguageProvider = ({
9
- locale,
10
- children
11
- }) => {
12
- return /*#__PURE__*/jsxRuntime.jsx(LanguageContext.Provider, {
13
- value: locale,
14
- children: children
15
- });
16
- };
17
-
18
- exports.LanguageContext = LanguageContext;
19
- exports.LanguageProvider = LanguageProvider;
20
- //# sourceMappingURL=LanguageProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LanguageProvider.js","sources":["../../../src/Provider/Language/LanguageProvider.tsx"],"sourcesContent":["import { createContext, PropsWithChildren } from 'react';\n\nimport { DEFAULT_LOCALE } from '../../common/Locale';\n\nexport const LanguageContext = createContext<string>(DEFAULT_LOCALE);\n\nexport type LanguageProviderProps = PropsWithChildren<{ locale: string }>;\n\nexport const LanguageProvider = ({ locale, children }: LanguageProviderProps) => {\n return <LanguageContext.Provider value={locale}>{children}</LanguageContext.Provider>;\n};\n"],"names":["LanguageContext","createContext","DEFAULT_LOCALE","LanguageProvider","locale","children","_jsx","Provider","value"],"mappings":";;;;;;MAIaA,eAAe,gBAAGC,mBAAa,CAASC,oBAAc;AAI5D,MAAMC,gBAAgB,GAAGA,CAAC;EAAEC,MAAM;AAAEC,EAAAA;AAAQ,CAAyB,KAAI;AAC9E,EAAA,oBAAOC,cAAA,CAACN,eAAe,CAACO,QAAQ,EAAA;AAACC,IAAAA,KAAK,EAAEJ,MAAO;AAAAC,IAAAA,QAAA,EAAEA;AAAQ,GAA2B,CAAC;AACvF;;;"}
@@ -1,17 +0,0 @@
1
- import { createContext } from 'react';
2
- import { DEFAULT_LOCALE } from '../../common/Locale/index.mjs';
3
- import { jsx } from 'react/jsx-runtime';
4
-
5
- const LanguageContext = /*#__PURE__*/createContext(DEFAULT_LOCALE);
6
- const LanguageProvider = ({
7
- locale,
8
- children
9
- }) => {
10
- return /*#__PURE__*/jsx(LanguageContext.Provider, {
11
- value: locale,
12
- children: children
13
- });
14
- };
15
-
16
- export { LanguageContext, LanguageProvider };
17
- //# sourceMappingURL=LanguageProvider.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LanguageProvider.mjs","sources":["../../../src/Provider/Language/LanguageProvider.tsx"],"sourcesContent":["import { createContext, PropsWithChildren } from 'react';\n\nimport { DEFAULT_LOCALE } from '../../common/Locale';\n\nexport const LanguageContext = createContext<string>(DEFAULT_LOCALE);\n\nexport type LanguageProviderProps = PropsWithChildren<{ locale: string }>;\n\nexport const LanguageProvider = ({ locale, children }: LanguageProviderProps) => {\n return <LanguageContext.Provider value={locale}>{children}</LanguageContext.Provider>;\n};\n"],"names":["LanguageContext","createContext","DEFAULT_LOCALE","LanguageProvider","locale","children","_jsx","Provider","value"],"mappings":";;;;MAIaA,eAAe,gBAAGC,aAAa,CAASC,cAAc;AAI5D,MAAMC,gBAAgB,GAAGA,CAAC;EAAEC,MAAM;AAAEC,EAAAA;AAAQ,CAAyB,KAAI;AAC9E,EAAA,oBAAOC,GAAA,CAACN,eAAe,CAACO,QAAQ,EAAA;AAACC,IAAAA,KAAK,EAAEJ,MAAO;AAAAC,IAAAA,QAAA,EAAEA;AAAQ,GAA2B,CAAC;AACvF;;"}
@@ -1,7 +0,0 @@
1
- import { PropsWithChildren } from 'react';
2
- export declare const LanguageContext: import("react").Context<string>;
3
- export type LanguageProviderProps = PropsWithChildren<{
4
- locale: string;
5
- }>;
6
- export declare const LanguageProvider: ({ locale, children }: LanguageProviderProps) => import("react").JSX.Element;
7
- //# sourceMappingURL=LanguageProvider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LanguageProvider.d.ts","sourceRoot":"","sources":["../../../../src/Provider/Language/LanguageProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAIzD,eAAO,MAAM,eAAe,iCAAwC,CAAC;AAErE,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE1E,eAAO,MAAM,gBAAgB,GAAI,sBAAsB,qBAAqB,gCAE3E,CAAC"}
@@ -1,3 +0,0 @@
1
- export { LanguageProvider } from './LanguageProvider';
2
- export type { LanguageProviderProps } from './LanguageProvider';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/Provider/Language/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}