Wise Dynamic Flows
This package is deprecated.
Please use @wise/dynamic-flow-client or @wise/dynamic-flow-client-internal.
Neptune is the Design System built by and used at Wise. Neptune Web is the Neptune framework for Web. Neptune Web provides a way to build high quality, consistent user experiences on the web with ease.
This is the Wise Web Dynamic Flows React component library. It uses Neptune Components and Neptune CSS.
Usage
Neptune Components are published to npm as @transferwise/dynamic-flows.
Install @transferwise/dynamic-flows
and its peer dependencies.
# pnpm
pnpm add @transferwise/components @transferwise/neptune-css @transferwise/icons @transferwise/neptune-validation prop-types react react-dom react-intl
# yarn
yarn add @transferwise/components @transferwise/neptune-css @transferwise/icons @transferwise/neptune-validation prop-types react react-dom react-intl
# npm
npm install @transferwise/components @transferwise/neptune-css @transferwise/icons @transferwise/neptune-validation prop-types react react-dom react-intl
Important: Please refer to setup instructions for components and neptune CSS to ensure you have imported all required CSS files before you begin. This is required to enable styling and theming.
// Should be imported once in your application
// components and neptune-css files should be imported here
import '@transferwise/dynamic-flows/build/main.css';
// next.config.js
// Include '@transferwise/dynamic-flows' in list of modules to transpile
{
// ... other config settings
transpileModules: [
// ... other modules
'@transferwise/dynamic-flows'
],
}
// --------------
// jest.config.js
// Want ensure '@transferwise/dynamic-flows' is transformed for tests
{
// ... other config settings
transformIgnorePatterns: [
// ... other patterns
'node_modules/?!(@transferwise/dynamic-flows)',
]
}
The DynamicFlow
component must be wrapped in a Neptune Provider
to support localisation, and a ThemeProvider
to provide theming. See the docs for full instructions.
import {
Provider,
SnackbarProvider,
translations as componentTranslations,
getLangFromLocale,
DEFAULT_LANG,
} from '@transferwise/components';
import {
DynamicFlow,
translations as dynamicFlowsTranslations,
} from '@transferwise/dynamic-flows/';
const lang = getLangFromLocale(locale) || DEFAULT_LANG;
const i18n = {
locale,
messages: {
...componentTranslations[lang],
...dynamicFlowsTranslations[lang],
},
};
return (
<Provider i18n={i18n}>
<ThemeProvider theme={theme}>
<SnackbarProvider>
<DynamicFlow {...props} />
</SnackbarProvider>
</ThemeProvider>
</Provider>
);
DF Props
There are few ways to initialise DF:
- with a
initialAction
or with aninitialStep
- with a
baseUrl
or with afetcher
function
We recommend using a initialAction
and a fetcher
function.
<DynamicFlow
initialAction={{ method: 'GET', url: '/my-amazing-new-flow' }}
fetcher={(...args) => fetch(...args)}
onClose={(result) => {
console.log('Flow exited with', result);
}}
onError={(error, statusCode) => {
console.error('Flow Error:', error, 'status code', statusCode);
}}
/>
initialAction
vs initialStep
In some cases you may want to obtain the initial step yourself, and then pass it to DF component. In these cases you don't provide a initialAction
since the next steps will result from interactions in the provided initialStep
:
<DynamicFlow
initialStep={someInitialStepIfoundLayingAroundHere}
fetcher={...}
onClose={...}
onError={...}
/>
baseUrl
vs fetcher
We recommend passing a fetcher function. This can be window.fetch
itself or some wrapper function where you inject auth headers and anything else you many need.
You can take advantage of the makeFetcher
utility function. This function takes a baseUrl
and additionalHeaders
arguments. The baseUrl
will be prefixed to any relative request URLs. Absolute URLs will not be altered. The additionalHeaders
parameter can be used to add any request headers you need in all requests, such as { 'X-Access-Token': 'Tr4n5f3rw153' }
:
import { makeFetcher, DynamicFlow } from '@transferwise/dynamic-flows';
const myFetcher = makeFetcher('/my-base-url', { 'X-Access-Token': 'Tr4n5f3rw153' });
...
<DynamicFlow
initialAction={{ method: 'GET', url: '/my-amazing-new-flow' }}
fetcher={myFetcher}
// baseUrl="/my-base-url"
onClose={...}
onError={...}
/>
Logging and Tracking
The DynamicFlow
component accepts two optional props: onTrackableEvent
and onLog
which can be used to track and log.
In the example below we send tracking events to Mixpanel and logging events to Rollbar.
<DynamicFlow
onTrackableEvent={(event, props) => mixpanel.track(event, props)}
onLog={(level, message, extra) => Rollbar[level](message, extra)}
/>
Alternatively, you can log to the browser console:
onTrackableEvent={(event, props) => console.log(event, props)}
onLog={(level, message, extra) => {
const levelToConsole = {
critical: console.error,
error: console.error,
warning: console.warn,
info: console.info,
debug: console.log,
} as const;
levelToConsole[level](message, extra);
}}
More Props
loaderConfig
By default, DF will display a loading animation (The Loader
component from Neptune) when the first step is loading. It will not display it during refresh-on-change or while submitting forms.
You can change the defaults by passing a loaderConfig
prop:
type LoaderConfig = {
size?: `xs | sm | md | lg | xl`;
initial?: boolean;
submission?: boolean;
};
property | type | notes | default |
---|---|---|---|
size |
string | The size of the Loader component. | xl |
initial |
boolean | Whether or not to display the Loader component while loading the initial step. | true |
submission |
boolean | Whether or not to display the Loader component during form submissions. | false |