@wise/dynamic-flow-client-internal 5.17.0 → 5.19.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.
package/build/main.mjs CHANGED
@@ -34,7 +34,11 @@ var __objRest = (source, exclude) => {
34
34
  return target;
35
35
  };
36
36
  var __commonJS = (cb, mod) => function __require() {
37
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
37
+ try {
38
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
39
+ } catch (e) {
40
+ throw mod = 0, e;
41
+ }
38
42
  };
39
43
  var __copyProps = (to, from, except, desc) => {
40
44
  if (from && typeof from === "object" || typeof from === "function") {
@@ -123,7 +127,7 @@ import { useDynamicFlow } from "@wise/dynamic-flow-client";
123
127
  // src/dynamicFlow/telemetry/app-version.ts
124
128
  var appVersion = (
125
129
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
126
- typeof process !== "undefined" ? "5.17.0" : "0.0.0"
130
+ typeof process !== "undefined" ? "5.19.0" : "0.0.0"
127
131
  );
128
132
 
129
133
  // src/dynamicFlow/context-menu/useContextMenu.tsx
@@ -208,27 +212,29 @@ var useDFContextMenu = (controller) => {
208
212
  }
209
213
  },
210
214
  {
211
- label: "Open in Sandbox",
215
+ label: "Copy step JSON",
212
216
  onClick: () => {
213
- openInSandbox(getEncodedCurrentStep());
217
+ copyToClipboard(getCurrentStep());
214
218
  }
215
219
  },
216
220
  {
217
- label: "Open in Sandbox (with model)",
221
+ label: "Open in Studio (experimental)",
218
222
  onClick: () => {
219
- void getEncodedCurrentStepWithModel().then(openInSandbox);
223
+ openIn("studio", getEncodedCurrentStep());
220
224
  }
221
225
  },
222
226
  {
223
- label: "Copy step JSON",
227
+ label: "Open in Sandbox",
224
228
  onClick: () => {
225
- copyToClipboard(getCurrentStep());
229
+ openIn("sandbox", getEncodedCurrentStep());
226
230
  }
227
231
  },
228
232
  {
229
- label: "Copy step JSON (with model)",
233
+ label: "Open in Sandbox (with model)",
230
234
  onClick: () => {
231
- void getCurrentStepWithModel().then(copyToClipboard);
235
+ void getEncodedCurrentStepWithModel().then(
236
+ (base64Step) => openIn("sandbox", base64Step)
237
+ );
232
238
  }
233
239
  }
234
240
  ] : []
@@ -239,9 +245,9 @@ var toBase64 = (str) => {
239
245
  const binString = Array.from(bytes, (b) => String.fromCharCode(b)).join("");
240
246
  return btoa(binString);
241
247
  };
242
- var openInSandbox = (base64Step) => {
248
+ var openIn = (editor, base64Step) => {
243
249
  if (base64Step) {
244
- window.open(`https://df.wise.com/sandbox#${base64Step}`, "_blank", "noopener,noreferrer");
250
+ window.open(`https://df.wise.com/${editor}#${base64Step}`, "_blank", "noopener,noreferrer");
245
251
  }
246
252
  };
247
253
  var openVersionPage = (version) => {
@@ -307,54 +313,8 @@ var recursivelyRemoveNullish = (element) => {
307
313
  // src/dynamicFlow/useWiseToCoreProps.tsx
308
314
  import { useMemo as useMemo2 } from "react";
309
315
 
310
- // src/dynamicFlow/telemetry/getLogEvent.ts
311
- var getLogEvent = (onLog) => (level, message, extra) => {
312
- const extraWithVersion = __spreadProps(__spreadValues({}, extra), {
313
- dfWiseVersion: appVersion
314
- });
315
- if (level !== "info" && onLog) {
316
- if (onLog) {
317
- onLog(level, message, extraWithVersion);
318
- } else {
319
- logToRollbar(level, message, extraWithVersion);
320
- }
321
- }
322
- };
323
- var logToRollbar = (level, message, extra) => {
324
- try {
325
- const rollbar = typeof window.Rollbar !== "undefined" ? window.Rollbar : void 0;
326
- rollbar == null ? void 0 : rollbar[level](message, extra);
327
- } catch (error) {
328
- console.error("Failed to log to Rollbar", error);
329
- }
330
- };
331
-
332
- // src/dynamicFlow/telemetry/getTrackEvent.ts
333
- import { eventNames } from "@wise/dynamic-flow-client";
334
- var prefix = "Dynamic Flow - ";
335
- var getTrackEvent = (onEvent, onAnalytics) => (name, properties) => {
336
- onEvent == null ? void 0 : onEvent(name, properties);
337
- if (includeInAnalytics(name)) {
338
- onAnalytics == null ? void 0 : onAnalytics(name, properties);
339
- }
340
- };
341
- var includeInAnalytics = (name) => {
342
- const eventName = name.startsWith(prefix) ? name.slice(prefix.length) : name;
343
- if (isCoreEventName(eventName)) {
344
- return true;
345
- }
346
- if (eventName in customEventsToAnalytics) {
347
- return customEventsToAnalytics[eventName];
348
- }
349
- return true;
350
- };
351
- var isCoreEventName = (eventName) => {
352
- return eventNames.includes(eventName);
353
- };
354
- var customEventsToAnalytics = {
355
- "Theme Required": false
356
- // Excluded from analytics
357
- };
316
+ // src/dynamicFlow/getMergedRenderers.tsx
317
+ import { getDynamicSubflowRenderer } from "@wise/dynamic-flow-client";
358
318
 
359
319
  // ../renderers/src/AlertRenderer.tsx
360
320
  import { Alert } from "@transferwise/components";
@@ -405,10 +365,10 @@ var AlertRenderer = {
405
365
  };
406
366
  var mapCtaToAlertAction = (callToAction) => {
407
367
  if (callToAction) {
408
- return __spreadValues(__spreadValues({
368
+ return __spreadValues({
409
369
  text: callToAction.title,
410
370
  "aria-label": callToAction.accessibilityDescription
411
- }, "onClick" in callToAction ? { onClick: callToAction.onClick } : {}), callToAction.href ? { href: callToAction.href, target: "_blank" } : {});
371
+ }, callToAction.getAnchorProps());
412
372
  }
413
373
  return void 0;
414
374
  };
@@ -893,6 +853,18 @@ var getPriority = (control, tags) => {
893
853
 
894
854
  // ../renderers/src/components/FieldInput.tsx
895
855
  import { Field } from "@transferwise/components";
856
+ import { useEffect as useEffect4, useRef } from "react";
857
+
858
+ // ../renderers/src/utils/scroll-to-if-not-visible.ts
859
+ var scrollToIfNotVisible = (ref) => {
860
+ const rect = ref == null ? void 0 : ref.getBoundingClientRect();
861
+ if (!ref || !rect) {
862
+ return;
863
+ }
864
+ if (rect.bottom > window.innerHeight || rect.top < 0) {
865
+ ref.scrollIntoView({ behavior: "instant" });
866
+ }
867
+ };
896
868
 
897
869
  // ../renderers/src/components/Help.tsx
898
870
  import { Info, Markdown } from "@transferwise/components";
@@ -936,28 +908,47 @@ function LabelContentWithHelp({ text, help }) {
936
908
 
937
909
  // ../renderers/src/components/FieldInput.tsx
938
910
  import { jsx as jsx19 } from "react/jsx-runtime";
939
- function FieldInput({ id, children, label, validation, description, help }) {
911
+ function FieldInput({
912
+ id,
913
+ children,
914
+ label,
915
+ validation,
916
+ description,
917
+ help,
918
+ loadingState = "idle",
919
+ inlineAlert
920
+ }) {
940
921
  const labelContent = label && help ? /* @__PURE__ */ jsx19(LabelContentWithHelp, { text: label, help }) : label;
941
- return /* @__PURE__ */ jsx19(
922
+ const message = validation == null ? void 0 : validation.message;
923
+ const ref = useRef(null);
924
+ useEffect4(() => {
925
+ if (message) {
926
+ scrollToIfNotVisible(ref.current);
927
+ }
928
+ }, [message]);
929
+ return /* @__PURE__ */ jsx19("div", { ref, children: /* @__PURE__ */ jsx19(
942
930
  Field,
943
931
  {
944
932
  id,
945
933
  label: labelContent,
946
934
  description,
947
- message: validation == null ? void 0 : validation.message,
948
- sentiment: mapStatusToSentiment(validation),
935
+ message: message != null ? message : inlineAlert == null ? void 0 : inlineAlert.content,
936
+ messageLoading: loadingState !== "idle",
937
+ sentiment: mapStatusToSentiment(validation, inlineAlert == null ? void 0 : inlineAlert.context),
949
938
  children
950
939
  }
951
- );
940
+ ) });
952
941
  }
953
- var mapStatusToSentiment = (validation) => {
954
- if (validation) {
955
- if (validation.status === "valid") {
956
- return "positive";
942
+ var mapStatusToSentiment = (validation, defaultContext) => {
943
+ if (validation == null ? void 0 : validation.message) {
944
+ switch (validation.status) {
945
+ case "valid":
946
+ return "positive";
947
+ case "invalid":
948
+ return "negative";
957
949
  }
958
- return "negative";
959
950
  }
960
- return void 0;
951
+ return defaultContext;
961
952
  };
962
953
  var FieldInput_default = FieldInput;
963
954
 
@@ -1025,7 +1016,19 @@ var CheckboxComponent = (props) => {
1025
1016
  "value"
1026
1017
  ]);
1027
1018
  const checkboxProps = __spreadProps(__spreadValues({}, rest), { label: title, secondary: description, checked: value });
1028
- return /* @__PURE__ */ jsx23(FieldInput_default, { id, label: "", description: "", validation: validationState, help, children: /* @__PURE__ */ jsx23(Checkbox, __spreadValues({ id }, checkboxProps)) });
1019
+ return /* @__PURE__ */ jsx23(
1020
+ FieldInput_default,
1021
+ {
1022
+ id,
1023
+ label: "",
1024
+ description: "",
1025
+ validation: validationState,
1026
+ help,
1027
+ inlineAlert: rest.inlineAlert,
1028
+ loadingState: rest.fieldLoadingState,
1029
+ children: /* @__PURE__ */ jsx23(Checkbox, __spreadValues({ id }, checkboxProps))
1030
+ }
1031
+ );
1029
1032
  };
1030
1033
  var CheckboxItemComponent = (props) => {
1031
1034
  const {
@@ -1080,7 +1083,7 @@ var SwitchItemComponent = (props) => {
1080
1083
  );
1081
1084
  };
1082
1085
  var getInlineAlertOrValidation = (validationState, inlineAlert) => {
1083
- if (validationState && validationState.status === "invalid") {
1086
+ if ((validationState == null ? void 0 : validationState.status) === "invalid") {
1084
1087
  return /* @__PURE__ */ jsx23(ListItem3.Prompt, { sentiment: "negative", children: validationState.message });
1085
1088
  }
1086
1089
  return getInlineAlert(inlineAlert);
@@ -1217,6 +1220,8 @@ var DateInputRenderer = {
1217
1220
  label: title,
1218
1221
  description,
1219
1222
  validation: validationState,
1223
+ inlineAlert: props.inlineAlert,
1224
+ loadingState: props.fieldLoadingState,
1220
1225
  help,
1221
1226
  children: /* @__PURE__ */ jsx26(VariableDateInput_default, { control, inputProps })
1222
1227
  }
@@ -1232,6 +1237,7 @@ import { ListItem as ListItem5 } from "@transferwise/components";
1232
1237
  import { ListItem as ListItem4 } from "@transferwise/components";
1233
1238
  import { jsx as jsx27 } from "react/jsx-runtime";
1234
1239
  var getAdditionalInfo = (additionalInfo) => {
1240
+ var _a, _b;
1235
1241
  if (!additionalInfo) {
1236
1242
  return void 0;
1237
1243
  }
@@ -1240,12 +1246,9 @@ var getAdditionalInfo = (additionalInfo) => {
1240
1246
  return /* @__PURE__ */ jsx27(
1241
1247
  ListItem4.AdditionalInfo,
1242
1248
  {
1243
- action: {
1244
- label: text,
1245
- href,
1246
- onClick,
1247
- target: "_blank"
1248
- }
1249
+ action: __spreadValues({
1250
+ label: text
1251
+ }, (_b = (_a = additionalInfo.getAnchorProps) == null ? void 0 : _a.call(additionalInfo)) != null ? _b : { onClick })
1249
1252
  }
1250
1253
  );
1251
1254
  }
@@ -1448,7 +1451,7 @@ var renderDecisionList = ({ options, control }) => {
1448
1451
  disabled,
1449
1452
  media,
1450
1453
  title: itemTitle,
1451
- href,
1454
+ getAnchorProps,
1452
1455
  additionalText,
1453
1456
  inlineAlert,
1454
1457
  supportingValues,
@@ -1466,7 +1469,7 @@ var renderDecisionList = ({ options, control }) => {
1466
1469
  media: getMedia(media, shouldUseAvatar(control, tags)),
1467
1470
  prompt: getInlineAlert(inlineAlert),
1468
1471
  additionalInfo: additionalText ? getAdditionalInfo({ text: additionalText }) : void 0,
1469
- control: href ? /* @__PURE__ */ jsx30(ListItem5.Navigation, { href, target: "_blank" }) : /* @__PURE__ */ jsx30(ListItem5.Navigation, { onClick })
1472
+ control: /* @__PURE__ */ jsx30(ListItem5.Navigation, __spreadValues({}, getAnchorProps()))
1470
1473
  },
1471
1474
  JSON.stringify(rest)
1472
1475
  );
@@ -1523,7 +1526,7 @@ var external_confirmation_messages_default = defineMessages5({
1523
1526
 
1524
1527
  // ../renderers/src/ExternalConfirmationRenderer.tsx
1525
1528
  import { useIntl as useIntl5 } from "react-intl";
1526
- import { useEffect as useEffect4 } from "react";
1529
+ import { useEffect as useEffect5 } from "react";
1527
1530
  import { Fragment as Fragment4, jsx as jsx32, jsxs as jsxs7 } from "react/jsx-runtime";
1528
1531
  var ExternalConfirmationRenderer = {
1529
1532
  canRenderType: "external-confirmation",
@@ -1536,7 +1539,7 @@ function ExternalConfirmationRendererComponent({
1536
1539
  onCancel
1537
1540
  }) {
1538
1541
  const { formatMessage } = useIntl5();
1539
- useEffect4(() => {
1542
+ useEffect5(() => {
1540
1543
  open();
1541
1544
  }, []);
1542
1545
  return /* @__PURE__ */ jsx32(
@@ -1650,7 +1653,7 @@ var HeadingRenderer_default = HeadingRenderer;
1650
1653
 
1651
1654
  // ../renderers/src/ImageRenderer/UrlImage.tsx
1652
1655
  import { Image } from "@transferwise/components";
1653
- import { useEffect as useEffect5, useState as useState5 } from "react";
1656
+ import { useEffect as useEffect6, useState as useState5 } from "react";
1654
1657
 
1655
1658
  // ../renderers/src/utils/api-utils.ts
1656
1659
  function isRelativePath(url = "") {
@@ -1670,7 +1673,7 @@ function UrlImage({
1670
1673
  httpClient
1671
1674
  }) {
1672
1675
  const [imageSource, setImageSource] = useState5("");
1673
- useEffect5(() => {
1676
+ useEffect6(() => {
1674
1677
  if (!uri.startsWith("urn:")) {
1675
1678
  void getImageSource(httpClient, uri).then(setImageSource);
1676
1679
  }
@@ -1909,6 +1912,8 @@ var IntegerInputRenderer = {
1909
1912
  label: title,
1910
1913
  description,
1911
1914
  validation: validationState,
1915
+ inlineAlert: props.inlineAlert,
1916
+ loadingState: props.fieldLoadingState,
1912
1917
  help,
1913
1918
  children: /* @__PURE__ */ jsx43(InputGroup, { addonStart: getInputGroupAddonStart(media), children: /* @__PURE__ */ jsx43(
1914
1919
  Input,
@@ -1942,33 +1947,17 @@ var getCTAControl = (callToAction, { ctaSecondary, fullyInteractive }) => {
1942
1947
  if (!callToAction) {
1943
1948
  return void 0;
1944
1949
  }
1945
- const { accessibilityDescription, href, title, context, onClick } = callToAction;
1950
+ const { accessibilityDescription, title, context } = callToAction;
1946
1951
  const { priority, sentiment } = getPriorityAndSentiment(ctaSecondary, context);
1947
- if (href) {
1948
- return /* @__PURE__ */ jsx44(
1949
- ListItem6.Button,
1950
- {
1951
- href,
1952
- target: "_blank",
1953
- rel: "noopener noreferrer",
1954
- partiallyInteractive: !fullyInteractive,
1955
- priority,
1956
- "aria-description": accessibilityDescription,
1957
- sentiment,
1958
- children: title
1959
- }
1960
- );
1961
- }
1962
1952
  return /* @__PURE__ */ jsx44(
1963
1953
  ListItem6.Button,
1964
- {
1965
- "aria-description": accessibilityDescription,
1954
+ __spreadProps(__spreadValues({}, callToAction.getAnchorProps()), {
1966
1955
  partiallyInteractive: !fullyInteractive,
1967
1956
  priority,
1957
+ "aria-description": accessibilityDescription,
1968
1958
  sentiment,
1969
- onClick,
1970
1959
  children: title
1971
- }
1960
+ })
1972
1961
  );
1973
1962
  };
1974
1963
  var getPriorityAndSentiment = (ctaSecondary, context) => {
@@ -1986,20 +1975,10 @@ var getHeaderAction = (callToAction) => {
1986
1975
  if (!callToAction) {
1987
1976
  return void 0;
1988
1977
  }
1989
- const { accessibilityDescription, href, title, onClick } = callToAction;
1990
- return href ? {
1991
- "aria-label": accessibilityDescription,
1992
- text: title,
1993
- href,
1994
- target: "_blank"
1995
- } : {
1996
- "aria-label": accessibilityDescription,
1997
- text: title,
1998
- onClick: (event) => {
1999
- event.preventDefault();
2000
- onClick();
2001
- }
2002
- };
1978
+ return __spreadValues({
1979
+ "aria-label": callToAction.accessibilityDescription,
1980
+ text: callToAction.title
1981
+ }, callToAction.getAnchorProps());
2003
1982
  };
2004
1983
 
2005
1984
  // ../renderers/src/ListRenderer.tsx
@@ -2162,7 +2141,7 @@ var ModalRenderer = {
2162
2141
 
2163
2142
  // ../renderers/src/MoneyInputRenderer.tsx
2164
2143
  import { MoneyInput } from "@transferwise/components";
2165
- import { useEffect as useEffect6 } from "react";
2144
+ import { useEffect as useEffect7 } from "react";
2166
2145
  import { useIntl as useIntl6 } from "react-intl";
2167
2146
  import { jsx as jsx52 } from "react/jsx-runtime";
2168
2147
  var groupingTags2 = Object.keys(group_messages_default).filter((key) => key !== "all");
@@ -2185,7 +2164,7 @@ function MoneyInputRendererComponent(props) {
2185
2164
  onAmountChange,
2186
2165
  onCurrencyChange
2187
2166
  } = props;
2188
- useEffect6(() => {
2167
+ useEffect7(() => {
2189
2168
  if (!isValidIndex(selectedCurrencyIndex, currencies.length)) {
2190
2169
  onCurrencyChange(0);
2191
2170
  }
@@ -2503,6 +2482,7 @@ import { Status, UploadInput } from "@transferwise/components";
2503
2482
 
2504
2483
  // ../renderers/src/components/UploadFieldInput.tsx
2505
2484
  var import_classnames4 = __toESM(require_classnames());
2485
+ import { useEffect as useEffect8, useRef as useRef2 } from "react";
2506
2486
  import { InlineAlert as InlineAlert2 } from "@transferwise/components";
2507
2487
  import { jsx as jsx57, jsxs as jsxs12 } from "react/jsx-runtime";
2508
2488
  function UploadFieldInput({
@@ -2515,9 +2495,17 @@ function UploadFieldInput({
2515
2495
  }) {
2516
2496
  const labelContent = label && help ? /* @__PURE__ */ jsx57(LabelContentWithHelp, { text: label, help }) : label;
2517
2497
  const descriptionId = description ? `${id}-description` : void 0;
2498
+ const message = validation == null ? void 0 : validation.message;
2499
+ const ref = useRef2(null);
2500
+ useEffect8(() => {
2501
+ if (message) {
2502
+ scrollToIfNotVisible(ref.current);
2503
+ }
2504
+ }, [message]);
2518
2505
  return /* @__PURE__ */ jsxs12(
2519
2506
  "div",
2520
2507
  {
2508
+ ref,
2521
2509
  className: (0, import_classnames4.default)("form-group d-block", {
2522
2510
  "has-error": (validation == null ? void 0 : validation.status) === "invalid"
2523
2511
  }),
@@ -2642,6 +2630,8 @@ var NumberInputRenderer = {
2642
2630
  label: title,
2643
2631
  description,
2644
2632
  validation: validationState,
2633
+ inlineAlert: props.inlineAlert,
2634
+ loadingState: props.fieldLoadingState,
2645
2635
  help,
2646
2636
  children: /* @__PURE__ */ jsx59(InputGroup2, { addonStart: getInputGroupAddonStart(media), children: /* @__PURE__ */ jsx59(
2647
2637
  Input2,
@@ -3348,7 +3338,7 @@ function RadioInputRendererComponent(props) {
3348
3338
 
3349
3339
  // ../renderers/src/SelectInputRenderer/TabInputRendererComponent.tsx
3350
3340
  import { Tabs } from "@transferwise/components";
3351
- import { useEffect as useEffect7 } from "react";
3341
+ import { useEffect as useEffect9 } from "react";
3352
3342
  import { Fragment as Fragment9, jsx as jsx71, jsxs as jsxs21 } from "react/jsx-runtime";
3353
3343
  function TabInputRendererComponent(props) {
3354
3344
  const {
@@ -3363,7 +3353,7 @@ function TabInputRendererComponent(props) {
3363
3353
  validationState,
3364
3354
  onSelect
3365
3355
  } = props;
3366
- useEffect7(() => {
3356
+ useEffect9(() => {
3367
3357
  if (!isValidIndex2(selectedIndex, options.length)) {
3368
3358
  onSelect(0);
3369
3359
  }
@@ -3476,7 +3466,7 @@ function SelectInputRendererComponent(props) {
3476
3466
  }
3477
3467
 
3478
3468
  // ../renderers/src/SelectInputRenderer/SegmentedInputRendererComponent.tsx
3479
- import { useEffect as useEffect8 } from "react";
3469
+ import { useEffect as useEffect10 } from "react";
3480
3470
  import { SegmentedControl } from "@transferwise/components";
3481
3471
  import { Fragment as Fragment11, jsx as jsx73, jsxs as jsxs23 } from "react/jsx-runtime";
3482
3472
  function SegmentedInputRendererComponent(props) {
@@ -3491,7 +3481,7 @@ function SegmentedInputRendererComponent(props) {
3491
3481
  validationState,
3492
3482
  onSelect
3493
3483
  } = props;
3494
- useEffect8(() => {
3484
+ useEffect10(() => {
3495
3485
  if (!isValidIndex3(selectedIndex, options.length)) {
3496
3486
  onSelect(0);
3497
3487
  }
@@ -3609,7 +3599,7 @@ var StatusListRenderer = {
3609
3599
  render: ({ margin, items, title }) => /* @__PURE__ */ jsxs25("div", { className: getMargin(margin), children: [
3610
3600
  title ? /* @__PURE__ */ jsx76(Header9, { title }) : null,
3611
3601
  items.map((item) => {
3612
- const { callToAction, description, icon, status, title: itemTitle } = item;
3602
+ const { callToAction, description, title: itemTitle } = item;
3613
3603
  return /* @__PURE__ */ jsx76(
3614
3604
  ListItem12,
3615
3605
  {
@@ -3619,12 +3609,9 @@ var StatusListRenderer = {
3619
3609
  additionalInfo: callToAction ? /* @__PURE__ */ jsx76(
3620
3610
  ListItem12.AdditionalInfo,
3621
3611
  {
3622
- action: {
3623
- href: callToAction.href,
3624
- onClick: callToAction.href ? void 0 : callToAction.onClick,
3625
- label: callToAction.title,
3626
- target: "_blank"
3627
- }
3612
+ action: __spreadValues({
3613
+ label: callToAction.title
3614
+ }, callToAction.getAnchorProps())
3628
3615
  }
3629
3616
  ) : void 0
3630
3617
  },
@@ -3659,12 +3646,12 @@ var StatusListRenderer_default = StatusListRenderer;
3659
3646
 
3660
3647
  // ../renderers/src/utils/useCustomTheme.ts
3661
3648
  import { useTheme } from "@wise/components-theming";
3662
- import { useEffect as useEffect9, useMemo } from "react";
3649
+ import { useEffect as useEffect11, useMemo } from "react";
3663
3650
  var ThemeRequiredEventName = "Theme Required";
3664
3651
  var useCustomTheme = (theme, trackEvent) => {
3665
3652
  const theming = useTheme();
3666
3653
  const previousTheme = useMemo(() => theming.theme, []);
3667
- useEffect9(() => {
3654
+ useEffect11(() => {
3668
3655
  theming.setTheme(theme);
3669
3656
  trackEvent(ThemeRequiredEventName, { theme });
3670
3657
  return theme !== previousTheme ? () => {
@@ -3677,7 +3664,7 @@ var useCustomTheme = (theme, trackEvent) => {
3677
3664
 
3678
3665
  // ../renderers/src/step/StepFooter.tsx
3679
3666
  import { Button as Button7 } from "@transferwise/components";
3680
- import { useEffect as useEffect10, useRef, useState as useState12 } from "react";
3667
+ import { useEffect as useEffect12, useRef as useRef3, useState as useState12 } from "react";
3681
3668
  import { useIntl as useIntl14 } from "react-intl";
3682
3669
 
3683
3670
  // ../renderers/src/messages/step.messages.ts
@@ -3705,7 +3692,7 @@ var DefaultFooter = ({ footer }) => {
3705
3692
  };
3706
3693
  var FooterWithScrollButton = ({ footer }) => {
3707
3694
  const { formatMessage } = useIntl14();
3708
- const endOfLayoutRef = useRef(null);
3695
+ const endOfLayoutRef = useRef3(null);
3709
3696
  const isElementVisible = useIsElementVisible(endOfLayoutRef);
3710
3697
  const scrollButton = /* @__PURE__ */ jsx77(
3711
3698
  Button7,
@@ -3735,7 +3722,7 @@ var FooterWithScrollButton = ({ footer }) => {
3735
3722
  };
3736
3723
  var useIsElementVisible = (elementRef) => {
3737
3724
  const [isVisible, setIsVisible] = useState12(false);
3738
- useEffect10(() => {
3725
+ useEffect12(() => {
3739
3726
  const element = elementRef.current;
3740
3727
  if (!element) return;
3741
3728
  const observer = new IntersectionObserver(([entry]) => {
@@ -4095,6 +4082,8 @@ var TextInputRenderer = {
4095
4082
  label: title,
4096
4083
  description,
4097
4084
  validation: validationState,
4085
+ inlineAlert: props.inlineAlert,
4086
+ loadingState: props.fieldLoadingState,
4098
4087
  help,
4099
4088
  children: /* @__PURE__ */ jsx87(InputGroup4, { addonStart: getInputGroupAddonStart(media), children: /* @__PURE__ */ jsx87(VariableTextInput, __spreadValues({}, inputProps)) })
4100
4089
  }
@@ -4239,12 +4228,9 @@ function UpsellRendererComponent(props) {
4239
4228
  className: getMargin(margin),
4240
4229
  mediaName: getMediaName(media),
4241
4230
  title: text,
4242
- action: {
4243
- href: callToAction.href,
4244
- onClick: callToAction.href ? void 0 : callToAction.onClick,
4245
- target: callToAction.href ? "_blank" : void 0,
4231
+ action: __spreadValues({
4246
4232
  text: callToAction.title
4247
- },
4233
+ }, callToAction.getAnchorProps()),
4248
4234
  onDismiss: onDismiss ? () => {
4249
4235
  setIsVisible(false);
4250
4236
  onDismiss();
@@ -4254,7 +4240,7 @@ function UpsellRendererComponent(props) {
4254
4240
  }
4255
4241
  var urnPrefix2 = "urn:wise:illustrations:";
4256
4242
  var getMediaName = (media) => {
4257
- if (media && media.type === "image" && media.uri.startsWith(urnPrefix2)) {
4243
+ if ((media == null ? void 0 : media.type) === "image" && media.uri.startsWith(urnPrefix2)) {
4258
4244
  const mediaName = media.uri.substring(urnPrefix2.length);
4259
4245
  if (supportedMediaNames.includes(mediaName)) {
4260
4246
  return mediaName;
@@ -4373,6 +4359,115 @@ var InitialLoadingStateRenderer = {
4373
4359
  )
4374
4360
  };
4375
4361
 
4362
+ // src/dynamicFlow/DynamicFlowModal.tsx
4363
+ import { useDynamicFlowModal } from "@wise/dynamic-flow-client";
4364
+ import { Modal as Modal5 } from "@transferwise/components";
4365
+ import { jsx as jsx92 } from "react/jsx-runtime";
4366
+ function DynamicFlowModal(props) {
4367
+ const _a = props, { className = "" } = _a, rest = __objRest(_a, ["className"]);
4368
+ const dfProps = useWiseToCoreProps(rest);
4369
+ const df = useDynamicFlowModal(dfProps);
4370
+ return /* @__PURE__ */ jsx92(
4371
+ Modal5,
4372
+ __spreadProps(__spreadValues({
4373
+ className: `dynamic-flow-modal ${className}`,
4374
+ disableDimmerClickToClose: true
4375
+ }, df.modal), {
4376
+ body: /* @__PURE__ */ jsx92("div", { className: "dynamic-flow-modal", children: df.modal.body })
4377
+ })
4378
+ );
4379
+ }
4380
+
4381
+ // src/dynamicFlow/getMergedRenderers.tsx
4382
+ import { jsx as jsx93 } from "react/jsx-runtime";
4383
+ var wiseRenderers = getWiseRenderers();
4384
+ var getMergedRenderers = (props) => {
4385
+ var _d, _e;
4386
+ const _a = props, { initialAction, initialStep } = _a, restProps = __objRest(_a, ["initialAction", "initialStep"]);
4387
+ const subflowFeatures = __spreadProps(__spreadValues({}, props.features), { nativeBack: true });
4388
+ const subflowRenderer = getDynamicSubflowRenderer({
4389
+ Component: (_b) => {
4390
+ var _c = _b, { presentation, initialRequest } = _c, rest = __objRest(_c, ["presentation", "initialRequest"]);
4391
+ const action = {
4392
+ url: initialRequest.url,
4393
+ method: initialRequest.method,
4394
+ data: initialRequest.body
4395
+ };
4396
+ return presentation.type === "push" ? /* @__PURE__ */ jsx93(DynamicFlow, __spreadProps(__spreadValues(__spreadValues({}, restProps), rest), { features: subflowFeatures, initialAction: action })) : /* @__PURE__ */ jsx93(
4397
+ DynamicFlowModal,
4398
+ __spreadProps(__spreadValues(__spreadValues({}, restProps), rest), {
4399
+ features: subflowFeatures,
4400
+ initialAction: action
4401
+ })
4402
+ );
4403
+ }
4404
+ });
4405
+ const loadingStateRenderer = ((_d = props.features) == null ? void 0 : _d.initialLoader) ? [InitialLoadingStateRenderer] : [];
4406
+ return [...(_e = props.renderers) != null ? _e : [], subflowRenderer, ...loadingStateRenderer, ...wiseRenderers];
4407
+ };
4408
+
4409
+ // src/dynamicFlow/telemetry/getLogEvent.ts
4410
+ var getLogEvent = (onLog) => (level, message, extra) => {
4411
+ const extraWithVersion = __spreadProps(__spreadValues({}, extra), {
4412
+ dfWiseVersion: appVersion
4413
+ });
4414
+ if (level !== "info" && onLog) {
4415
+ if (onLog) {
4416
+ onLog(level, message, extraWithVersion);
4417
+ } else {
4418
+ logToRollbar(level, message, extraWithVersion);
4419
+ }
4420
+ }
4421
+ };
4422
+ var logToRollbar = (level, message, extra) => {
4423
+ try {
4424
+ const rollbar = typeof window.Rollbar !== "undefined" ? window.Rollbar : void 0;
4425
+ rollbar == null ? void 0 : rollbar[level](message, extra);
4426
+ } catch (error) {
4427
+ console.error("Failed to log to Rollbar", error);
4428
+ }
4429
+ };
4430
+
4431
+ // src/dynamicFlow/telemetry/getTrackEvent.ts
4432
+ import { eventNames } from "@wise/dynamic-flow-client";
4433
+
4434
+ // src/dynamicFlow/telemetry/dispatchAnalyticsEvent.ts
4435
+ var dispatchAnalyticsEvent = (eventName, properties) => {
4436
+ const props = __spreadValues({ dfFallbackAnalytics: true }, properties);
4437
+ if (typeof window !== "undefined" && window.mixpanel && typeof window.mixpanel.track === "function") {
4438
+ window.mixpanel.track(eventName, props);
4439
+ }
4440
+ };
4441
+
4442
+ // src/dynamicFlow/telemetry/getTrackEvent.ts
4443
+ var prefix = "Dynamic Flow - ";
4444
+ var getTrackEvent = (onEvent, onAnalytics) => {
4445
+ const dispatchAnalytics = !onAnalytics && !onEvent ? dispatchAnalyticsEvent : onAnalytics;
4446
+ return (name, properties) => {
4447
+ onEvent == null ? void 0 : onEvent(name, properties);
4448
+ if (includeInAnalytics(name)) {
4449
+ dispatchAnalytics == null ? void 0 : dispatchAnalytics(name, properties);
4450
+ }
4451
+ };
4452
+ };
4453
+ var includeInAnalytics = (name) => {
4454
+ const eventName = name.startsWith(prefix) ? name.slice(prefix.length) : name;
4455
+ if (isCoreEventName(eventName)) {
4456
+ return true;
4457
+ }
4458
+ if (eventName in customEventsToAnalytics) {
4459
+ return customEventsToAnalytics[eventName];
4460
+ }
4461
+ return true;
4462
+ };
4463
+ var isCoreEventName = (eventName) => {
4464
+ return eventNames.includes(eventName);
4465
+ };
4466
+ var customEventsToAnalytics = {
4467
+ "Theme Required": false
4468
+ // Excluded from analytics
4469
+ };
4470
+
4376
4471
  // src/dynamicFlow/useOnCopy.tsx
4377
4472
  import { useCallback as useCallback2 } from "react";
4378
4473
  import { useIntl as useIntl16 } from "react-intl";
@@ -4434,54 +4529,10 @@ var handleRejection = (error) => {
4434
4529
  throw error;
4435
4530
  };
4436
4531
 
4437
- // src/dynamicFlow/getMergedRenderers.tsx
4438
- import { getDynamicSubflowRenderer } from "@wise/dynamic-flow-client";
4439
-
4440
- // src/dynamicFlow/DynamicFlowModal.tsx
4441
- import { useDynamicFlowModal } from "@wise/dynamic-flow-client";
4442
- import { Modal as Modal5 } from "@transferwise/components";
4443
- import { jsx as jsx92 } from "react/jsx-runtime";
4444
- function DynamicFlowModal(props) {
4445
- const _a = props, { className = "" } = _a, rest = __objRest(_a, ["className"]);
4446
- const dfProps = useWiseToCoreProps(rest);
4447
- const df = useDynamicFlowModal(dfProps);
4448
- return /* @__PURE__ */ jsx92(
4449
- Modal5,
4450
- __spreadProps(__spreadValues({
4451
- className: `dynamic-flow-modal ${className}`,
4452
- disableDimmerClickToClose: true
4453
- }, df.modal), {
4454
- body: /* @__PURE__ */ jsx92("div", { className: "dynamic-flow-modal", children: df.modal.body })
4455
- })
4456
- );
4457
- }
4458
-
4459
- // src/dynamicFlow/getMergedRenderers.tsx
4460
- import { jsx as jsx93 } from "react/jsx-runtime";
4461
- var wiseRenderers = getWiseRenderers();
4462
- var getMergedRenderers = (props) => {
4463
- var _d, _e;
4464
- const _a = props, { initialAction, initialStep } = _a, restProps = __objRest(_a, ["initialAction", "initialStep"]);
4465
- const subflowFeatures = __spreadProps(__spreadValues({}, props.features), { nativeBack: true });
4466
- const subflowRenderer = getDynamicSubflowRenderer({
4467
- Component: (_b) => {
4468
- var _c = _b, { presentation, initialRequest } = _c, rest = __objRest(_c, ["presentation", "initialRequest"]);
4469
- const action = {
4470
- url: initialRequest.url,
4471
- method: initialRequest.method,
4472
- data: initialRequest.body
4473
- };
4474
- return presentation.type === "push" ? /* @__PURE__ */ jsx93(DynamicFlow, __spreadProps(__spreadValues(__spreadValues({}, restProps), rest), { features: subflowFeatures, initialAction: action })) : /* @__PURE__ */ jsx93(
4475
- DynamicFlowModal,
4476
- __spreadProps(__spreadValues(__spreadValues({}, restProps), rest), {
4477
- features: subflowFeatures,
4478
- initialAction: action
4479
- })
4480
- );
4481
- }
4482
- });
4483
- const loadingStateRenderer = ((_d = props.features) == null ? void 0 : _d.initialLoader) ? [InitialLoadingStateRenderer] : [];
4484
- return [...(_e = props.renderers) != null ? _e : [], subflowRenderer, ...loadingStateRenderer, ...wiseRenderers];
4532
+ // src/dynamicFlow/useCreateSnackBar.tsx
4533
+ var useCreateSnackBar = () => {
4534
+ const createSnackBar = useSnackBarIfAvailable();
4535
+ return createSnackBar;
4485
4536
  };
4486
4537
 
4487
4538
  // src/dynamicFlow/useWiseToCoreProps.tsx
@@ -4494,10 +4545,12 @@ var useWiseToCoreProps = (props) => {
4494
4545
  onAnalytics,
4495
4546
  onEvent,
4496
4547
  onLink = openLinkInNewTab,
4548
+ onNotification,
4497
4549
  onLog
4498
4550
  } = props;
4499
4551
  const httpClient = useWiseHttpClient(customFetch);
4500
4552
  const mergedRenderers = useMemo2(() => getMergedRenderers(props), [renderers]);
4553
+ const createSnackBar = useCreateSnackBar();
4501
4554
  const logEvent = useMemo2(() => getLogEvent(onLog), [onLog]);
4502
4555
  const trackEvent = useMemo2(() => getTrackEvent(onEvent, onAnalytics), [onEvent, onAnalytics]);
4503
4556
  const onCopy = useOnCopy();
@@ -4508,6 +4561,7 @@ var useWiseToCoreProps = (props) => {
4508
4561
  onEvent: trackEvent,
4509
4562
  onLog: logEvent,
4510
4563
  onCopy,
4564
+ onNotification: onNotification != null ? onNotification : createSnackBar,
4511
4565
  onLink
4512
4566
  });
4513
4567
  };
@@ -5350,7 +5404,7 @@ var zh_CN_default = {
5350
5404
  "df.wise.ControlFeedback.required": "\u8BF7\u586B\u5199\u6B64\u5B57\u6BB5\u3002",
5351
5405
  "df.wise.ControlFeedback.type": "\u7C7B\u578B\u9519\u8BEF",
5352
5406
  "df.wise.CopyFeedback.copy": "\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F",
5353
- "df.wise.CopyFeedback.copyFailed": "\u590D\u5236\u5230\u526A\u8D34\u677F\u5931\u8D25",
5407
+ "df.wise.CopyFeedback.copyFailed": "\u65E0\u6CD5\u590D\u5236\u5230\u526A\u8D34\u677F",
5354
5408
  "df.wise.DynamicParagraph.copied": "\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F",
5355
5409
  "df.wise.DynamicParagraph.copy": "\u590D\u5236",
5356
5410
  "df.wise.ErrorBoundary.errorAlert": "\u51FA\u9519\u4E86\u3002",
@@ -5365,7 +5419,7 @@ var zh_CN_default = {
5365
5419
  "df.wise.MultipleFileUploadSchema.maxItemsError": "\u8BF7\u4E0A\u4F20\u4E0D\u8D85\u8FC7 {maxItems} \u4E2A\u6587\u4EF6\u3002",
5366
5420
  "df.wise.MultipleFileUploadSchema.minItemsError": "\u8BF7\u4E0A\u4F20\u81F3\u5C11 {minItems} \u4E2A\u6587\u4EF6\u3002",
5367
5421
  "df.wise.PersistAsyncSchema.genericError": "\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5\u3002",
5368
- "df.wise.SearchLayout.loading": "\u6B63\u5728\u52A0\u8F7D\u2026",
5422
+ "df.wise.SearchLayout.loading": "\u6B63\u5728\u52A0\u8F7D\u2026\u2026",
5369
5423
  "df.wise.back.label": "\u8FD4\u56DE",
5370
5424
  "df.wise.filter.noResults": "\u6682\u65E0\u7ED3\u679C",
5371
5425
  "df.wise.filter.placeholder": "\u5F00\u59CB\u8F93\u5165\u4EE5\u641C\u7D22",