@wise/dynamic-flow-client-internal 4.27.0-experimental-renderer-utils-876fd4f → 4.27.0-experimental-f4fee36

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
@@ -17,16 +17,3488 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
32
+
33
+ // src/index.ts
34
+ import { makeHttpClient } from "@wise/dynamic-flow-client";
35
+ import { findRendererPropsByType, isValidSchema, JsonSchemaForm } from "@wise/dynamic-flow-client";
36
+
37
+ // ../renderers/src/AlertRenderer.tsx
38
+ import { Alert } from "@transferwise/components";
39
+
40
+ // ../renderers/src/utils/layout-utils.ts
41
+ var getMargin = (size) => {
42
+ switch (size) {
43
+ case "xs":
44
+ return "m-b-0";
45
+ case "sm":
46
+ return "m-b-1";
47
+ case "md":
48
+ return "m-b-2";
49
+ case "lg":
50
+ return "m-b-3";
51
+ case "xl":
52
+ return "m-b-5";
53
+ default:
54
+ return "";
55
+ }
56
+ };
57
+ var getTextAlignment = (align) => {
58
+ switch (align) {
59
+ case "end":
60
+ return "text-xs-right";
61
+ case "center":
62
+ return "text-xs-center";
63
+ case "start":
64
+ default:
65
+ return "";
66
+ }
67
+ };
68
+ var getTextAlignmentAndMargin = (component) => `${getTextAlignment(component.align)} ${getMargin(component.margin)}`;
69
+
70
+ // ../renderers/src/AlertRenderer.tsx
71
+ import { jsx } from "react/jsx-runtime";
72
+ var AlertRenderer = {
73
+ canRenderType: "alert",
74
+ render: ({ context, markdown, margin, callToAction }) => /* @__PURE__ */ jsx(
75
+ Alert,
76
+ {
77
+ type: context,
78
+ className: getMargin(margin),
79
+ message: markdown,
80
+ action: mapCtaToAlertAction(callToAction)
81
+ }
82
+ )
83
+ };
84
+ var mapCtaToAlertAction = (callToAction) => {
85
+ if (callToAction) {
86
+ return __spreadValues(__spreadValues({
87
+ text: callToAction.title,
88
+ "aria-label": callToAction.accessibilityDescription
89
+ }, "onClick" in callToAction ? { onClick: callToAction.onClick } : {}), callToAction.type === "link" ? { href: callToAction.href, target: "_blank" } : {});
90
+ }
91
+ return void 0;
92
+ };
93
+ var AlertRenderer_default = AlertRenderer;
94
+
95
+ // ../renderers/src/BoxRenderer.tsx
96
+ import classNames from "classnames";
97
+ import { jsx as jsx2 } from "react/jsx-runtime";
98
+ var BoxRenderer = {
99
+ canRenderType: "box",
100
+ render: ({ children, control, margin, width }) => {
101
+ const hasFixedWidth = width !== "xl";
102
+ const hasBorder = control === "bordered" || control === "bordered-web";
103
+ const contents = /* @__PURE__ */ jsx2(
104
+ "div",
105
+ {
106
+ className: classNames({
107
+ "df-box-renderer-border": hasBorder,
108
+ [`df-box-renderer-width-${width}`]: hasFixedWidth,
109
+ [getMargin(margin)]: !hasFixedWidth
110
+ }),
111
+ children
112
+ }
113
+ );
114
+ return hasFixedWidth ? /* @__PURE__ */ jsx2("div", { className: classNames("df-box-renderer-fixed-width", getMargin(margin)), children: contents }) : contents;
115
+ }
116
+ };
117
+ var BoxRenderer_default = BoxRenderer;
118
+
119
+ // ../renderers/src/ButtonRenderer/AddressValidationButtonRenderer.tsx
120
+ import { Button, InlineAlert } from "@transferwise/components";
121
+ import { useIntl } from "react-intl";
122
+
123
+ // ../renderers/src/messages/loading-button.messages.ts
124
+ import { defineMessages } from "react-intl";
125
+ var loading_button_messages_default = defineMessages({
126
+ buttonLoadingMessage: {
127
+ id: "df.wise.ButtonLayout.buttonLoadingMessage",
128
+ defaultMessage: "This might take a few seconds",
129
+ description: "Message displayed below a button when it is in a loading state."
130
+ }
131
+ });
132
+
133
+ // ../renderers/src/ButtonRenderer/AddressValidationButtonRenderer.tsx
134
+ import { useEffect, useState } from "react";
135
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
136
+ var AddressValidationButtonRenderer = {
137
+ canRenderType: "button",
138
+ canRender: ({ control }) => control === "address-validation",
139
+ render: AddressValidationButtonComponent
140
+ };
141
+ function AddressValidationButtonComponent(props) {
142
+ const { disabled, margin, title, stepLoadingState, onClick } = props;
143
+ const { formatMessage } = useIntl();
144
+ const [spinny, setSpinny] = useState(false);
145
+ useEffect(() => {
146
+ if (stepLoadingState === "idle") {
147
+ setSpinny(false);
148
+ }
149
+ }, [stepLoadingState]);
150
+ return /* @__PURE__ */ jsxs("div", { className: `d-flex flex-column ${getMargin(margin)}`, children: [
151
+ /* @__PURE__ */ jsx3(
152
+ Button,
153
+ {
154
+ v2: true,
155
+ block: true,
156
+ disabled,
157
+ priority: "primary",
158
+ size: "md",
159
+ loading: spinny,
160
+ onClick: () => {
161
+ setSpinny(true);
162
+ onClick();
163
+ },
164
+ children: title
165
+ }
166
+ ),
167
+ spinny && /* @__PURE__ */ jsx3(InlineAlert, { type: "warning", className: "m-x-auto", children: formatMessage(loading_button_messages_default.buttonLoadingMessage) })
168
+ ] });
169
+ }
170
+ var AddressValidationButtonRenderer_default = AddressValidationButtonRenderer;
171
+
172
+ // ../renderers/src/ButtonRenderer/ButtonRenderer.tsx
173
+ import { Button as Button2 } from "@transferwise/components";
174
+ import { useEffect as useEffect2, useState as useState2 } from "react";
175
+
176
+ // ../renderers/src/ButtonRenderer/mapButtonSize.tsx
177
+ var mapButtonSize = (size) => {
178
+ if (!size) {
179
+ return void 0;
180
+ }
181
+ switch (size) {
182
+ case "xs":
183
+ case "sm":
184
+ return "sm";
185
+ case "lg":
186
+ case "xl":
187
+ return "lg";
188
+ case "md":
189
+ default:
190
+ return "md";
191
+ }
192
+ };
193
+
194
+ // ../renderers/src/ButtonRenderer/ButtonRenderer.tsx
195
+ import { jsx as jsx4 } from "react/jsx-runtime";
196
+ var ButtonRenderer = {
197
+ canRenderType: "button",
198
+ render: ButtonComponent
199
+ };
200
+ function ButtonComponent(props) {
201
+ const { control, context, disabled, margin, title, size, stepLoadingState, onClick } = props;
202
+ const [spinny, setSpinny] = useState2(false);
203
+ useEffect2(() => {
204
+ if (stepLoadingState === "idle") {
205
+ setSpinny(false);
206
+ }
207
+ }, [stepLoadingState]);
208
+ const priority = getPriority(control);
209
+ const type = getButtonType(context, priority);
210
+ const loading = spinny && stepLoadingState !== "idle";
211
+ return /* @__PURE__ */ jsx4(
212
+ Button2,
213
+ {
214
+ block: true,
215
+ className: getMargin(margin),
216
+ disabled,
217
+ priority,
218
+ size: mapButtonSize(size),
219
+ loading,
220
+ type,
221
+ onClick: () => {
222
+ setSpinny(true);
223
+ onClick();
224
+ },
225
+ children: title
226
+ }
227
+ );
228
+ }
229
+ var getPriority = (control) => {
230
+ switch (control) {
231
+ case "primary":
232
+ case "tertiary":
233
+ return control;
234
+ default:
235
+ return "secondary";
236
+ }
237
+ };
238
+ var getButtonType = (context, priority) => {
239
+ if (priority === "tertiary") {
240
+ return void 0;
241
+ }
242
+ switch (context) {
243
+ case "neutral":
244
+ case "warning":
245
+ return "accent";
246
+ default:
247
+ return context;
248
+ }
249
+ };
250
+
251
+ // ../renderers/src/components/FieldInput.tsx
252
+ import { Field } from "@transferwise/components";
253
+
254
+ // ../renderers/src/components/Help.tsx
255
+ import { Info, Markdown } from "@transferwise/components";
256
+ import { useIntl as useIntl2 } from "react-intl";
257
+
258
+ // ../renderers/src/messages/help.messages.ts
259
+ import { defineMessages as defineMessages2 } from "react-intl";
260
+ var help_messages_default = defineMessages2({
261
+ helpAria: {
262
+ id: "df.wise.Help.ariaLabel",
263
+ defaultMessage: "Click here for more info.",
264
+ description: "Aria label for help."
265
+ }
266
+ });
267
+
268
+ // ../renderers/src/components/Help.tsx
269
+ import { jsx as jsx5 } from "react/jsx-runtime";
270
+ function Help({ help, onClick }) {
271
+ const intl = useIntl2();
272
+ return /* @__PURE__ */ jsx5(
273
+ Info,
274
+ {
275
+ content: /* @__PURE__ */ jsx5(Markdown, { config: { link: { target: "_blank" } }, children: help }),
276
+ presentation: "POPOVER",
277
+ size: "sm",
278
+ "aria-label": intl.formatMessage(help_messages_default.helpAria),
279
+ onClick
280
+ }
281
+ );
282
+ }
283
+ var Help_default = Help;
284
+
285
+ // ../renderers/src/components/LabelContentWithHelp.tsx
286
+ import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
287
+ function LabelContentWithHelp({ text, help }) {
288
+ return /* @__PURE__ */ jsxs2("div", { children: [
289
+ text,
290
+ /* @__PURE__ */ jsx6(Help_default, { help })
291
+ ] });
292
+ }
293
+
294
+ // ../renderers/src/components/FieldInput.tsx
295
+ import { jsx as jsx7 } from "react/jsx-runtime";
296
+ function FieldInput({ id, children, label, validation, description, help }) {
297
+ const labelContent = label && help ? /* @__PURE__ */ jsx7(LabelContentWithHelp, { text: label, help }) : label;
298
+ return /* @__PURE__ */ jsx7(
299
+ Field,
300
+ {
301
+ id,
302
+ label: labelContent,
303
+ description,
304
+ message: validation == null ? void 0 : validation.message,
305
+ sentiment: mapStatusToSentiment(validation),
306
+ children
307
+ }
308
+ );
309
+ }
310
+ var mapStatusToSentiment = (validation) => {
311
+ if (validation) {
312
+ if (validation.status === "valid") {
313
+ return "positive";
314
+ }
315
+ return "negative";
316
+ }
317
+ return void 0;
318
+ };
319
+ var FieldInput_default = FieldInput;
320
+
321
+ // ../renderers/src/CheckboxInputRenderer.tsx
322
+ import { Checkbox, ListItem } from "@transferwise/components";
323
+
324
+ // ../renderers/src/utils/UrnFlag.tsx
325
+ import { Flag } from "@wise/art";
326
+ import { jsx as jsx8 } from "react/jsx-runtime";
327
+ var countryUrnPrefix = "urn:wise:countries:";
328
+ var currencyUrnPrefix = "urn:wise:currencies:";
329
+ var isUrnFlag = (uri) => uri.startsWith(countryUrnPrefix) || uri.startsWith(currencyUrnPrefix);
330
+ function UrnFlag({ size, urn }) {
331
+ return /* @__PURE__ */ jsx8(Flag, { code: getCode(urn), intrinsicSize: size });
332
+ }
333
+ var getCode = (urn) => {
334
+ return urn.replace(countryUrnPrefix, "").replace(currencyUrnPrefix, "").replace(":image", "").split("?")[0];
335
+ };
336
+
337
+ // ../renderers/src/components/icon/FlagIcon.tsx
338
+ import { Flag as Flag2 } from "@wise/art";
339
+ import { jsx as jsx9 } from "react/jsx-runtime";
340
+ var isFlagIcon = (name) => name.startsWith("flag-");
341
+ function FlagIcon({ name }) {
342
+ if (!isFlagIcon(name)) {
343
+ return null;
344
+ }
345
+ const code = name.substring(5);
346
+ return /* @__PURE__ */ jsx9(Flag2, { code, intrinsicSize: 24 });
347
+ }
348
+
349
+ // ../renderers/src/components/icon/NamedIcon.tsx
350
+ import * as icons from "@transferwise/icons";
351
+ import { jsx as jsx10 } from "react/jsx-runtime";
352
+ var isNamedIcon = (name) => {
353
+ const iconName = toCapitalisedCamelCase(name);
354
+ return Object.keys(icons).includes(iconName);
355
+ };
356
+ function NamedIcon({ name }) {
357
+ if (!isNamedIcon(name)) {
358
+ return null;
359
+ }
360
+ const iconName = toCapitalisedCamelCase(name);
361
+ const Icon = icons[iconName];
362
+ return /* @__PURE__ */ jsx10(Icon, { size: 24 });
363
+ }
364
+ var toCapitalisedCamelCase = (value) => value.split("-").map(capitaliseFirstChar).join("");
365
+ var capitaliseFirstChar = (value) => `${value[0].toUpperCase()}${value.slice(1)}`;
366
+
367
+ // ../renderers/src/components/icon/DynamicIcon.tsx
368
+ import { jsx as jsx11 } from "react/jsx-runtime";
369
+ function DynamicIcon({ name }) {
370
+ if (isFlagIcon(name)) {
371
+ return /* @__PURE__ */ jsx11(FlagIcon, { name });
372
+ }
373
+ if (isNamedIcon(name)) {
374
+ return /* @__PURE__ */ jsx11(NamedIcon, { name });
375
+ }
376
+ return null;
377
+ }
378
+ function isValidIconName(name) {
379
+ return isNamedIcon(name) || isFlagIcon(name);
380
+ }
381
+ function isValidIconUrn(uri) {
382
+ if (!uri.startsWith("urn:wise:icons:")) {
383
+ return false;
384
+ }
385
+ const name = uri.replace("urn:wise:icons:", "").split("?")[0];
386
+ return isValidIconName(name);
387
+ }
388
+ var DynamicIcon_default = DynamicIcon;
389
+
390
+ // ../renderers/src/components/Media/stringToURN.ts
391
+ var stringToURN = (uri) => {
392
+ var _a, _b, _c;
393
+ const [nameWithRQComponents, _] = uri.split("#");
394
+ const [nameWithRComponent, qComponent] = nameWithRQComponents.split("?=");
395
+ const [name, rComponent] = (_a = nameWithRComponent == null ? void 0 : nameWithRComponent.split("?+")) != null ? _a : ["", ""];
396
+ const rComponents = rComponent ? (_b = decodeURIComponent(rComponent)) == null ? void 0 : _b.split("&").map((c) => c.split("=")).map(([a, b]) => [a, b]) : void 0;
397
+ const qComponents = qComponent ? (_c = decodeURIComponent(qComponent)) == null ? void 0 : _c.split("&").map((c) => c.split("=")).map(([a, b]) => [a, b]) : void 0;
398
+ return {
399
+ name,
400
+ rComponents,
401
+ qComponents
402
+ };
403
+ };
404
+
405
+ // ../renderers/src/components/Media/resolveMediaFromUri.tsx
406
+ import { jsx as jsx12 } from "react/jsx-runtime";
407
+ var resolveMediaFromUri = (uri, size) => {
408
+ var _a, _b;
409
+ const { name, qComponents = [] } = stringToURN(uri);
410
+ if (isValidIconUrn(name)) {
411
+ const icon = /* @__PURE__ */ jsx12(DynamicIcon_default, { name: name.replace("urn:wise:icons:", "") });
412
+ return {
413
+ icon,
414
+ backgroundColor: formatColor((_a = qComponents.find(([key]) => key === "background-color")) == null ? void 0 : _a[1])
415
+ };
416
+ }
417
+ if (isUrnFlag(name)) {
418
+ return {
419
+ asset: /* @__PURE__ */ jsx12(UrnFlag, { urn: name, size })
420
+ };
421
+ }
422
+ if (name.startsWith("data:text/plain,")) {
423
+ const text = decodeURI(name.replace("data:text/plain,", ""));
424
+ return {
425
+ asset: text,
426
+ backgroundColor: formatColor((_b = qComponents.find(([key]) => key === "background-color")) == null ? void 0 : _b[1])
427
+ };
428
+ }
429
+ if (!uri.startsWith("urn:")) {
430
+ return { asset: /* @__PURE__ */ jsx12("img", { src: uri, alt: "", width: `${size}px` }) };
431
+ }
432
+ return { asset: void 0 };
433
+ };
434
+ var formatColor = (color) => {
435
+ if (!color) {
436
+ return void 0;
437
+ }
438
+ if (color.startsWith("#")) {
439
+ return color;
440
+ }
441
+ return `var(--color-${color.replace(/^base-|brand-/, "")})`;
442
+ };
443
+
444
+ // ../renderers/src/components/Media/AvatarMedia.tsx
445
+ import { AvatarLayout, AvatarView } from "@transferwise/components";
446
+ import { jsx as jsx13 } from "react/jsx-runtime";
447
+ var AvatarMedia = ({
448
+ accessibilityDescription,
449
+ content,
450
+ size
451
+ }) => {
452
+ const getRenderableAvatar = (avatar) => {
453
+ if (avatar.type === "text") {
454
+ return { asset: avatar.text };
455
+ }
456
+ return __spreadProps(__spreadValues({}, resolveMediaFromUri(avatar.uri, size)), {
457
+ badge: avatar.badgeUri ? resolveMediaFromUri(avatar.badgeUri, 16) : void 0
458
+ });
459
+ };
460
+ const avatars = content.map(getRenderableAvatar);
461
+ if (avatars.length === 1) {
462
+ const { badge, backgroundColor, asset, icon } = avatars[0];
463
+ if (!asset && !icon) {
464
+ return null;
465
+ }
466
+ return /* @__PURE__ */ jsx13(
467
+ AvatarView,
468
+ {
469
+ "aria-label": accessibilityDescription,
470
+ size,
471
+ badge: badge ? __spreadProps(__spreadValues({}, badge), {
472
+ type: "reference"
473
+ }) : void 0,
474
+ style: { backgroundColor },
475
+ children: icon != null ? icon : asset
476
+ }
477
+ );
478
+ }
479
+ const avatarsWithoutBadges = avatars.filter(({ asset }) => asset).slice(0, 2).map((_a) => {
480
+ var _b = _a, { badge } = _b, rest = __objRest(_b, ["badge"]);
481
+ return __spreadValues({}, rest);
482
+ });
483
+ return /* @__PURE__ */ jsx13(
484
+ AvatarLayout,
485
+ {
486
+ "aria-label": accessibilityDescription,
487
+ size,
488
+ orientation: "diagonal",
489
+ avatars: avatarsWithoutBadges
490
+ }
491
+ );
492
+ };
493
+
494
+ // ../renderers/src/utils/image-utils.tsx
495
+ import { AvatarView as AvatarView2 } from "@transferwise/components";
496
+ import { jsx as jsx14 } from "react/jsx-runtime";
497
+ var getBadgedMedia = (iconNode, imageNode, size) => {
498
+ if (iconNode && imageNode) {
499
+ if (imageNode && iconNode) {
500
+ return /* @__PURE__ */ jsx14(AvatarView2, { size, badge: { asset: iconNode, type: "reference" }, children: imageNode });
501
+ }
502
+ }
503
+ return null;
504
+ };
505
+ var getIconNode = (icon) => {
506
+ if (icon) {
507
+ if ("name" in icon) {
508
+ return /* @__PURE__ */ jsx14(DynamicIcon_default, { name: icon.name });
509
+ }
510
+ if (icon.text) {
511
+ return icon.text;
512
+ }
513
+ }
514
+ return null;
515
+ };
516
+ var getImageNode = (image, size) => {
517
+ if (image) {
518
+ const { accessibilityDescription, uri } = image;
519
+ if (!uri.startsWith("urn:")) {
520
+ return /* @__PURE__ */ jsx14("img", { src: uri, alt: accessibilityDescription, width: `${size}px` });
521
+ }
522
+ if (isUrnFlag(uri)) {
523
+ return /* @__PURE__ */ jsx14(UrnFlag, { urn: uri, accessibilityDescription, size });
524
+ }
525
+ }
526
+ return null;
527
+ };
528
+
529
+ // ../renderers/src/components/Media/LegacyMedia.tsx
530
+ import { AvatarView as AvatarView3 } from "@transferwise/components";
531
+ import { jsx as jsx15 } from "react/jsx-runtime";
532
+ var LegacyMedia = ({ image, icon, preferAvatar, size }) => {
533
+ const imageNode = getImageNode(image, size);
534
+ const iconNode = getIconNode(icon);
535
+ const badge = getBadgedMedia(iconNode, imageNode, size);
536
+ if (badge) {
537
+ return badge;
538
+ }
539
+ if (imageNode) {
540
+ return preferAvatar ? /* @__PURE__ */ jsx15(AvatarView3, { children: imageNode }) : imageNode;
541
+ }
542
+ if (iconNode && icon) {
543
+ if ("text" in icon || size === 48) {
544
+ return /* @__PURE__ */ jsx15(AvatarView3, { size, children: iconNode });
545
+ }
546
+ return iconNode;
547
+ }
548
+ return null;
549
+ };
550
+
551
+ // ../renderers/src/components/Media/Media.tsx
552
+ import { jsx as jsx16 } from "react/jsx-runtime";
553
+ var Media = ({ media, preferAvatar, size }) => {
554
+ switch (media == null ? void 0 : media.type) {
555
+ case "avatar":
556
+ return /* @__PURE__ */ jsx16(AvatarMedia, __spreadProps(__spreadValues({}, media), { size }));
557
+ case "image": {
558
+ const { asset, icon } = resolveMediaFromUri(media.uri, size);
559
+ return icon != null ? icon : asset;
560
+ }
561
+ case "legacy": {
562
+ return /* @__PURE__ */ jsx16(LegacyMedia, __spreadProps(__spreadValues({}, media), { preferAvatar, size }));
563
+ }
564
+ default:
565
+ return null;
566
+ }
567
+ };
568
+
569
+ // ../renderers/src/components/Media/OptionMedia.tsx
570
+ import { jsx as jsx17 } from "react/jsx-runtime";
571
+ var mediaSize = 48;
572
+ function OptionMedia(props) {
573
+ return /* @__PURE__ */ jsx17(Media, __spreadProps(__spreadValues({}, props), { size: mediaSize }));
574
+ }
575
+
576
+ // ../renderers/src/components/Media/getInlineMedia.tsx
577
+ import { jsx as jsx18 } from "react/jsx-runtime";
578
+ var getInlineMedia = (media) => media ? /* @__PURE__ */ jsx18(Media, { media, preferAvatar: false, size: 24 }) : null;
579
+
580
+ // ../renderers/src/NewListItem/getMedia.tsx
581
+ import { jsx as jsx19 } from "react/jsx-runtime";
582
+ var getMedia = (media, preferAvatar) => media ? /* @__PURE__ */ jsx19(OptionMedia, { media, preferAvatar }) : void 0;
583
+
584
+ // ../renderers/src/CheckboxInputRenderer.tsx
585
+ import { jsx as jsx20 } from "react/jsx-runtime";
586
+ var CheckboxInputRenderer = {
587
+ canRenderType: "input-checkbox",
588
+ render: (props) => props.control === "switch-item" ? /* @__PURE__ */ jsx20(SwitchComponent, __spreadValues({}, props)) : /* @__PURE__ */ jsx20(CheckboxComponent, __spreadValues({}, props))
589
+ };
590
+ var CheckboxComponent = (props) => {
591
+ const _a = props, {
592
+ id,
593
+ control,
594
+ title = "",
595
+ description,
596
+ help,
597
+ type,
598
+ validationState,
599
+ value
600
+ } = _a, rest = __objRest(_a, [
601
+ "id",
602
+ "control",
603
+ "title",
604
+ "description",
605
+ "help",
606
+ "type",
607
+ "validationState",
608
+ "value"
609
+ ]);
610
+ const checkboxProps = __spreadProps(__spreadValues({}, rest), { label: title, secondary: description, checked: value });
611
+ return /* @__PURE__ */ jsx20(FieldInput_default, { id, label: "", description: "", validation: validationState, help, children: /* @__PURE__ */ jsx20(Checkbox, __spreadValues({ id }, checkboxProps)) });
612
+ };
613
+ var SwitchComponent = (props) => {
614
+ const { title, description, disabled, media, validationState, value, onChange } = props;
615
+ return /* @__PURE__ */ jsx20(
616
+ ListItem,
617
+ {
618
+ title,
619
+ subtitle: description,
620
+ media: getMedia(media, false),
621
+ disabled,
622
+ prompt: validationState && validationState.status === "invalid" ? /* @__PURE__ */ jsx20(ListItem.Prompt, { sentiment: "negative", children: validationState.message }) : void 0,
623
+ control: /* @__PURE__ */ jsx20(ListItem.Switch, { checked: value, onClick: () => onChange(!value) })
624
+ }
625
+ );
626
+ };
627
+ var CheckboxInputRenderer_default = CheckboxInputRenderer;
628
+
629
+ // ../renderers/src/ColumnsRenderer.tsx
630
+ import classNames2 from "classnames";
631
+ import { jsx as jsx21, jsxs as jsxs3 } from "react/jsx-runtime";
632
+ var ColumnsRenderer = {
633
+ canRenderType: "columns",
634
+ render: ({ bias, margin, startChildren, endChildren }) => /* @__PURE__ */ jsxs3(
635
+ "div",
636
+ {
637
+ className: classNames2("df-columns-renderer-container", getMargin(margin), {
638
+ "df-columns-renderer-bias-start": bias === "start",
639
+ "df-columns-renderer-bias-end": bias === "end"
640
+ }),
641
+ children: [
642
+ /* @__PURE__ */ jsx21("div", { className: "df-columns-renderer-column", children: startChildren }),
643
+ /* @__PURE__ */ jsx21("div", { className: "df-columns-renderer-column", children: endChildren })
644
+ ]
645
+ }
646
+ )
647
+ };
648
+ var ColumnsRenderer_default = ColumnsRenderer;
649
+
650
+ // ../renderers/src/components/VariableDateInput.tsx
651
+ import { DateInput, DateLookup } from "@transferwise/components";
652
+
653
+ // ../renderers/src/validators/type-validators.ts
654
+ var isNumber = (value) => typeof value === "number" && !Number.isNaN(value);
655
+
656
+ // ../renderers/src/utils/value-utils.ts
657
+ var dateStringToDateOrNull = (dateString) => {
658
+ if (!dateString) {
659
+ return null;
660
+ }
661
+ const [year, month, date] = dateString.split("-").map((number) => Number.parseInt(number, 10));
662
+ if (!isNumber(year) || !isNumber(month) || !isNumber(date)) {
663
+ return null;
664
+ }
665
+ return new Date(year, month - 1, date);
666
+ };
667
+ var dateToDateString = (date) => {
668
+ const d = new Date(date);
669
+ const month = String(d.getMonth() + 1);
670
+ const day = String(d.getDate());
671
+ const year = d.getFullYear();
672
+ const formattedMonth = month.length < 2 ? `0${month}` : month;
673
+ const formattedDay = day.length < 2 ? `0${day}` : day;
674
+ return [year, formattedMonth, formattedDay].join("-");
675
+ };
676
+
677
+ // ../renderers/src/components/VariableDateInput.tsx
678
+ import { jsx as jsx22 } from "react/jsx-runtime";
679
+ function VariableDateInput({
680
+ control,
681
+ inputProps
682
+ }) {
683
+ const {
684
+ autoComplete,
685
+ minimumDate,
686
+ maximumDate,
687
+ placeholder,
688
+ disabled,
689
+ onBlur,
690
+ onChange,
691
+ onFocus
692
+ } = inputProps;
693
+ if (control === "date-lookup") {
694
+ return /* @__PURE__ */ jsx22(
695
+ DateLookup,
696
+ {
697
+ value: dateStringToDateOrNull(inputProps.value),
698
+ min: dateStringToDateOrNull(minimumDate),
699
+ max: dateStringToDateOrNull(maximumDate),
700
+ placeholder,
701
+ disabled,
702
+ onChange: (date) => {
703
+ onChange(date !== null ? dateToDateString(date) : null);
704
+ },
705
+ onBlur,
706
+ onFocus
707
+ }
708
+ );
709
+ }
710
+ return /* @__PURE__ */ jsx22(
711
+ DateInput,
712
+ __spreadProps(__spreadValues({}, inputProps), {
713
+ dayAutoComplete: getAutocompleteString(autoComplete, "day"),
714
+ yearAutoComplete: getAutocompleteString(autoComplete, "year")
715
+ })
716
+ );
717
+ }
718
+ var getAutocompleteString = (value, suffix) => {
719
+ if (value === "bday") {
720
+ return `${value}-${suffix}`;
721
+ }
722
+ return void 0;
723
+ };
724
+ var VariableDateInput_default = VariableDateInput;
725
+
726
+ // ../renderers/src/DateInputRenderer.tsx
727
+ import { jsx as jsx23 } from "react/jsx-runtime";
728
+ var DateInputRenderer = {
729
+ canRenderType: "input-date",
730
+ render: (props) => {
731
+ const _a = props, {
732
+ id,
733
+ control,
734
+ description,
735
+ type,
736
+ help,
737
+ title,
738
+ validationState,
739
+ value: initialValue
740
+ } = _a, rest = __objRest(_a, [
741
+ "id",
742
+ "control",
743
+ "description",
744
+ "type",
745
+ "help",
746
+ "title",
747
+ "validationState",
748
+ "value"
749
+ ]);
750
+ const value = initialValue != null ? initialValue : "";
751
+ const inputProps = __spreadProps(__spreadValues({}, rest), { value, id });
752
+ return /* @__PURE__ */ jsx23(
753
+ FieldInput_default,
754
+ {
755
+ id,
756
+ label: title,
757
+ description,
758
+ validation: validationState,
759
+ help,
760
+ children: /* @__PURE__ */ jsx23(VariableDateInput_default, { control, inputProps })
761
+ }
762
+ );
763
+ }
764
+ };
765
+ var DateInputRenderer_default = DateInputRenderer;
766
+
767
+ // ../renderers/src/DecisionRenderer/DecisionRenderer.tsx
768
+ import { NavigationOption, NavigationOptionsList } from "@transferwise/components";
769
+
770
+ // ../renderers/src/DecisionRenderer/DecisionList.tsx
771
+ import { Header as Header2, SearchInput } from "@transferwise/components";
772
+
773
+ // ../renderers/src/DecisionRenderer/GroupedList.tsx
774
+ import { Header, Section } from "@transferwise/components";
775
+ import { useIntl as useIntl3 } from "react-intl";
776
+
777
+ // ../renderers/src/messages/decision.messages.ts
778
+ import { defineMessages as defineMessages3 } from "react-intl";
779
+ var decision_messages_default = defineMessages3({
780
+ all: {
781
+ id: "df.wise.Decision.all",
782
+ defaultMessage: "All",
783
+ description: "Label for the group of options that encompasses all options"
784
+ },
785
+ popular: {
786
+ id: "df.wise.Decision.popular",
787
+ defaultMessage: "Popular",
788
+ description: "Label for the group of options that are tagged as popular"
789
+ },
790
+ recent: {
791
+ id: "df.wise.Decision.recent",
792
+ defaultMessage: "Recent",
793
+ description: "Label for the group of options that are tagged as recent"
794
+ },
795
+ currenciesWithAccountDetails: {
796
+ id: "df.wise.Decision.currenciesWithAccountDetails",
797
+ defaultMessage: "Currencies with account details",
798
+ description: "Label for the group of options that are tagged as currencies with account details"
799
+ },
800
+ filterPlaceholder: {
801
+ id: "df.wise.Decision.filterPlaceholder",
802
+ defaultMessage: "Start typing to search",
803
+ description: "Placeholder for the filter input"
804
+ },
805
+ results: {
806
+ id: "df.wise.Decision.results",
807
+ defaultMessage: "Search results",
808
+ description: "Label for the results section"
809
+ },
810
+ noResults: {
811
+ id: "df.wise.Decision.noResults",
812
+ defaultMessage: "No results",
813
+ description: "Message for if there are no results"
814
+ }
815
+ });
816
+
817
+ // ../renderers/src/DecisionRenderer/GroupedList.tsx
818
+ import { Fragment, jsx as jsx24, jsxs as jsxs4 } from "react/jsx-runtime";
819
+ var OPTION_GROUPS = {
820
+ popular: "popular",
821
+ recent: "recent",
822
+ currencyWithAccountDetails: "currencies-with-account-details"
823
+ };
824
+ var GroupedList = (_a) => {
825
+ var _b = _a, { renderDecisionList: renderDecisionList3 } = _b, rest = __objRest(_b, ["renderDecisionList"]);
826
+ const { formatMessage } = useIntl3();
827
+ const { options } = rest;
828
+ const popularOptions = options.filter((option) => option.tag === OPTION_GROUPS.popular);
829
+ const recentOptions = options.filter((option) => option.tag === OPTION_GROUPS.recent);
830
+ const currencyWithAccountDetailsOptions = options.filter(
831
+ (option) => option.tag === OPTION_GROUPS.currencyWithAccountDetails
832
+ );
833
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
834
+ popularOptions.length > 0 ? /* @__PURE__ */ jsxs4(Section, { children: [
835
+ /* @__PURE__ */ jsx24(Header, { as: "h2", title: formatMessage(decision_messages_default.popular) }),
836
+ renderDecisionList3(__spreadProps(__spreadValues({}, rest), { options: popularOptions }))
837
+ ] }) : null,
838
+ recentOptions.length > 0 ? /* @__PURE__ */ jsxs4(Section, { children: [
839
+ /* @__PURE__ */ jsx24(Header, { as: "h2", title: formatMessage(decision_messages_default.recent) }),
840
+ renderDecisionList3(__spreadProps(__spreadValues({}, rest), { options: recentOptions }))
841
+ ] }) : null,
842
+ currencyWithAccountDetailsOptions.length > 0 ? /* @__PURE__ */ jsxs4(Section, { children: [
843
+ /* @__PURE__ */ jsx24(Header, { as: "h2", title: formatMessage(decision_messages_default.currenciesWithAccountDetails) }),
844
+ renderDecisionList3(__spreadProps(__spreadValues({}, rest), { options: currencyWithAccountDetailsOptions }))
845
+ ] }) : null,
846
+ /* @__PURE__ */ jsxs4(Section, { children: [
847
+ /* @__PURE__ */ jsx24(Header, { as: "h2", title: formatMessage(decision_messages_default.all) }),
848
+ renderDecisionList3(rest)
849
+ ] })
850
+ ] });
851
+ };
852
+ var isGroupedDecision = (options) => {
853
+ const possibleGroups = Object.values(OPTION_GROUPS);
854
+ return options.some(({ tag }) => tag && possibleGroups.includes(tag));
855
+ };
856
+
857
+ // ../renderers/src/DecisionRenderer/DecisionList.tsx
858
+ import { useIntl as useIntl4 } from "react-intl";
859
+ import { useState as useState3 } from "react";
860
+
861
+ // ../renderers/src/DecisionRenderer/filter-and-sort-decision-options.ts
862
+ function filterAndSortDecisionOptions(selectOptions, query) {
863
+ const upperQuery = query.toUpperCase().trim();
864
+ const filteredItems = selectOptions.filter((option) => {
865
+ var _a, _b, _c, _d;
866
+ const searchableWords = [
867
+ option.title,
868
+ option.description,
869
+ option.additionalText,
870
+ (_a = option.supportingValues) == null ? void 0 : _a.value,
871
+ (_b = option.supportingValues) == null ? void 0 : _b.subvalue,
872
+ ...(_c = option.keywords) != null ? _c : []
873
+ ];
874
+ return (_d = searchableWords.some((word) => word == null ? void 0 : word.toUpperCase().includes(upperQuery))) != null ? _d : false;
875
+ });
876
+ return [...filteredItems].sort((a, b) => {
877
+ const aTitleUpper = a.title.toUpperCase();
878
+ const bTitleUpper = b.title.toUpperCase();
879
+ const aTitleStarts = aTitleUpper.startsWith(upperQuery);
880
+ const bTitleStarts = bTitleUpper.startsWith(upperQuery);
881
+ if (aTitleStarts && !bTitleStarts) {
882
+ return -1;
883
+ }
884
+ if (!aTitleStarts && bTitleStarts) {
885
+ return 1;
886
+ }
887
+ const aWordStarts = aTitleUpper.split(" ").some((word) => word.startsWith(upperQuery));
888
+ const bWordStarts = bTitleUpper.split(" ").some((word) => word.startsWith(upperQuery));
889
+ if (aWordStarts && !bWordStarts) {
890
+ return -1;
891
+ }
892
+ if (!aWordStarts && bWordStarts) {
893
+ return 1;
894
+ }
895
+ return a.title.localeCompare(b.title);
896
+ });
897
+ }
898
+
899
+ // ../renderers/src/DecisionRenderer/DecisionList.tsx
900
+ import { Fragment as Fragment2, jsx as jsx25, jsxs as jsxs5 } from "react/jsx-runtime";
901
+ var DecisionWrapper = (props) => {
902
+ return /* @__PURE__ */ jsxs5("div", { className: getMargin(props.margin), children: [
903
+ props.title && /* @__PURE__ */ jsx25(Header2, { as: "h2", title: props.title }),
904
+ props.control === "filtered" ? /* @__PURE__ */ jsx25(FilteredDecisionList, __spreadValues({}, props)) : /* @__PURE__ */ jsx25(UnfilteredDecisionList, __spreadValues({}, props))
905
+ ] });
906
+ };
907
+ var UnfilteredDecisionList = (_a) => {
908
+ var _b = _a, { renderDecisionList: renderDecisionList3 } = _b, rest = __objRest(_b, ["renderDecisionList"]);
909
+ return isGroupedDecision(rest.options) ? /* @__PURE__ */ jsx25(GroupedList, __spreadProps(__spreadValues({}, rest), { renderDecisionList: renderDecisionList3 })) : renderDecisionList3(rest);
910
+ };
911
+ var FilteredDecisionList = (props) => {
912
+ const { formatMessage } = useIntl4();
913
+ const [query, setQuery] = useState3("");
914
+ const { control, options, renderDecisionList: renderDecisionList3 } = props;
915
+ const filteredOptions = filterAndSortDecisionOptions(options, query);
916
+ const isGrouped = isGroupedDecision(options);
917
+ return /* @__PURE__ */ jsxs5(Fragment2, { children: [
918
+ /* @__PURE__ */ jsx25(
919
+ SearchInput,
920
+ {
921
+ placeholder: formatMessage(decision_messages_default.filterPlaceholder),
922
+ value: query,
923
+ onChange: (e) => {
924
+ var _a;
925
+ return setQuery((_a = e.target.value) != null ? _a : "");
926
+ }
927
+ }
928
+ ),
929
+ isGrouped && query.length === 0 ? /* @__PURE__ */ jsx25(GroupedList, __spreadValues({}, props)) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
930
+ query.length > 0 && /* @__PURE__ */ jsx25(Header2, { as: "h2", title: formatMessage(decision_messages_default.results), className: "m-t-4" }),
931
+ filteredOptions.length > 0 ? renderDecisionList3({
932
+ control,
933
+ className: query.length === 0 ? "m-t-3" : "",
934
+ options: filteredOptions
935
+ }) : /* @__PURE__ */ jsx25("p", { children: formatMessage(decision_messages_default.noResults) })
936
+ ] })
937
+ ] });
938
+ };
939
+
940
+ // ../renderers/src/DecisionRenderer/DecisionRenderer.tsx
941
+ import { jsx as jsx26 } from "react/jsx-runtime";
942
+ var DecisionRenderer = {
943
+ canRenderType: "decision",
944
+ render: (props) => {
945
+ return /* @__PURE__ */ jsx26(DecisionWrapper, __spreadProps(__spreadValues({}, props), { renderDecisionList }));
946
+ }
947
+ };
948
+ var renderDecisionList = ({ options, className, control }) => {
949
+ return /* @__PURE__ */ jsx26("div", { className, children: /* @__PURE__ */ jsx26(NavigationOptionsList, { children: options.map((option) => {
950
+ const { description, disabled, media, title: itemTitle, tag, onClick } = option;
951
+ return /* @__PURE__ */ jsx26(
952
+ NavigationOption,
953
+ {
954
+ title: itemTitle,
955
+ content: description,
956
+ disabled,
957
+ media: media ? /* @__PURE__ */ jsx26(
958
+ OptionMedia,
959
+ {
960
+ media,
961
+ preferAvatar: control === "with-avatar" || tag === "with-avatar"
962
+ }
963
+ ) : null,
964
+ showMediaCircle: false,
965
+ showMediaAtAllSizes: true,
966
+ onClick
967
+ },
968
+ JSON.stringify(option)
969
+ );
970
+ }) }) });
971
+ };
972
+ var DecisionRenderer_default = DecisionRenderer;
973
+
974
+ // ../renderers/src/DividerRenderer.tsx
975
+ import { Divider } from "@transferwise/components";
976
+ import { jsx as jsx27 } from "react/jsx-runtime";
977
+ var mapControlToLevel = (control) => {
978
+ switch (control) {
979
+ case "section":
980
+ return "section";
981
+ case "content":
982
+ return "content";
983
+ default:
984
+ return "subsection";
985
+ }
986
+ };
987
+ var DividerRenderer = {
988
+ canRenderType: "divider",
989
+ render: ({ margin, control }) => /* @__PURE__ */ jsx27(Divider, { className: `m-t-0 d-block ${getMargin(margin)}`, level: mapControlToLevel(control) })
990
+ };
991
+ var DividerRenderer_default = DividerRenderer;
992
+
993
+ // ../renderers/src/ExternalConfirmationRenderer.tsx
994
+ import { Button as Button3, Markdown as Markdown2, Modal } from "@transferwise/components";
995
+
996
+ // ../renderers/src/messages/external-confirmation.messages.ts
997
+ import { defineMessages as defineMessages4 } from "react-intl";
998
+ var external_confirmation_messages_default = defineMessages4({
999
+ title: {
1000
+ id: "df.wise.ExternalConfirmation.title",
1001
+ defaultMessage: "Please confirm",
1002
+ description: "Heading for the confirmation screen."
1003
+ },
1004
+ description: {
1005
+ id: "df.wise.ExternalConfirmation.description",
1006
+ defaultMessage: "Please confirm you want to open **{origin}** in a new browser tab.",
1007
+ description: "Description for the confirmation screen."
1008
+ },
1009
+ open: {
1010
+ id: "df.wise.ExternalConfirmation.open",
1011
+ defaultMessage: "Open in new tab",
1012
+ description: "Button text confirming opening a new browser tab."
1013
+ },
1014
+ cancel: {
1015
+ id: "df.wise.ExternalConfirmation.cancel",
1016
+ defaultMessage: "Cancel",
1017
+ description: "Button text rejecting opening a new browser tab."
1018
+ }
1019
+ });
1020
+
1021
+ // ../renderers/src/ExternalConfirmationRenderer.tsx
1022
+ import { useIntl as useIntl5 } from "react-intl";
1023
+ import { useEffect as useEffect3 } from "react";
1024
+ import { Fragment as Fragment3, jsx as jsx28, jsxs as jsxs6 } from "react/jsx-runtime";
1025
+ var ExternalConfirmationRenderer = {
1026
+ canRenderType: "external-confirmation",
1027
+ render: ExternalConfirmationRendererComponent
1028
+ };
1029
+ function ExternalConfirmationRendererComponent({
1030
+ url,
1031
+ status,
1032
+ onSuccess,
1033
+ onFailure,
1034
+ onCancel
1035
+ }) {
1036
+ const { formatMessage } = useIntl5();
1037
+ useEffect3(() => {
1038
+ if (url) {
1039
+ const w = window.open(url, "_blank");
1040
+ if (w) {
1041
+ onSuccess();
1042
+ } else {
1043
+ onFailure();
1044
+ }
1045
+ }
1046
+ }, []);
1047
+ return /* @__PURE__ */ jsx28(
1048
+ Modal,
1049
+ {
1050
+ open: status === "failure",
1051
+ title: formatMessage(external_confirmation_messages_default.title),
1052
+ body: /* @__PURE__ */ jsxs6(Fragment3, { children: [
1053
+ /* @__PURE__ */ jsx28(Markdown2, { config: { link: { target: "_blank" } }, className: "text-xs-center m-b-5", children: formatMessage(external_confirmation_messages_default.description, { origin: getOrigin(url) }) }),
1054
+ /* @__PURE__ */ jsx28("div", { className: "df-box-renderer-fixed-width", children: /* @__PURE__ */ jsxs6("div", { className: "df-box-renderer-width-lg", children: [
1055
+ /* @__PURE__ */ jsx28(
1056
+ Button3,
1057
+ {
1058
+ v2: true,
1059
+ block: true,
1060
+ className: "m-b-2",
1061
+ priority: "primary",
1062
+ size: "md",
1063
+ onClick: () => {
1064
+ window.open(url);
1065
+ onCancel();
1066
+ },
1067
+ children: formatMessage(external_confirmation_messages_default.open)
1068
+ }
1069
+ ),
1070
+ /* @__PURE__ */ jsx28(Button3, { v2: true, block: true, className: "m-b-2", priority: "tertiary", size: "md", onClick: onCancel, children: formatMessage(external_confirmation_messages_default.cancel) })
1071
+ ] }) })
1072
+ ] }),
1073
+ onClose: onCancel
1074
+ }
1075
+ );
1076
+ }
1077
+ function getOrigin(url) {
1078
+ try {
1079
+ return new URL(url).origin;
1080
+ } catch (e) {
1081
+ return url;
1082
+ }
1083
+ }
1084
+ var ExternalConfirmationRenderer_default = ExternalConfirmationRenderer;
1085
+
1086
+ // ../renderers/src/FormRenderer.tsx
1087
+ import { jsx as jsx29 } from "react/jsx-runtime";
1088
+ var FormRenderer = {
1089
+ canRenderType: "form",
1090
+ render: ({ children, margin }) => /* @__PURE__ */ jsx29("div", { className: getMargin(margin), children })
1091
+ };
1092
+ var FormRenderer_default = FormRenderer;
1093
+
1094
+ // ../renderers/src/FormSectionRenderer.tsx
1095
+ import { Header as Header3 } from "@transferwise/components";
1096
+ import { jsx as jsx30, jsxs as jsxs7 } from "react/jsx-runtime";
1097
+ var FormSectionRenderer = {
1098
+ canRenderType: "form-section",
1099
+ render: ({ title, description, children }) => /* @__PURE__ */ jsxs7("fieldset", { children: [
1100
+ title && /* @__PURE__ */ jsx30(
1101
+ Header3,
1102
+ {
1103
+ as: "h2",
1104
+ title
1105
+ }
1106
+ ),
1107
+ description && /* @__PURE__ */ jsx30("p", { children: description }),
1108
+ children
1109
+ ] })
1110
+ };
1111
+ var FormSectionRenderer_default = FormSectionRenderer;
1112
+
1113
+ // ../renderers/src/HeadingRenderer.tsx
1114
+ import { Display, Title } from "@transferwise/components";
1115
+ import { jsx as jsx31 } from "react/jsx-runtime";
1116
+ var HeadingRenderer = {
1117
+ canRenderType: "heading",
1118
+ render: (props) => /* @__PURE__ */ jsx31(Heading, __spreadValues({}, props))
1119
+ };
1120
+ function Heading(props) {
1121
+ const { text, size, align, margin, control } = props;
1122
+ const className = getTextAlignmentAndMargin({ align, margin });
1123
+ return control === "display" ? /* @__PURE__ */ jsx31(DisplayHeading, { size, text, className }) : /* @__PURE__ */ jsx31(StandardHeading, { size, text, className });
1124
+ }
1125
+ function DisplayHeading({ size, text, className }) {
1126
+ return /* @__PURE__ */ jsx31(Display, { type: getDisplayType(size), className, children: text });
1127
+ }
1128
+ var getDisplayType = (size) => {
1129
+ switch (size) {
1130
+ case "xs":
1131
+ case "sm":
1132
+ return "display-small";
1133
+ case "xl":
1134
+ case "lg":
1135
+ return "display-large";
1136
+ case "md":
1137
+ default:
1138
+ return "display-medium";
1139
+ }
1140
+ };
1141
+ function StandardHeading({ size, text, className }) {
1142
+ return /* @__PURE__ */ jsx31(Title, { type: getTitleTypeBySize(size), className, children: text });
1143
+ }
1144
+ var getTitleTypeBySize = (size) => {
1145
+ var _a;
1146
+ const titleTypes = {
1147
+ xs: "title-group",
1148
+ sm: "title-body",
1149
+ md: "title-subsection",
1150
+ lg: "title-section",
1151
+ xl: "title-screen"
1152
+ };
1153
+ return (_a = titleTypes[size]) != null ? _a : "title-subsection";
1154
+ };
1155
+ var HeadingRenderer_default = HeadingRenderer;
1156
+
1157
+ // ../renderers/src/ImageRenderer/UrlImage.tsx
1158
+ import { Image } from "@transferwise/components";
1159
+ import { useEffect as useEffect4, useState as useState4 } from "react";
1160
+
1161
+ // ../renderers/src/utils/api-utils.ts
1162
+ function isRelativePath(url = "") {
1163
+ return !["https://", "http://", "data:"].some(
1164
+ (prefix) => url.startsWith(prefix) && url.length > prefix.length
1165
+ );
1166
+ }
1167
+
1168
+ // ../renderers/src/ImageRenderer/UrlImage.tsx
1169
+ import { jsx as jsx32 } from "react/jsx-runtime";
1170
+ function UrlImage({
1171
+ accessibilityDescription,
1172
+ align,
1173
+ margin,
1174
+ size,
1175
+ uri,
1176
+ httpClient
1177
+ }) {
1178
+ const [imageSource, setImageSource] = useState4("");
1179
+ useEffect4(() => {
1180
+ if (!uri.startsWith("urn:")) {
1181
+ void getImageSource(httpClient, uri).then(setImageSource);
1182
+ }
1183
+ }, [uri, httpClient]);
1184
+ return /* @__PURE__ */ jsx32("div", { className: `df-image ${align} ${size || "md"}`, children: /* @__PURE__ */ jsx32(
1185
+ Image,
1186
+ {
1187
+ className: `img-responsive ${getMargin(margin)}`,
1188
+ alt: accessibilityDescription != null ? accessibilityDescription : "",
1189
+ src: imageSource,
1190
+ stretch: true,
1191
+ shrink: true
1192
+ }
1193
+ ) });
1194
+ }
1195
+ var readImageBlobAsDataURL = async (imageBlob) => (
1196
+ // we can safely assume the type of reader.result is string
1197
+ // because we're calling reader.readAsDataURL
1198
+ // https://developer.mozilla.org/en-US/docs/Web/API/FileReader/result
1199
+ new Promise((resolve, reject) => {
1200
+ const reader = new FileReader();
1201
+ reader.addEventListener("loadend", () => resolve(reader.result));
1202
+ reader.addEventListener("error", reject);
1203
+ reader.readAsDataURL(imageBlob);
1204
+ })
1205
+ );
1206
+ var getImageSource = async (httpClient, imageUrl) => {
1207
+ var _a;
1208
+ try {
1209
+ if (isRelativePath(imageUrl) || (imageUrl == null ? void 0 : imageUrl.startsWith(`${(_a = window == null ? void 0 : window.location) == null ? void 0 : _a.origin}/`))) {
1210
+ return await httpClient(imageUrl, {
1211
+ method: "GET",
1212
+ headers: { "Content-Type": "image/image" },
1213
+ credentials: "same-origin"
1214
+ }).then(async (response) => {
1215
+ if (response.ok) {
1216
+ return response.blob();
1217
+ }
1218
+ throw new Error("Image fetching failed");
1219
+ }).then(readImageBlobAsDataURL).catch(() => imageUrl);
1220
+ }
1221
+ return imageUrl;
1222
+ } catch (e) {
1223
+ return imageUrl;
1224
+ }
1225
+ };
1226
+
1227
+ // ../renderers/src/ImageRenderer/UrnFlagImage.tsx
1228
+ import { jsx as jsx33 } from "react/jsx-runtime";
1229
+ var maxFlagSize = 600;
1230
+ function UrnFlagImage({
1231
+ accessibilityDescription,
1232
+ align,
1233
+ margin,
1234
+ size,
1235
+ uri
1236
+ }) {
1237
+ return /* @__PURE__ */ jsx33("div", { className: `df-image ${align} ${size || "md"} ${getMargin(margin)}`, children: /* @__PURE__ */ jsx33(UrnFlag, { size: maxFlagSize, urn: uri, accessibilityDescription }) });
1238
+ }
1239
+
1240
+ // ../renderers/src/ImageRenderer/UrnIllustration.tsx
1241
+ import {
1242
+ Illustration,
1243
+ isIllustrationSupport3D
1244
+ } from "@wise/art";
1245
+ import { useState as useState5 } from "react";
1246
+
1247
+ // ../renderers/src/ImageRenderer/isAnimated.ts
1248
+ var isAnimated = (uri) => {
1249
+ var _a;
1250
+ const { rComponents } = stringToURN(uri);
1251
+ return (_a = rComponents == null ? void 0 : rComponents.some(([key, value]) => key === "type" && value === "animated")) != null ? _a : false;
1252
+ };
1253
+
1254
+ // ../renderers/src/ImageRenderer/SafeIllustration3D.tsx
1255
+ import { Illustration3D } from "@wise/art";
1256
+ import { Component } from "react";
1257
+ import { jsx as jsx34 } from "react/jsx-runtime";
1258
+ var Illustration3DErrorBoundary = class extends Component {
1259
+ constructor(props) {
1260
+ super(props);
1261
+ this.state = { hasError: false };
1262
+ }
1263
+ static getDerivedStateFromError() {
1264
+ return { hasError: true };
1265
+ }
1266
+ componentDidCatch() {
1267
+ this.props.onError();
1268
+ }
1269
+ render() {
1270
+ if (this.state.hasError) {
1271
+ return null;
1272
+ }
1273
+ return this.props.children;
1274
+ }
1275
+ };
1276
+ var SafeIllustration3D = ({
1277
+ name,
1278
+ size,
1279
+ onError
1280
+ }) => {
1281
+ return /* @__PURE__ */ jsx34(Illustration3DErrorBoundary, { onError, children: /* @__PURE__ */ jsx34(Illustration3D, { name, size }) });
1282
+ };
1283
+ var SafeIllustration3D_default = SafeIllustration3D;
1284
+
1285
+ // ../renderers/src/ImageRenderer/UrnIllustration.tsx
1286
+ import { jsx as jsx35 } from "react/jsx-runtime";
1287
+ var urnPrefix = "urn:wise:illustrations:";
1288
+ var isUrnIllustration = (uri) => uri.startsWith(urnPrefix);
1289
+ function UrnIllustration({
1290
+ accessibilityDescription,
1291
+ align,
1292
+ margin,
1293
+ size,
1294
+ uri
1295
+ }) {
1296
+ const [has3DFailed, setHas3DFailed] = useState5(false);
1297
+ const illustrationSize = getIllustrationSize(size);
1298
+ const illustrationName = getIllustrationName(uri);
1299
+ const illustration3DName = getIllustration3DName(uri);
1300
+ if (illustration3DName && isAnimated(uri) && !has3DFailed) {
1301
+ return /* @__PURE__ */ jsx35("div", { className: `df-image ${align} ${getMargin(margin)}`, children: /* @__PURE__ */ jsx35(
1302
+ SafeIllustration3D_default,
1303
+ {
1304
+ name: illustration3DName,
1305
+ size: illustrationSize,
1306
+ onError: () => setHas3DFailed(true)
1307
+ }
1308
+ ) });
1309
+ }
1310
+ return /* @__PURE__ */ jsx35("div", { className: `df-image ${align} ${getMargin(margin)}`, children: /* @__PURE__ */ jsx35(
1311
+ Illustration,
1312
+ {
1313
+ className: "df-illustration",
1314
+ name: illustrationName,
1315
+ size: illustrationSize,
1316
+ alt: accessibilityDescription
1317
+ }
1318
+ ) });
1319
+ }
1320
+ var getIllustrationSize = (size) => ({ xs: "small", sm: "small", md: "medium", lg: "large", xl: "large" })[size] || "medium";
1321
+ var getIllustrationName = (uri) => {
1322
+ return uri.replace(urnPrefix, "").split("?")[0];
1323
+ };
1324
+ var getIllustration3DName = (uri) => {
1325
+ const illustrationName = getIllustrationName(uri);
1326
+ return isIllustrationSupport3D(illustrationName) ? illustrationName : null;
1327
+ };
1328
+
1329
+ // ../renderers/src/ImageRenderer/UrnImage.tsx
1330
+ import { jsx as jsx36 } from "react/jsx-runtime";
1331
+ var isUrnImage = (uri) => uri.startsWith("urn:");
1332
+ function UrnImage(props) {
1333
+ const { uri } = props;
1334
+ if (isUrnIllustration(uri)) {
1335
+ return /* @__PURE__ */ jsx36(UrnIllustration, __spreadValues({}, props));
1336
+ }
1337
+ if (isUrnFlag(uri)) {
1338
+ return /* @__PURE__ */ jsx36(UrnFlagImage, __spreadValues({}, props));
1339
+ }
1340
+ return null;
1341
+ }
1342
+
1343
+ // ../renderers/src/ImageRenderer/ImageRenderer.tsx
1344
+ import { jsx as jsx37 } from "react/jsx-runtime";
1345
+ var ImageRenderer = {
1346
+ canRenderType: "image",
1347
+ render: (props) => isUrnImage(props.uri) ? /* @__PURE__ */ jsx37(UrnImage, __spreadValues({}, props)) : /* @__PURE__ */ jsx37(UrlImage, __spreadValues({}, props))
1348
+ };
1349
+
1350
+ // ../renderers/src/ImageRenderer/index.tsx
1351
+ var ImageRenderer_default = ImageRenderer;
1352
+
1353
+ // ../renderers/src/InstructionsRenderer.tsx
1354
+ import { Header as Header4, InstructionsList } from "@transferwise/components";
1355
+ import { jsx as jsx38, jsxs as jsxs8 } from "react/jsx-runtime";
1356
+ var doContext = ["positive", "neutral"];
1357
+ var dontContext = ["warning", "negative"];
1358
+ var InstructionsRenderer = {
1359
+ canRenderType: "instructions",
1360
+ render: ({ items, margin, title }) => {
1361
+ const dos = items.filter((item) => doContext.includes(item.context)).map(({ text }) => text);
1362
+ const donts = items.filter((item) => dontContext.includes(item.context)).map(({ text }) => text);
1363
+ return /* @__PURE__ */ jsxs8("div", { className: getMargin(margin), children: [
1364
+ title ? /* @__PURE__ */ jsx38(Header4, { title }) : null,
1365
+ /* @__PURE__ */ jsx38(InstructionsList, { dos, donts })
1366
+ ] });
1367
+ }
1368
+ };
1369
+ var InstructionsRenderer_default = InstructionsRenderer;
1370
+
1371
+ // ../renderers/src/IntegerInputRenderer.tsx
1372
+ import { Input, InputGroup } from "@transferwise/components";
1373
+
1374
+ // ../renderers/src/utils/input-utils.ts
1375
+ var onWheel = (event) => {
1376
+ if (event.target instanceof HTMLElement) {
1377
+ event.target.blur();
1378
+ }
1379
+ };
1380
+
1381
+ // ../renderers/src/utils/getInputGroupAddonStart.tsx
1382
+ var getInputGroupAddonStart = (media) => {
1383
+ const content = getInlineMedia(media);
1384
+ return content ? { content } : void 0;
1385
+ };
1386
+
1387
+ // ../renderers/src/utils/pick.ts
1388
+ function pick(obj, ...keys) {
1389
+ const result = {};
1390
+ keys.forEach((key) => {
1391
+ result[key] = obj[key];
1392
+ });
1393
+ return result;
1394
+ }
1395
+
1396
+ // ../renderers/src/IntegerInputRenderer.tsx
1397
+ import { jsx as jsx39 } from "react/jsx-runtime";
1398
+ var IntegerInputRenderer = {
1399
+ canRenderType: "input-integer",
1400
+ render: (props) => {
1401
+ const { id, title, description, help, media, validationState, value, onChange } = props;
1402
+ const commonProps = pick(
1403
+ props,
1404
+ "autoComplete",
1405
+ "disabled",
1406
+ "onBlur",
1407
+ "onFocus",
1408
+ "placeholder",
1409
+ "maximum",
1410
+ "minimum"
1411
+ );
1412
+ return /* @__PURE__ */ jsx39(
1413
+ FieldInput_default,
1414
+ {
1415
+ id,
1416
+ label: title,
1417
+ description,
1418
+ validation: validationState,
1419
+ help,
1420
+ children: /* @__PURE__ */ jsx39(InputGroup, { addonStart: getInputGroupAddonStart(media), children: /* @__PURE__ */ jsx39(
1421
+ Input,
1422
+ __spreadValues({
1423
+ id,
1424
+ name: id,
1425
+ type: "number",
1426
+ step: "1",
1427
+ pattern: "\\d+",
1428
+ value: value != null ? value : "",
1429
+ onChange: ({ target: { value: newValue } }) => {
1430
+ const parsedValue = Number.parseInt(newValue, 10);
1431
+ onChange(Number.isNaN(parsedValue) ? null : parsedValue);
1432
+ },
1433
+ onWheel
1434
+ }, commonProps)
1435
+ ) })
1436
+ }
1437
+ );
1438
+ }
1439
+ };
1440
+ var IntegerInputRenderer_default = IntegerInputRenderer;
1441
+
1442
+ // ../renderers/src/ListRenderer.tsx
1443
+ import { Body, Header as Header5 } from "@transferwise/components";
1444
+ import classNames3 from "classnames";
1445
+ import { jsx as jsx40, jsxs as jsxs9 } from "react/jsx-runtime";
1446
+ var ListRenderer = {
1447
+ canRenderType: "list",
1448
+ render: ({ callToAction, control, margin, items, title }) => /* @__PURE__ */ jsxs9("div", { className: getMargin(margin), children: [
1449
+ (title || callToAction) && /* @__PURE__ */ jsx40(Header5, { as: "h2", title: title != null ? title : "", action: getListAction(callToAction) }),
1450
+ items.map((props) => /* @__PURE__ */ jsx40(DesignSystemListItem, __spreadProps(__spreadValues({}, props), { control }), props.title))
1451
+ ] })
1452
+ };
1453
+ var DesignSystemListItem = ({
1454
+ title,
1455
+ description,
1456
+ supportingValues,
1457
+ icon,
1458
+ image,
1459
+ media,
1460
+ control,
1461
+ tag
1462
+ }) => /* @__PURE__ */ jsx40(
1463
+ "label",
1464
+ {
1465
+ className: classNames3("np-option p-a-2", {
1466
+ "np-option__sm-media": true,
1467
+ "np-option__container-aligned": true
1468
+ }),
1469
+ children: /* @__PURE__ */ jsxs9("div", { className: "media", children: [
1470
+ icon || image || media ? /* @__PURE__ */ jsx40("div", { className: "media-left", children: /* @__PURE__ */ jsx40(
1471
+ ListItemMedia,
1472
+ {
1473
+ icon,
1474
+ media,
1475
+ preferAvatar: control === "with-avatar" || tag === "with-avatar"
1476
+ }
1477
+ ) }) : null,
1478
+ /* @__PURE__ */ jsxs9("div", { className: "media-body", children: [
1479
+ /* @__PURE__ */ jsxs9("div", { className: "d-flex justify-content-between", children: [
1480
+ /* @__PURE__ */ jsx40("h4", { className: "np-text-body-large-bold text-primary np-option__title", children: title }),
1481
+ /* @__PURE__ */ jsx40("h4", { className: "np-text-body-large-bold text-primary np-option__title", children: supportingValues == null ? void 0 : supportingValues.value })
1482
+ ] }),
1483
+ /* @__PURE__ */ jsxs9("div", { className: "d-flex justify-content-between", children: [
1484
+ /* @__PURE__ */ jsx40(Body, { className: "d-block np-option__body", children: description }),
1485
+ /* @__PURE__ */ jsx40(Body, { className: "d-block np-option__body", children: supportingValues == null ? void 0 : supportingValues.subvalue })
1486
+ ] })
1487
+ ] })
1488
+ ] })
1489
+ },
1490
+ title
1491
+ );
1492
+ var ListItemMedia = ({
1493
+ icon,
1494
+ media,
1495
+ preferAvatar
1496
+ }) => {
1497
+ if (icon) {
1498
+ return /* @__PURE__ */ jsx40("div", { className: "circle circle-sm text-primary circle-inverse", children: /* @__PURE__ */ jsx40(OptionMedia, { media, preferAvatar }) });
1499
+ }
1500
+ return /* @__PURE__ */ jsx40("div", { className: "np-option__no-media-circle", children: /* @__PURE__ */ jsx40(OptionMedia, { media, preferAvatar }) });
1501
+ };
1502
+ var getListAction = (callToAction) => {
1503
+ if (callToAction) {
1504
+ return __spreadValues({
1505
+ "aria-label": callToAction.accessibilityDescription,
1506
+ text: callToAction.title,
1507
+ onClick: callToAction.onClick
1508
+ }, callToAction.type === "link" ? { href: callToAction.href, target: "_blank" } : {});
1509
+ }
1510
+ return void 0;
1511
+ };
1512
+ var ListRenderer_default = ListRenderer;
1513
+
1514
+ // ../renderers/src/LoadingIndicatorRenderer.tsx
1515
+ import { Loader } from "@transferwise/components";
1516
+ import { jsx as jsx41 } from "react/jsx-runtime";
1517
+ var LoadingIndicatorRenderer = {
1518
+ canRenderType: "loading-indicator",
1519
+ render: ({ margin, size }) => /* @__PURE__ */ jsx41(
1520
+ Loader,
1521
+ {
1522
+ size,
1523
+ classNames: { "tw-loader": `tw-loader m-x-auto ${getMargin(margin)}` },
1524
+ "data-testid": "loading-indicator"
1525
+ }
1526
+ )
1527
+ };
1528
+ var LoadingIndicatorRenderer_default = LoadingIndicatorRenderer;
1529
+
1530
+ // ../renderers/src/MarkdownRenderer.tsx
1531
+ import { Markdown as Markdown3 } from "@transferwise/components";
1532
+ import { jsx as jsx42 } from "react/jsx-runtime";
1533
+ var MarkdownRenderer = {
1534
+ canRenderType: "markdown",
1535
+ render: ({ content, align, margin }) => /* @__PURE__ */ jsx42("div", { className: getTextAlignmentAndMargin({ align, margin }), children: /* @__PURE__ */ jsx42(Markdown3, { className: "np-text-body-large", config: { link: { target: "_blank" } }, children: content }) })
1536
+ };
1537
+ var MarkdownRenderer_default = MarkdownRenderer;
1538
+
1539
+ // ../renderers/src/ModalLayoutRenderer.tsx
1540
+ import { Button as Button4, Modal as Modal2 } from "@transferwise/components";
1541
+ import { useState as useState6 } from "react";
1542
+ import { jsx as jsx43, jsxs as jsxs10 } from "react/jsx-runtime";
1543
+ var ModalLayoutRenderer = {
1544
+ canRenderType: "modal-layout",
1545
+ render: (props) => /* @__PURE__ */ jsx43(DFModal, __spreadValues({}, props))
1546
+ };
1547
+ var ModalLayoutRenderer_default = ModalLayoutRenderer;
1548
+ function DFModal({ content, margin, trigger }) {
1549
+ const [visible, setVisible] = useState6(false);
1550
+ const { children, title } = content;
1551
+ return /* @__PURE__ */ jsxs10("div", { className: getMargin(margin), children: [
1552
+ /* @__PURE__ */ jsx43(Button4, { v2: true, priority: "tertiary", block: true, onClick: () => setVisible(true), children: trigger.title }),
1553
+ /* @__PURE__ */ jsx43(
1554
+ Modal2,
1555
+ {
1556
+ scroll: "content",
1557
+ open: visible,
1558
+ size: "lg",
1559
+ title,
1560
+ body: children,
1561
+ onClose: () => setVisible(false)
1562
+ }
1563
+ )
1564
+ ] });
1565
+ }
1566
+
1567
+ // ../renderers/src/ModalRenderer.tsx
1568
+ import { Modal as Modal3 } from "@transferwise/components";
1569
+ import { jsx as jsx44 } from "react/jsx-runtime";
1570
+ var ModalRenderer = {
1571
+ canRenderType: "modal",
1572
+ render: ({ title, children, open, onClose }) => {
1573
+ return /* @__PURE__ */ jsx44(Modal3, { open, title, body: children, onClose });
1574
+ }
1575
+ };
1576
+
1577
+ // ../renderers/src/MultiSelectInputRenderer.tsx
1578
+ import { SelectInput, SelectInputOptionContent } from "@transferwise/components";
1579
+ import { useState as useState7 } from "react";
1580
+ import { useIntl as useIntl6 } from "react-intl";
1581
+
1582
+ // ../renderers/src/messages/multi-select.messages.ts
1583
+ import { defineMessages as defineMessages5 } from "react-intl";
1584
+ var multi_select_messages_default = defineMessages5({
1585
+ summary: {
1586
+ id: "df.wise.MultiSelect.summary",
1587
+ defaultMessage: "{first} and {count} more",
1588
+ description: "A summary of the multiple items selected. Showing the title of the first selected item, and the number of other items that have been selected."
1589
+ }
1590
+ });
1591
+
1592
+ // ../renderers/src/MultiSelectInputRenderer.tsx
1593
+ import { jsx as jsx45 } from "react/jsx-runtime";
1594
+ var MultiSelectInputRenderer = {
1595
+ canRenderType: "input-multi-select",
1596
+ render: (props) => /* @__PURE__ */ jsx45(MultiSelectInputRendererComponent, __spreadValues({}, props))
1597
+ };
1598
+ function MultiSelectInputRendererComponent(props) {
1599
+ const { formatMessage } = useIntl6();
1600
+ const [stagedIndices, setStagedIndices] = useState7();
1601
+ const {
1602
+ id,
1603
+ autoComplete,
1604
+ description,
1605
+ disabled,
1606
+ help,
1607
+ options,
1608
+ placeholder,
1609
+ selectedIndices,
1610
+ title,
1611
+ validationState,
1612
+ onSelect
1613
+ } = props;
1614
+ const mergedIndices = stagedIndices != null ? stagedIndices : selectedIndices;
1615
+ const getFormattedMessage = () => {
1616
+ if (mergedIndices.length > 0) {
1617
+ if (mergedIndices.length > 1) {
1618
+ return formatMessage(multi_select_messages_default.summary, {
1619
+ first: options[mergedIndices[0]].title,
1620
+ count: mergedIndices.length - 1
1621
+ });
1622
+ }
1623
+ return options[mergedIndices[0]].title;
1624
+ }
1625
+ return void 0;
1626
+ };
1627
+ const renderValue = (index, withinTrigger) => {
1628
+ const option = index >= 0 ? options[index] : null;
1629
+ if (option === null) {
1630
+ return null;
1631
+ }
1632
+ if (withinTrigger) {
1633
+ return index === mergedIndices[0] ? getFormattedMessage() : void 0;
1634
+ }
1635
+ const contentProps = {
1636
+ title: option.title,
1637
+ description: option.description,
1638
+ icon: /* @__PURE__ */ jsx45(OptionMedia, { media: option.media, preferAvatar: false })
1639
+ };
1640
+ return /* @__PURE__ */ jsx45(SelectInputOptionContent, __spreadValues({}, contentProps));
1641
+ };
1642
+ const extraProps = { autoComplete };
1643
+ return /* @__PURE__ */ jsx45(
1644
+ FieldInput_default,
1645
+ {
1646
+ id,
1647
+ label: title,
1648
+ help,
1649
+ description,
1650
+ validation: validationState,
1651
+ children: /* @__PURE__ */ jsx45(
1652
+ SelectInput,
1653
+ __spreadValues({
1654
+ id,
1655
+ items: options.map((option, index) => {
1656
+ var _a, _b, _c;
1657
+ return {
1658
+ type: "option",
1659
+ value: index,
1660
+ filterMatchers: [
1661
+ ...(_a = option.keywords) != null ? _a : [],
1662
+ (_b = option.title) != null ? _b : "",
1663
+ (_c = option.description) != null ? _c : ""
1664
+ ],
1665
+ disabled: option.disabled
1666
+ };
1667
+ }),
1668
+ disabled,
1669
+ placeholder,
1670
+ value: mergedIndices,
1671
+ renderValue,
1672
+ multiple: true,
1673
+ filterable: options.length >= 8,
1674
+ onChange: (values) => {
1675
+ setStagedIndices(values);
1676
+ },
1677
+ onClose: () => {
1678
+ if (stagedIndices) {
1679
+ onSelect(stagedIndices);
1680
+ setStagedIndices(void 0);
1681
+ }
1682
+ }
1683
+ }, extraProps)
1684
+ )
1685
+ }
1686
+ );
1687
+ }
1688
+ var MultiSelectInputRenderer_default = MultiSelectInputRenderer;
20
1689
 
21
- // src/index.ts
22
- import { makeHttpClient } from "@wise/dynamic-flow-client";
23
- import { findRendererPropsByType, isValidSchema, JsonSchemaForm } from "@wise/dynamic-flow-client";
1690
+ // ../renderers/src/MultiUploadInputRenderer.tsx
1691
+ import { UploadInput } from "@transferwise/components";
1692
+
1693
+ // ../renderers/src/components/UploadFieldInput.tsx
1694
+ import { InlineAlert as InlineAlert2 } from "@transferwise/components";
1695
+ import classNames4 from "classnames";
1696
+ import { jsx as jsx46, jsxs as jsxs11 } from "react/jsx-runtime";
1697
+ function UploadFieldInput({
1698
+ id,
1699
+ children,
1700
+ label,
1701
+ description,
1702
+ help,
1703
+ validation
1704
+ }) {
1705
+ const labelContent = label && help ? /* @__PURE__ */ jsx46(LabelContentWithHelp, { text: label, help }) : label;
1706
+ const descriptionId = description ? `${id}-description` : void 0;
1707
+ return /* @__PURE__ */ jsxs11(
1708
+ "div",
1709
+ {
1710
+ className: classNames4("form-group d-block", {
1711
+ "has-error": (validation == null ? void 0 : validation.status) === "invalid"
1712
+ }),
1713
+ children: [
1714
+ /* @__PURE__ */ jsx46("label", { htmlFor: id, className: "control-label", children: labelContent }),
1715
+ children,
1716
+ (validation == null ? void 0 : validation.status) === "invalid" && /* @__PURE__ */ jsx46(InlineAlert2, { type: "negative", id: descriptionId, children: validation.message })
1717
+ ]
1718
+ }
1719
+ );
1720
+ }
1721
+ var UploadFieldInput_default = UploadFieldInput;
1722
+
1723
+ // ../renderers/src/utils/file-utils.ts
1724
+ var acceptsToFileTypes = (accepts) => Array.isArray(accepts) && accepts.length >= 1 ? accepts : "*";
1725
+ var toKilobytes = (sizeInBytes) => {
1726
+ const ONE_KB_IN_BYTES = 1024;
1727
+ return Math.floor(sizeInBytes / ONE_KB_IN_BYTES);
1728
+ };
1729
+ var toFile = async (base64Url, name) => {
1730
+ const type = getFileType(base64Url);
1731
+ const blob = await toBlob(base64Url);
1732
+ return new File([blob], name, { type });
1733
+ };
1734
+ var toBlob = async (base64Url) => (await fetch(base64Url)).blob();
1735
+ var getFileType = (base64Url) => {
1736
+ const contentTypeRegex = /^data:(.+);/;
1737
+ const matches = contentTypeRegex.exec(base64Url);
1738
+ if (matches && matches.length > 1) {
1739
+ return matches[1];
1740
+ }
1741
+ return void 0;
1742
+ };
1743
+ var getSizeLimit = (maxSize) => {
1744
+ if (maxSize === void 0) {
1745
+ return null;
1746
+ }
1747
+ return toKilobytes(maxSize);
1748
+ };
1749
+
1750
+ // ../renderers/src/MultiUploadInputRenderer.tsx
1751
+ import { jsx as jsx47 } from "react/jsx-runtime";
1752
+ var MultiUploadInputRenderer = {
1753
+ canRenderType: "input-upload-multi",
1754
+ render: (props) => {
1755
+ const {
1756
+ id,
1757
+ accepts,
1758
+ help,
1759
+ title,
1760
+ description,
1761
+ disabled,
1762
+ maxSize,
1763
+ maxItems,
1764
+ uploadLabel,
1765
+ validationState,
1766
+ value,
1767
+ onInsertFile,
1768
+ onRemoveFile
1769
+ } = props;
1770
+ const onUploadFile = async (formData) => {
1771
+ const file = formData.get("file");
1772
+ return onInsertFile(value.length, file).then((newId) => ({ id: newId }));
1773
+ };
1774
+ const onDeleteFile = async (fileId) => onRemoveFile(value.findIndex((file) => file.id === fileId));
1775
+ const descriptionId = description ? `${id}-description` : void 0;
1776
+ return /* @__PURE__ */ jsx47(
1777
+ UploadFieldInput_default,
1778
+ {
1779
+ id,
1780
+ label: title,
1781
+ description,
1782
+ validation: validationState,
1783
+ help,
1784
+ children: /* @__PURE__ */ jsx47(
1785
+ UploadInput,
1786
+ {
1787
+ id,
1788
+ "aria-describedby": descriptionId,
1789
+ description,
1790
+ disabled,
1791
+ fileTypes: acceptsToFileTypes(accepts),
1792
+ maxFiles: maxItems,
1793
+ multiple: true,
1794
+ sizeLimit: getSizeLimit(maxSize),
1795
+ uploadButtonTitle: uploadLabel,
1796
+ onDeleteFile,
1797
+ onUploadFile
1798
+ }
1799
+ )
1800
+ }
1801
+ );
1802
+ }
1803
+ };
1804
+ var MultiUploadInputRenderer_default = MultiUploadInputRenderer;
1805
+
1806
+ // ../renderers/src/NumberInputRenderer.tsx
1807
+ import { Input as Input2, InputGroup as InputGroup2 } from "@transferwise/components";
1808
+ import { jsx as jsx48 } from "react/jsx-runtime";
1809
+ var NumberInputRenderer = {
1810
+ canRenderType: "input-number",
1811
+ render: (props) => {
1812
+ const { id, title, description, help, media, validationState, value, onChange } = props;
1813
+ const commonProps = pick(
1814
+ props,
1815
+ "disabled",
1816
+ "onBlur",
1817
+ "onFocus",
1818
+ "placeholder",
1819
+ "maximum",
1820
+ "minimum"
1821
+ );
1822
+ return /* @__PURE__ */ jsx48(
1823
+ FieldInput_default,
1824
+ {
1825
+ id,
1826
+ label: title,
1827
+ description,
1828
+ validation: validationState,
1829
+ help,
1830
+ children: /* @__PURE__ */ jsx48(InputGroup2, { addonStart: getInputGroupAddonStart(media), children: /* @__PURE__ */ jsx48(
1831
+ Input2,
1832
+ __spreadValues({
1833
+ id,
1834
+ name: id,
1835
+ type: "number",
1836
+ value: value != null ? value : "",
1837
+ onChange: ({ target: { value: newValue } }) => {
1838
+ const parsedValue = Number.parseFloat(newValue);
1839
+ onChange(Number.isNaN(parsedValue) ? null : parsedValue);
1840
+ },
1841
+ onWheel
1842
+ }, commonProps)
1843
+ ) })
1844
+ }
1845
+ );
1846
+ }
1847
+ };
1848
+ var NumberInputRenderer_default = NumberInputRenderer;
1849
+
1850
+ // ../renderers/src/ParagraphRenderer.tsx
1851
+ import { useIntl as useIntl7 } from "react-intl";
1852
+
1853
+ // ../renderers/src/hooks/useSnackBarIfAvailable.ts
1854
+ import { SnackbarContext } from "@transferwise/components";
1855
+ import { useContext } from "react";
1856
+ function useSnackBarIfAvailable() {
1857
+ const context = useContext(SnackbarContext);
1858
+ return context ? context.createSnackbar : () => {
1859
+ };
1860
+ }
1861
+
1862
+ // ../renderers/src/ParagraphRenderer.tsx
1863
+ import { Button as Button5, Input as Input3 } from "@transferwise/components";
1864
+ import classNames5 from "classnames";
1865
+
1866
+ // ../renderers/src/messages/paragraph.messages.ts
1867
+ import { defineMessages as defineMessages6 } from "react-intl";
1868
+ var paragraph_messages_default = defineMessages6({
1869
+ copy: {
1870
+ id: "df.wise.DynamicParagraph.copy",
1871
+ defaultMessage: "Copy",
1872
+ description: "Copy to clipboard button label."
1873
+ },
1874
+ copied: {
1875
+ id: "df.wise.DynamicParagraph.copied",
1876
+ defaultMessage: "Copied to clipboard",
1877
+ description: "Appears in a snackbar when the copy operation succeeds."
1878
+ }
1879
+ });
1880
+
1881
+ // ../renderers/src/ParagraphRenderer.tsx
1882
+ import { jsx as jsx49, jsxs as jsxs12 } from "react/jsx-runtime";
1883
+ var ParagraphRenderer = {
1884
+ canRenderType: "paragraph",
1885
+ render: (props) => /* @__PURE__ */ jsx49(Paragraph, __spreadValues({}, props))
1886
+ };
1887
+ function Paragraph({ align, control, margin, text }) {
1888
+ const className = getTextAlignmentAndMargin({ align, margin });
1889
+ return control === "copyable" ? /* @__PURE__ */ jsx49(CopyableParagraph, { className, align, text }) : /* @__PURE__ */ jsx49(StandardParagraph, { className, text });
1890
+ }
1891
+ function StandardParagraph({ text, className }) {
1892
+ return /* @__PURE__ */ jsx49("p", { className: `np-text-body-large ${className}`, children: text });
1893
+ }
1894
+ function CopyableParagraph({
1895
+ text,
1896
+ align,
1897
+ className
1898
+ }) {
1899
+ const { formatMessage } = useIntl7();
1900
+ const createSnackbar = useSnackBarIfAvailable();
1901
+ const copy = () => {
1902
+ navigator.clipboard.writeText(text).then(() => createSnackbar({ text: formatMessage(paragraph_messages_default.copied) })).catch(() => {
1903
+ });
1904
+ };
1905
+ const inputAlignmentClasses = getTextAlignmentAndMargin({ align, margin: "sm" });
1906
+ return /* @__PURE__ */ jsxs12("div", { className, children: [
1907
+ /* @__PURE__ */ jsx49(
1908
+ Input3,
1909
+ {
1910
+ type: "text",
1911
+ value: text,
1912
+ readOnly: true,
1913
+ className: classNames5("text-ellipsis", inputAlignmentClasses)
1914
+ }
1915
+ ),
1916
+ /* @__PURE__ */ jsx49(Button5, { v2: true, block: true, onClick: copy, children: formatMessage(paragraph_messages_default.copy) })
1917
+ ] });
1918
+ }
1919
+ var ParagraphRenderer_default = ParagraphRenderer;
1920
+
1921
+ // ../renderers/src/RepeatableRenderer.tsx
1922
+ import { Button as Button6, Header as Header6, InlineAlert as InlineAlert3, Modal as Modal4, NavigationOption as NavigationOption2 } from "@transferwise/components";
1923
+ import { Plus } from "@transferwise/icons";
1924
+ import classNames6 from "classnames";
1925
+ import { useState as useState8 } from "react";
1926
+ import { useIntl as useIntl8 } from "react-intl";
1927
+
1928
+ // ../renderers/src/messages/repeatable.messages.ts
1929
+ import { defineMessages as defineMessages7 } from "react-intl";
1930
+ var repeatable_messages_default = defineMessages7({
1931
+ addItemTitle: {
1932
+ id: "df.wise.ArraySchema.addItemTitle",
1933
+ defaultMessage: "Add Item",
1934
+ description: "Label on the button used to open a form to add an item"
1935
+ },
1936
+ addItem: {
1937
+ id: "df.wise.ArraySchema.addItem",
1938
+ defaultMessage: "Save",
1939
+ description: "Label on the add button used to submit a form that adds an item"
1940
+ },
1941
+ editItem: {
1942
+ id: "df.wise.ArraySchema.editItem",
1943
+ defaultMessage: "Save",
1944
+ description: "Label on the edit button used to submit a form that edits an item"
1945
+ },
1946
+ removeItem: {
1947
+ id: "df.wise.ArraySchema.removeItem",
1948
+ defaultMessage: "Remove",
1949
+ description: "Label on the remove button used to confirm deletion of an item"
1950
+ }
1951
+ });
1952
+
1953
+ // ../renderers/src/RepeatableRenderer.tsx
1954
+ import { Fragment as Fragment4, jsx as jsx50, jsxs as jsxs13 } from "react/jsx-runtime";
1955
+ var RepeatableRenderer = {
1956
+ canRenderType: "repeatable",
1957
+ render: (props) => /* @__PURE__ */ jsx50(Repeatable, __spreadValues({}, props))
1958
+ };
1959
+ function Repeatable(props) {
1960
+ const {
1961
+ addItemTitle,
1962
+ description,
1963
+ editableItem,
1964
+ editItemTitle,
1965
+ items,
1966
+ title,
1967
+ validationState,
1968
+ onEdit,
1969
+ onAdd,
1970
+ onSave,
1971
+ onRemove
1972
+ } = props;
1973
+ const { formatMessage } = useIntl8();
1974
+ const [openModalType, setOpenModalType] = useState8(null);
1975
+ const onAddItem = () => {
1976
+ onAdd();
1977
+ setOpenModalType("add");
1978
+ };
1979
+ const onEditItem = (itemIndex) => {
1980
+ onEdit(itemIndex);
1981
+ setOpenModalType("edit");
1982
+ };
1983
+ const onSaveItem = () => {
1984
+ const saveSuccessful = onSave();
1985
+ if (saveSuccessful) {
1986
+ setOpenModalType(null);
1987
+ }
1988
+ };
1989
+ const onRemoveItem = () => {
1990
+ onRemove();
1991
+ setOpenModalType(null);
1992
+ };
1993
+ const onCancelEdit = () => {
1994
+ setOpenModalType(null);
1995
+ };
1996
+ return /* @__PURE__ */ jsxs13(Fragment4, { children: [
1997
+ title && /* @__PURE__ */ jsx50(Header6, { title }),
1998
+ description && /* @__PURE__ */ jsx50("p", { children: description }),
1999
+ /* @__PURE__ */ jsxs13(
2000
+ "div",
2001
+ {
2002
+ className: classNames6("form-group", {
2003
+ "has-error": (validationState == null ? void 0 : validationState.status) === "invalid"
2004
+ }),
2005
+ children: [
2006
+ items == null ? void 0 : items.map((item, index) => /* @__PURE__ */ jsx50(ItemSummaryOption, { item, onClick: () => onEditItem(index) }, item.id)),
2007
+ /* @__PURE__ */ jsx50(
2008
+ NavigationOption2,
2009
+ {
2010
+ media: /* @__PURE__ */ jsx50(Plus, {}),
2011
+ title: addItemTitle || formatMessage(repeatable_messages_default.addItemTitle),
2012
+ showMediaAtAllSizes: true,
2013
+ onClick: () => onAddItem()
2014
+ }
2015
+ ),
2016
+ (validationState == null ? void 0 : validationState.status) === "invalid" && /* @__PURE__ */ jsx50(InlineAlert3, { type: "negative", children: validationState.message })
2017
+ ]
2018
+ }
2019
+ ),
2020
+ /* @__PURE__ */ jsx50(
2021
+ Modal4,
2022
+ {
2023
+ open: openModalType !== null,
2024
+ title: (openModalType === "add" ? addItemTitle : editItemTitle) || formatMessage(repeatable_messages_default.addItemTitle),
2025
+ body: /* @__PURE__ */ jsxs13(Fragment4, { children: [
2026
+ /* @__PURE__ */ jsx50("div", { className: "m-b-2", children: editableItem }),
2027
+ /* @__PURE__ */ jsxs13("div", { children: [
2028
+ /* @__PURE__ */ jsx50(Button6, { priority: "primary", block: true, className: "m-b-2", onClick: () => onSaveItem(), children: formatMessage(repeatable_messages_default.addItem) }),
2029
+ /* @__PURE__ */ jsx50(
2030
+ Button6,
2031
+ {
2032
+ v2: true,
2033
+ priority: "secondary",
2034
+ sentiment: "negative",
2035
+ block: true,
2036
+ onClick: () => onRemoveItem(),
2037
+ children: formatMessage(repeatable_messages_default.removeItem)
2038
+ }
2039
+ )
2040
+ ] })
2041
+ ] }),
2042
+ onClose: () => onCancelEdit()
2043
+ }
2044
+ )
2045
+ ] });
2046
+ }
2047
+ function ItemSummaryOption({
2048
+ item,
2049
+ onClick
2050
+ }) {
2051
+ return /* @__PURE__ */ jsx50(
2052
+ NavigationOption2,
2053
+ {
2054
+ media: /* @__PURE__ */ jsx50(OptionMedia, { media: item.media, preferAvatar: false }),
2055
+ title: item.title,
2056
+ content: item.description,
2057
+ showMediaAtAllSizes: true,
2058
+ onClick
2059
+ }
2060
+ );
2061
+ }
2062
+ var RepeatableRenderer_default = RepeatableRenderer;
2063
+
2064
+ // ../renderers/src/ReviewRenderer.tsx
2065
+ import { DefinitionList } from "@transferwise/components";
2066
+
2067
+ // ../renderers/src/components/Header.tsx
2068
+ import { Header as DSHeader } from "@transferwise/components";
2069
+ import { jsx as jsx51 } from "react/jsx-runtime";
2070
+ var Header7 = ({ title, callToAction }) => (title || callToAction) && /* @__PURE__ */ jsx51(DSHeader, { title: title != null ? title : "", action: getHeaderAction(callToAction) });
2071
+ var getHeaderAction = (callToAction) => {
2072
+ if (!callToAction) {
2073
+ return void 0;
2074
+ }
2075
+ const { accessibilityDescription, href, title, onClick } = callToAction;
2076
+ return href ? {
2077
+ "aria-label": accessibilityDescription,
2078
+ text: title,
2079
+ href,
2080
+ target: "_blank"
2081
+ } : {
2082
+ "aria-label": accessibilityDescription,
2083
+ text: title,
2084
+ onClick: (event) => {
2085
+ event.preventDefault();
2086
+ onClick();
2087
+ }
2088
+ };
2089
+ };
2090
+
2091
+ // ../renderers/src/ReviewRenderer.tsx
2092
+ import { Fragment as Fragment5, jsx as jsx52, jsxs as jsxs14 } from "react/jsx-runtime";
2093
+ var ReviewRenderer = {
2094
+ canRenderType: "review",
2095
+ render: ({ callToAction, control, fields, margin, title, trackEvent }) => {
2096
+ const orientation = mapControlToDefinitionListLayout(control);
2097
+ return /* @__PURE__ */ jsxs14("div", { className: getMargin(margin), children: [
2098
+ /* @__PURE__ */ jsx52(Header7, { title, callToAction }),
2099
+ /* @__PURE__ */ jsx52("div", { className: margin, children: /* @__PURE__ */ jsx52(
2100
+ DefinitionList,
2101
+ {
2102
+ layout: orientation,
2103
+ definitions: fields.map(
2104
+ ({ label, value, help, analyticsId: fieldAnalyticsId }, index) => ({
2105
+ key: String(index),
2106
+ value,
2107
+ title: getFieldLabel(
2108
+ label,
2109
+ help,
2110
+ () => trackEvent("Help Pressed", { layoutItemId: fieldAnalyticsId })
2111
+ )
2112
+ })
2113
+ )
2114
+ }
2115
+ ) })
2116
+ ] });
2117
+ }
2118
+ };
2119
+ var ReviewRenderer_default = ReviewRenderer;
2120
+ var mapControlToDefinitionListLayout = (control) => {
2121
+ switch (control) {
2122
+ case "horizontal":
2123
+ case "horizontal-end-aligned":
2124
+ return "HORIZONTAL_RIGHT_ALIGNED";
2125
+ case "horizontal-start-aligned":
2126
+ return "HORIZONTAL_LEFT_ALIGNED";
2127
+ case "vertical-two-column":
2128
+ return "VERTICAL_TWO_COLUMN";
2129
+ case "vertical":
2130
+ case "vertical-one-column":
2131
+ default:
2132
+ return "VERTICAL_ONE_COLUMN";
2133
+ }
2134
+ };
2135
+ var getFieldLabel = (label, help, onClick) => {
2136
+ if (help) {
2137
+ return /* @__PURE__ */ jsxs14(Fragment5, { children: [
2138
+ label,
2139
+ " ",
2140
+ /* @__PURE__ */ jsx52(Help_default, { help, onClick })
2141
+ ] });
2142
+ }
2143
+ return label;
2144
+ };
2145
+
2146
+ // ../renderers/src/SearchRenderer/BlockSearchRendererComponent.tsx
2147
+ import { Input as Input4, Markdown as Markdown4, NavigationOption as NavigationOption3, NavigationOptionsList as NavigationOptionsList2 } from "@transferwise/components";
2148
+ import { useState as useState9 } from "react";
2149
+ import { useIntl as useIntl10 } from "react-intl";
2150
+
2151
+ // ../renderers/src/messages/search.messages.ts
2152
+ import { defineMessages as defineMessages8 } from "react-intl";
2153
+ var search_messages_default = defineMessages8({
2154
+ loading: {
2155
+ id: "df.wise.SearchLayout.loading",
2156
+ defaultMessage: "Loading...",
2157
+ description: "A message shown to the user while their search is being processed, before results appear."
2158
+ }
2159
+ });
2160
+
2161
+ // ../renderers/src/SearchRenderer/ErrorResult.tsx
2162
+ import { useIntl as useIntl9 } from "react-intl";
2163
+
2164
+ // ../renderers/src/messages/generic-error.messages.ts
2165
+ import { defineMessages as defineMessages9 } from "react-intl";
2166
+ var generic_error_messages_default = defineMessages9({
2167
+ genericErrorRetryHint: {
2168
+ id: "df.wise.PersistAsyncSchema.genericError",
2169
+ defaultMessage: "Something went wrong, please try again.",
2170
+ description: "Generic error message for persist async schema"
2171
+ },
2172
+ genericError: {
2173
+ id: "df.wise.ErrorBoundary.errorAlert",
2174
+ defaultMessage: "Something went wrong.",
2175
+ description: "Generic error message for when something has gone wrong."
2176
+ },
2177
+ retry: {
2178
+ id: "df.wise.ErrorBoundary.retry",
2179
+ defaultMessage: "Retry",
2180
+ description: "Usually this follows the generic error and contains a link."
2181
+ }
2182
+ });
2183
+
2184
+ // ../renderers/src/SearchRenderer/ErrorResult.tsx
2185
+ import { Link } from "@transferwise/components";
2186
+ import { jsx as jsx53, jsxs as jsxs15 } from "react/jsx-runtime";
2187
+ function ErrorResult({ state }) {
2188
+ const intl = useIntl9();
2189
+ return /* @__PURE__ */ jsxs15("p", { className: "m-t-2", children: [
2190
+ intl.formatMessage(generic_error_messages_default.genericError),
2191
+ "\xA0",
2192
+ /* @__PURE__ */ jsx53(Link, { onClick: () => state.onRetry(), children: intl.formatMessage(generic_error_messages_default.retry) })
2193
+ ] });
2194
+ }
2195
+
2196
+ // ../renderers/src/SearchRenderer/BlockSearchRendererComponent.tsx
2197
+ import { Fragment as Fragment6, jsx as jsx54, jsxs as jsxs16 } from "react/jsx-runtime";
2198
+ function BlockSearchRendererComponent({
2199
+ id,
2200
+ isLoading,
2201
+ margin,
2202
+ query,
2203
+ state,
2204
+ title,
2205
+ trackEvent,
2206
+ onChange
2207
+ }) {
2208
+ const [hasSearched, setHasSearched] = useState9(false);
2209
+ const { formatMessage } = useIntl10();
2210
+ return /* @__PURE__ */ jsxs16("div", { className: getMargin(margin), children: [
2211
+ /* @__PURE__ */ jsx54(FieldInput_default, { id, description: "", validation: void 0, help: "", label: title, children: /* @__PURE__ */ jsx54(
2212
+ Input4,
2213
+ {
2214
+ id,
2215
+ name: id,
2216
+ type: "text",
2217
+ value: query,
2218
+ className: "m-t-1",
2219
+ onChange: ({ currentTarget: { value } }) => {
2220
+ if (!hasSearched) {
2221
+ setHasSearched(true);
2222
+ trackEvent("Search Started");
2223
+ }
2224
+ onChange(value);
2225
+ }
2226
+ }
2227
+ ) }),
2228
+ isLoading ? /* @__PURE__ */ jsx54(Fragment6, { children: formatMessage(search_messages_default.loading) }) : /* @__PURE__ */ jsx54(SearchResultContent, { state, trackEvent })
2229
+ ] });
2230
+ }
2231
+ function SearchResultContent({
2232
+ state,
2233
+ trackEvent
2234
+ }) {
2235
+ switch (state.type) {
2236
+ case "error":
2237
+ return /* @__PURE__ */ jsx54(ErrorResult, { state });
2238
+ case "results":
2239
+ return /* @__PURE__ */ jsx54(SearchResults, { state, trackEvent });
2240
+ case "noResults":
2241
+ return /* @__PURE__ */ jsx54(EmptySearchResult, { state });
2242
+ case "pending":
2243
+ default:
2244
+ return null;
2245
+ }
2246
+ }
2247
+ function EmptySearchResult({ state }) {
2248
+ return /* @__PURE__ */ jsx54(Markdown4, { className: "m-t-2", config: { link: { target: "_blank" } }, children: state.message });
2249
+ }
2250
+ function SearchResults({
2251
+ state,
2252
+ trackEvent
2253
+ }) {
2254
+ return /* @__PURE__ */ jsx54(NavigationOptionsList2, { children: state.results.map((result) => {
2255
+ const { media } = result;
2256
+ return /* @__PURE__ */ jsx54(
2257
+ NavigationOption3,
2258
+ {
2259
+ title: result.title,
2260
+ content: result.description,
2261
+ media: media ? /* @__PURE__ */ jsx54(OptionMedia, { media, preferAvatar: false }) : void 0,
2262
+ showMediaCircle: false,
2263
+ showMediaAtAllSizes: true,
2264
+ onClick: () => {
2265
+ trackEvent("Search Result Selected", __spreadValues({
2266
+ type: result.type
2267
+ }, result.type === "action" ? { actionId: result.id } : {}));
2268
+ result.onClick();
2269
+ }
2270
+ },
2271
+ JSON.stringify(result)
2272
+ );
2273
+ }) });
2274
+ }
2275
+ var BlockSearchRendererComponent_default = BlockSearchRendererComponent;
2276
+
2277
+ // ../renderers/src/SearchRenderer/InlineSearchRendererComponent.tsx
2278
+ import { Markdown as Markdown5, Typeahead } from "@transferwise/components";
2279
+ import { Search } from "@transferwise/icons";
2280
+ import { useState as useState10 } from "react";
2281
+ import { useIntl as useIntl11 } from "react-intl";
2282
+ import { jsx as jsx55 } from "react/jsx-runtime";
2283
+ function InlineSearchRenderer({
2284
+ id,
2285
+ isLoading,
2286
+ margin,
2287
+ onChange,
2288
+ state,
2289
+ title,
2290
+ trackEvent
2291
+ }) {
2292
+ const [hasSearched, setHasSearched] = useState10(false);
2293
+ const intl = useIntl11();
2294
+ return /* @__PURE__ */ jsx55("div", { className: getMargin(margin), children: /* @__PURE__ */ jsx55(FieldInput_default, { id, description: "", validation: void 0, help: "", label: title, children: /* @__PURE__ */ jsx55(
2295
+ Typeahead,
2296
+ {
2297
+ id: "typeahead-input-id",
2298
+ intl,
2299
+ name: "typeahead-input-name",
2300
+ size: "md",
2301
+ maxHeight: 100,
2302
+ footer: /* @__PURE__ */ jsx55(TypeaheadFooter, { state, isLoading }),
2303
+ multiple: false,
2304
+ clearable: false,
2305
+ addon: /* @__PURE__ */ jsx55(Search, { size: 24 }),
2306
+ options: state.type === "results" ? state.results.map(mapResultToTypeaheadOption) : [],
2307
+ minQueryLength: 1,
2308
+ onChange: (values) => {
2309
+ if (values.length > 0) {
2310
+ const [updatedValue] = values;
2311
+ const { value: result } = updatedValue;
2312
+ if (result) {
2313
+ trackEvent("Search Result Selected", __spreadValues({
2314
+ type: result.type
2315
+ }, result.type === "action" ? { actionId: result.id } : {}));
2316
+ result.onClick();
2317
+ }
2318
+ }
2319
+ },
2320
+ onInputChange: (query) => {
2321
+ if (!hasSearched) {
2322
+ setHasSearched(true);
2323
+ trackEvent("Search Started");
2324
+ }
2325
+ onChange(query);
2326
+ }
2327
+ }
2328
+ ) }) });
2329
+ }
2330
+ function mapResultToTypeaheadOption(result) {
2331
+ return {
2332
+ label: result.title,
2333
+ secondary: result.description,
2334
+ value: result,
2335
+ clearQueryOnSelect: result.type === "action",
2336
+ keepFocusOnSelect: result.type === "search"
2337
+ };
2338
+ }
2339
+ function TypeaheadFooter({ state, isLoading }) {
2340
+ const { formatMessage } = useIntl11();
2341
+ if (state.type === "noResults") {
2342
+ return /* @__PURE__ */ jsx55(Markdown5, { className: "m-t-2 m-x-2", config: { link: { target: "_blank" } }, children: state.message });
2343
+ }
2344
+ if (state.type === "error") {
2345
+ return /* @__PURE__ */ jsx55("div", { className: "m-t-2 m-x-2", children: /* @__PURE__ */ jsx55(ErrorResult, { state }) });
2346
+ }
2347
+ if (state.type === "pending" || isLoading) {
2348
+ return /* @__PURE__ */ jsx55("p", { className: "m-t-2 m-x-2", children: formatMessage(search_messages_default.loading) });
2349
+ }
2350
+ return null;
2351
+ }
2352
+ var InlineSearchRendererComponent_default = InlineSearchRenderer;
2353
+
2354
+ // ../renderers/src/SearchRenderer/SearchRenderer.tsx
2355
+ import { jsx as jsx56 } from "react/jsx-runtime";
2356
+ var SearchRenderer = {
2357
+ canRenderType: "search",
2358
+ render: (props) => props.control === "inline" ? /* @__PURE__ */ jsx56(InlineSearchRendererComponent_default, __spreadValues({}, props)) : /* @__PURE__ */ jsx56(BlockSearchRendererComponent_default, __spreadValues({}, props))
2359
+ };
2360
+ var SearchRenderer_default = SearchRenderer;
2361
+
2362
+ // ../renderers/src/SectionRenderer.tsx
2363
+ import { Header as Header8 } from "@transferwise/components";
2364
+
2365
+ // ../renderers/src/utils/getHeaderAction.tsx
2366
+ var getHeaderAction2 = (callToAction) => {
2367
+ if (!callToAction) {
2368
+ return void 0;
2369
+ }
2370
+ const { accessibilityDescription, href, title, onClick } = callToAction;
2371
+ return href ? {
2372
+ "aria-label": accessibilityDescription,
2373
+ text: title,
2374
+ href,
2375
+ target: "_blank"
2376
+ } : {
2377
+ "aria-label": accessibilityDescription,
2378
+ text: title,
2379
+ onClick: (event) => {
2380
+ event.preventDefault();
2381
+ onClick();
2382
+ }
2383
+ };
2384
+ };
2385
+
2386
+ // ../renderers/src/SectionRenderer.tsx
2387
+ import { jsx as jsx57, jsxs as jsxs17 } from "react/jsx-runtime";
2388
+ var SectionRenderer = {
2389
+ canRenderType: "section",
2390
+ render: ({ children, callToAction, margin, title }) => {
2391
+ return /* @__PURE__ */ jsxs17("section", { className: getMargin(margin), children: [
2392
+ (title || callToAction) && /* @__PURE__ */ jsx57(Header8, { title: title != null ? title : "", action: getHeaderAction2(callToAction) }),
2393
+ children
2394
+ ] });
2395
+ }
2396
+ };
2397
+ var SectionRenderer_default = SectionRenderer;
2398
+
2399
+ // ../renderers/src/SelectInputRenderer/RadioInputRendererComponent.tsx
2400
+ import { RadioGroup } from "@transferwise/components";
2401
+ import { Fragment as Fragment7, jsx as jsx58, jsxs as jsxs18 } from "react/jsx-runtime";
2402
+ function RadioInputRendererComponent(props) {
2403
+ const {
2404
+ id,
2405
+ children,
2406
+ description,
2407
+ disabled,
2408
+ help,
2409
+ title,
2410
+ options,
2411
+ selectedIndex,
2412
+ validationState,
2413
+ onSelect
2414
+ } = props;
2415
+ return /* @__PURE__ */ jsxs18(Fragment7, { children: [
2416
+ /* @__PURE__ */ jsx58(
2417
+ FieldInput_default,
2418
+ {
2419
+ id,
2420
+ label: title,
2421
+ help,
2422
+ description,
2423
+ validation: validationState,
2424
+ children: /* @__PURE__ */ jsx58("span", { children: /* @__PURE__ */ jsx58(
2425
+ RadioGroup,
2426
+ {
2427
+ name: id,
2428
+ radios: options.map((option, index) => ({
2429
+ label: option.title,
2430
+ value: index,
2431
+ secondary: option.description,
2432
+ disabled: option.disabled || disabled,
2433
+ avatar: /* @__PURE__ */ jsx58(OptionMedia, { media: option.media, preferAvatar: false })
2434
+ })),
2435
+ selectedValue: selectedIndex != null ? selectedIndex : void 0,
2436
+ onChange: onSelect
2437
+ },
2438
+ `${id}-${selectedIndex}`
2439
+ ) })
2440
+ }
2441
+ ),
2442
+ children
2443
+ ] });
2444
+ }
2445
+
2446
+ // ../renderers/src/SelectInputRenderer/TabInputRendererComponent.tsx
2447
+ import { Tabs } from "@transferwise/components";
2448
+ import { useEffect as useEffect5 } from "react";
2449
+ import { Fragment as Fragment8, jsx as jsx59, jsxs as jsxs19 } from "react/jsx-runtime";
2450
+ function TabInputRendererComponent(props) {
2451
+ const {
2452
+ id,
2453
+ children,
2454
+ description,
2455
+ disabled,
2456
+ help,
2457
+ title,
2458
+ options,
2459
+ selectedIndex,
2460
+ validationState,
2461
+ onSelect
2462
+ } = props;
2463
+ useEffect5(() => {
2464
+ if (!isValidIndex(selectedIndex, options.length)) {
2465
+ onSelect(0);
2466
+ }
2467
+ }, [selectedIndex, onSelect, options.length]);
2468
+ return /* @__PURE__ */ jsxs19(Fragment8, { children: [
2469
+ /* @__PURE__ */ jsx59(
2470
+ FieldInput_default,
2471
+ {
2472
+ id,
2473
+ label: title,
2474
+ help,
2475
+ description,
2476
+ validation: validationState,
2477
+ children: /* @__PURE__ */ jsx59(
2478
+ Tabs,
2479
+ {
2480
+ name: id,
2481
+ selected: selectedIndex != null ? selectedIndex : 0,
2482
+ tabs: options.map((option) => ({
2483
+ title: option.title,
2484
+ // if we pass null, we get some props-types console errors
2485
+ // eslint-disable-next-line react/jsx-no-useless-fragment
2486
+ content: /* @__PURE__ */ jsx59(Fragment8, {}),
2487
+ disabled: option.disabled || disabled
2488
+ })),
2489
+ onTabSelect: onSelect
2490
+ }
2491
+ )
2492
+ }
2493
+ ),
2494
+ children
2495
+ ] });
2496
+ }
2497
+ var isValidIndex = (index, options) => index !== null && index >= 0 && index < options;
2498
+
2499
+ // ../renderers/src/SelectInputRenderer/SelectInputRendererComponent.tsx
2500
+ import { SelectInput as SelectInput2, SelectInputOptionContent as SelectInputOptionContent2 } from "@transferwise/components";
2501
+ import { Fragment as Fragment9, jsx as jsx60, jsxs as jsxs20 } from "react/jsx-runtime";
2502
+ function SelectInputRendererComponent(props) {
2503
+ const {
2504
+ id,
2505
+ autoComplete,
2506
+ children,
2507
+ description,
2508
+ disabled,
2509
+ help,
2510
+ title,
2511
+ options,
2512
+ placeholder,
2513
+ required,
2514
+ selectedIndex,
2515
+ validationState,
2516
+ onSelect
2517
+ } = props;
2518
+ const items = options.map(
2519
+ (option, index) => {
2520
+ var _a, _b, _c;
2521
+ return {
2522
+ type: "option",
2523
+ value: index,
2524
+ filterMatchers: [...(_a = option.keywords) != null ? _a : [], (_b = option.title) != null ? _b : "", (_c = option.description) != null ? _c : ""],
2525
+ disabled: option.disabled
2526
+ };
2527
+ }
2528
+ );
2529
+ const renderValue = (index, withinTrigger) => {
2530
+ const option = index >= 0 ? options[index] : null;
2531
+ if (option === null) {
2532
+ return null;
2533
+ }
2534
+ const contentProps = withinTrigger ? {
2535
+ title: option.title,
2536
+ note: option.description,
2537
+ icon: getInlineMedia(option.media)
2538
+ } : {
2539
+ title: option.title,
2540
+ description: option.description,
2541
+ icon: /* @__PURE__ */ jsx60(OptionMedia, { media: option.media, preferAvatar: false })
2542
+ };
2543
+ return /* @__PURE__ */ jsx60(SelectInputOptionContent2, __spreadValues({}, contentProps));
2544
+ };
2545
+ const extraProps = { autoComplete };
2546
+ return /* @__PURE__ */ jsxs20(Fragment9, { children: [
2547
+ /* @__PURE__ */ jsx60(
2548
+ FieldInput_default,
2549
+ {
2550
+ id,
2551
+ label: title,
2552
+ help,
2553
+ description,
2554
+ validation: validationState,
2555
+ children: /* @__PURE__ */ jsx60(
2556
+ SelectInput2,
2557
+ __spreadValues({
2558
+ name: id,
2559
+ placeholder,
2560
+ items,
2561
+ disabled,
2562
+ value: selectedIndex,
2563
+ renderValue,
2564
+ filterable: items.length >= 8,
2565
+ onChange: onSelect,
2566
+ onClear: required ? void 0 : () => onSelect(null)
2567
+ }, extraProps)
2568
+ )
2569
+ }
2570
+ ),
2571
+ children
2572
+ ] });
2573
+ }
2574
+
2575
+ // ../renderers/src/SelectInputRenderer/SegmentedInputRendererComponent.tsx
2576
+ import { useEffect as useEffect6 } from "react";
2577
+ import { SegmentedControl } from "@transferwise/components";
2578
+ import { Fragment as Fragment10, jsx as jsx61, jsxs as jsxs21 } from "react/jsx-runtime";
2579
+ function SegmentedInputRendererComponent(props) {
2580
+ const {
2581
+ id,
2582
+ children,
2583
+ description,
2584
+ help,
2585
+ title,
2586
+ options,
2587
+ selectedIndex,
2588
+ validationState,
2589
+ onSelect
2590
+ } = props;
2591
+ useEffect6(() => {
2592
+ if (!isValidIndex2(selectedIndex, options.length)) {
2593
+ onSelect(0);
2594
+ }
2595
+ }, [selectedIndex, onSelect, options.length]);
2596
+ return /* @__PURE__ */ jsxs21(Fragment10, { children: [
2597
+ /* @__PURE__ */ jsx61(
2598
+ FieldInput_default,
2599
+ {
2600
+ id,
2601
+ label: title,
2602
+ help,
2603
+ description,
2604
+ validation: validationState,
2605
+ children: /* @__PURE__ */ jsx61(
2606
+ SegmentedControl,
2607
+ {
2608
+ name: `${id}-segmented-control`,
2609
+ value: String(selectedIndex),
2610
+ mode: "view",
2611
+ segments: options.map((option, index) => ({
2612
+ id: String(index),
2613
+ value: String(index),
2614
+ label: option.title,
2615
+ controls: `${id}-children`
2616
+ })),
2617
+ onChange: (value) => onSelect(Number(value))
2618
+ }
2619
+ )
2620
+ }
2621
+ ),
2622
+ /* @__PURE__ */ jsx61("div", { id: `${id}-children`, children })
2623
+ ] });
2624
+ }
2625
+ var isValidIndex2 = (index, options) => index !== null && index >= 0 && index < options;
2626
+
2627
+ // ../renderers/src/SelectInputRenderer/SelectInputRenderer.tsx
2628
+ import { jsx as jsx62 } from "react/jsx-runtime";
2629
+ var SelectInputRenderer = {
2630
+ canRenderType: "input-select",
2631
+ render: (props) => {
2632
+ switch (props.control) {
2633
+ case "radio":
2634
+ return /* @__PURE__ */ jsx62(RadioInputRendererComponent, __spreadValues({}, props));
2635
+ case "tab":
2636
+ return props.options.length > 3 ? /* @__PURE__ */ jsx62(SelectInputRendererComponent, __spreadValues({}, props)) : /* @__PURE__ */ jsx62(TabInputRendererComponent, __spreadValues({}, props));
2637
+ case "segmented":
2638
+ return props.options.length > 3 ? /* @__PURE__ */ jsx62(SelectInputRendererComponent, __spreadValues({}, props)) : /* @__PURE__ */ jsx62(SegmentedInputRendererComponent, __spreadValues({}, props));
2639
+ case "select":
2640
+ default:
2641
+ return /* @__PURE__ */ jsx62(SelectInputRendererComponent, __spreadValues({}, props));
2642
+ }
2643
+ }
2644
+ };
2645
+ var SelectInputRenderer_default = SelectInputRenderer;
2646
+
2647
+ // ../renderers/src/StatusListRenderer.tsx
2648
+ import { Header as Header9, Summary } from "@transferwise/components";
2649
+ import { jsx as jsx63, jsxs as jsxs22 } from "react/jsx-runtime";
2650
+ var StatusListRenderer = {
2651
+ canRenderType: "status-list",
2652
+ render: ({ margin, items, title }) => /* @__PURE__ */ jsxs22("div", { className: getMargin(margin), children: [
2653
+ title ? /* @__PURE__ */ jsx63(Header9, { title, className: "m-b-2" }) : null,
2654
+ items.map(({ callToAction, description, icon, status, title: itemTitle }) => /* @__PURE__ */ jsx63(
2655
+ Summary,
2656
+ {
2657
+ title: itemTitle,
2658
+ description,
2659
+ icon: icon && "name" in icon ? /* @__PURE__ */ jsx63(DynamicIcon_default, { name: icon.name }) : null,
2660
+ status: mapStatus(status),
2661
+ action: getSummaryAction(callToAction)
2662
+ },
2663
+ `${itemTitle}/${description || ""}`
2664
+ ))
2665
+ ] })
2666
+ };
2667
+ var StatusListRenderer_default = StatusListRenderer;
2668
+ var getSummaryAction = (callToAction) => {
2669
+ if (!callToAction) {
2670
+ return void 0;
2671
+ }
2672
+ const { accessibilityDescription, href, title, onClick } = callToAction;
2673
+ if (!href) {
2674
+ return {
2675
+ "aria-label": accessibilityDescription,
2676
+ text: title,
2677
+ onClick
2678
+ };
2679
+ }
2680
+ return {
2681
+ "aria-label": accessibilityDescription,
2682
+ href,
2683
+ target: "_blank",
2684
+ text: title
2685
+ };
2686
+ };
2687
+ var mapStatus = (status) => {
2688
+ if (status === "not-done") {
2689
+ return "notDone";
2690
+ }
2691
+ return status;
2692
+ };
2693
+
2694
+ // ../renderers/src/utils/useCustomTheme.ts
2695
+ import { useTheme } from "@wise/components-theming";
2696
+ import { useEffect as useEffect7, useMemo } from "react";
2697
+ var ThemeRequiredEventName = "Theme Required";
2698
+ var useCustomTheme = (theme, trackEvent) => {
2699
+ const previousThemeHookValue = useTheme();
2700
+ const previousTheme = useMemo(() => previousThemeHookValue.theme, []);
2701
+ useEffect7(() => {
2702
+ trackEvent(ThemeRequiredEventName, { theme });
2703
+ return theme !== previousTheme ? () => {
2704
+ trackEvent(ThemeRequiredEventName, { theme: previousTheme });
2705
+ } : () => {
2706
+ };
2707
+ }, []);
2708
+ };
2709
+
2710
+ // ../renderers/src/step/topbar/BackButton.tsx
2711
+ import { IconButton } from "@transferwise/components";
2712
+ import { ArrowLeft } from "@transferwise/icons";
2713
+ import { jsx as jsx64, jsxs as jsxs23 } from "react/jsx-runtime";
2714
+ function BackButton({ title, onClick }) {
2715
+ return /* @__PURE__ */ jsxs23(IconButton, { priority: "tertiary", onClick, children: [
2716
+ /* @__PURE__ */ jsx64("span", { className: "sr-only", children: title }),
2717
+ /* @__PURE__ */ jsx64(ArrowLeft, {})
2718
+ ] });
2719
+ }
2720
+
2721
+ // ../renderers/src/step/topbar/Toolbar.tsx
2722
+ import { Button as Button7, IconButton as IconButton2 } from "@transferwise/components";
2723
+ import { jsx as jsx65, jsxs as jsxs24 } from "react/jsx-runtime";
2724
+ var Toolbar = ({ items }) => {
2725
+ return (items == null ? void 0 : items.length) > 0 ? /* @__PURE__ */ jsx65("div", { className: "df-toolbar", children: items.map((item, index) => /* @__PURE__ */ jsx65(ToolbarButton, __spreadValues({}, item), `${item.type}-${index}-${item.title}`)) }) : null;
2726
+ };
2727
+ function ToolbarButton(props) {
2728
+ return prefersMedia(props.control) ? /* @__PURE__ */ jsx65(MediaToolbarButton, __spreadValues({}, props)) : /* @__PURE__ */ jsx65(TextToolbarButton, __spreadValues({}, props));
2729
+ }
2730
+ function MediaToolbarButton(props) {
2731
+ var _a;
2732
+ const { context, control, media, accessibilityDescription, disabled, onClick } = props;
2733
+ const priority = getIconButtonPriority(control);
2734
+ const type = getSentiment(context);
2735
+ return /* @__PURE__ */ jsxs24(
2736
+ IconButton2,
2737
+ {
2738
+ className: "df-toolbar-button",
2739
+ disabled,
2740
+ priority,
2741
+ size: 32,
2742
+ type,
2743
+ onClick,
2744
+ children: [
2745
+ accessibilityDescription ? /* @__PURE__ */ jsx65("span", { className: "sr-only", children: accessibilityDescription }) : null,
2746
+ media ? (_a = getAddonStart(media)) == null ? void 0 : _a.value : null
2747
+ ]
2748
+ }
2749
+ );
2750
+ }
2751
+ function TextToolbarButton(props) {
2752
+ const { context, control, title, media, disabled, onClick } = props;
2753
+ const addonStart = media ? getAddonStart(media) : void 0;
2754
+ const priority = getPriority2(control);
2755
+ const sentiment = getSentiment(context);
2756
+ return /* @__PURE__ */ jsx65(
2757
+ Button7,
2758
+ {
2759
+ v2: true,
2760
+ size: "sm",
2761
+ className: "df-toolbar-button",
2762
+ disabled,
2763
+ priority,
2764
+ addonStart,
2765
+ sentiment,
2766
+ onClick,
2767
+ children: title
2768
+ }
2769
+ );
2770
+ }
2771
+ var getAddonStart = (media) => {
2772
+ if (media.type === "avatar") {
2773
+ if (media.content.length > 0 && media.content[0].type === "uri" && isValidIconUrn(media.content[0].uri)) {
2774
+ return {
2775
+ type: "icon",
2776
+ value: getInlineMedia({
2777
+ type: "image",
2778
+ uri: media.content[0].uri
2779
+ })
2780
+ };
2781
+ }
2782
+ return void 0;
2783
+ }
2784
+ return { type: "icon", value: getInlineMedia(media) };
2785
+ };
2786
+ var getPriority2 = (control) => isKnownControl(control) ? control : "secondary";
2787
+ var prefersMedia = (control) => {
2788
+ return false;
2789
+ };
2790
+ var knownControls = ["primary", "secondary", "secondary-neutral"];
2791
+ var isKnownControl = (control) => control !== void 0 && knownControls.includes(control);
2792
+ var getSentiment = (context) => {
2793
+ return "default";
2794
+ };
2795
+ var getIconButtonPriority = (control) => {
2796
+ const priority = getPriority2(control);
2797
+ return priority === "secondary-neutral" ? "tertiary" : priority;
2798
+ };
2799
+
2800
+ // ../renderers/src/step/topbar/TopBar.tsx
2801
+ import { jsx as jsx66, jsxs as jsxs25 } from "react/jsx-runtime";
2802
+ function TopBar({ back, toolbar }) {
2803
+ return back || toolbar ? /* @__PURE__ */ jsxs25("div", { className: "d-flex m-b-2", children: [
2804
+ back ? /* @__PURE__ */ jsx66(BackButton, __spreadValues({}, back)) : null,
2805
+ toolbar ? /* @__PURE__ */ jsx66(Toolbar, __spreadValues({}, toolbar)) : null
2806
+ ] }) : null;
2807
+ }
2808
+
2809
+ // ../renderers/src/step/SplashCelebrationStepRenderer.tsx
2810
+ import { jsx as jsx67, jsxs as jsxs26 } from "react/jsx-runtime";
2811
+ var SplashCelebrationStepRenderer = {
2812
+ canRenderType: "step",
2813
+ canRender: ({ control }) => control === "splash-celebration",
2814
+ render: SplashCelebrationStepRendererComponent
2815
+ };
2816
+ function SplashCelebrationStepRendererComponent(props) {
2817
+ const { back, toolbar, children, trackEvent } = props;
2818
+ useCustomTheme("forest-green", trackEvent);
2819
+ return /* @__PURE__ */ jsxs26("div", { className: "splash-screen m-t-5", children: [
2820
+ /* @__PURE__ */ jsx67(TopBar, { back, toolbar }),
2821
+ children
2822
+ ] });
2823
+ }
2824
+
2825
+ // ../renderers/src/step/SplashStepRenderer.tsx
2826
+ import { jsx as jsx68, jsxs as jsxs27 } from "react/jsx-runtime";
2827
+ var SplashStepRenderer = {
2828
+ canRenderType: "step",
2829
+ canRender: ({ control }) => control === "splash",
2830
+ render: SplashStepRendererComponent
2831
+ };
2832
+ function SplashStepRendererComponent(props) {
2833
+ const { back, toolbar, children } = props;
2834
+ return /* @__PURE__ */ jsxs27("div", { className: "splash-screen m-t-5", children: [
2835
+ /* @__PURE__ */ jsx68(TopBar, { back, toolbar }),
2836
+ children
2837
+ ] });
2838
+ }
2839
+
2840
+ // ../renderers/src/step/StepRenderer.tsx
2841
+ import { Alert as Alert2, Title as Title2 } from "@transferwise/components";
2842
+ import { Fragment as Fragment11, jsx as jsx69, jsxs as jsxs28 } from "react/jsx-runtime";
2843
+ var StepRenderer = {
2844
+ canRenderType: "step",
2845
+ render: StepRendererComponent
2846
+ };
2847
+ function StepRendererComponent(props) {
2848
+ const { back, description, error, title, children, toolbar } = props;
2849
+ return /* @__PURE__ */ jsxs28(Fragment11, { children: [
2850
+ /* @__PURE__ */ jsx69(TopBar, { back, toolbar }),
2851
+ title || description ? /* @__PURE__ */ jsxs28("div", { className: "m-b-4", children: [
2852
+ title ? /* @__PURE__ */ jsx69(Title2, { as: "h1", type: "title-section", className: "text-xs-center m-b-2", children: title }) : void 0,
2853
+ description ? /* @__PURE__ */ jsx69("p", { className: "text-xs-center np-text-body-large", children: description }) : void 0
2854
+ ] }) : void 0,
2855
+ error ? /* @__PURE__ */ jsx69(Alert2, { type: "negative", className: "m-b-2", message: error }) : void 0,
2856
+ children
2857
+ ] });
2858
+ }
2859
+
2860
+ // ../renderers/src/TabsRenderer.tsx
2861
+ import { Chips, SegmentedControl as SegmentedControl2, Tabs as Tabs2 } from "@transferwise/components";
2862
+ import { useState as useState11 } from "react";
2863
+ import { jsx as jsx70, jsxs as jsxs29 } from "react/jsx-runtime";
2864
+ var TabsRenderer = {
2865
+ canRenderType: "tabs",
2866
+ render: (props) => {
2867
+ switch (props.control) {
2868
+ case "segmented":
2869
+ if (props.tabs.length > 3) {
2870
+ return /* @__PURE__ */ jsx70(TabsRendererComponent, __spreadValues({}, props));
2871
+ }
2872
+ return /* @__PURE__ */ jsx70(SegmentedTabsRendererComponent, __spreadValues({}, props));
2873
+ case "chips":
2874
+ return /* @__PURE__ */ jsx70(ChipsTabsRendererComponent, __spreadValues({}, props));
2875
+ default:
2876
+ return /* @__PURE__ */ jsx70(TabsRendererComponent, __spreadValues({}, props));
2877
+ }
2878
+ }
2879
+ };
2880
+ function TabsRendererComponent({ uid, margin, tabs }) {
2881
+ const [selectedIndex, setSelectedIndex] = useState11(0);
2882
+ return /* @__PURE__ */ jsx70("div", { className: getMargin(margin), children: /* @__PURE__ */ jsx70(
2883
+ Tabs2,
2884
+ {
2885
+ name: uid,
2886
+ selected: selectedIndex != null ? selectedIndex : 0,
2887
+ tabs: tabs.map((option) => ({
2888
+ title: option.title,
2889
+ disabled: false,
2890
+ content: /* @__PURE__ */ jsxs29("div", { className: "m-t-2", children: [
2891
+ " ",
2892
+ option.children,
2893
+ " "
2894
+ ] })
2895
+ })),
2896
+ onTabSelect: setSelectedIndex
2897
+ }
2898
+ ) });
2899
+ }
2900
+ function SegmentedTabsRendererComponent({ uid, margin, tabs }) {
2901
+ var _a;
2902
+ const [selectedIndex, setSelectedIndex] = useState11(0);
2903
+ return /* @__PURE__ */ jsxs29("div", { className: getMargin(margin), children: [
2904
+ /* @__PURE__ */ jsx70(
2905
+ SegmentedControl2,
2906
+ {
2907
+ name: uid,
2908
+ value: String(selectedIndex),
2909
+ mode: "view",
2910
+ segments: tabs.map((tab, index) => ({
2911
+ id: String(index),
2912
+ value: String(index),
2913
+ label: tab.title,
2914
+ controls: `${uid}-children`
2915
+ })),
2916
+ onChange: (value) => setSelectedIndex(Number(value))
2917
+ }
2918
+ ),
2919
+ /* @__PURE__ */ jsx70("div", { id: `${uid}-children`, className: "m-t-2", children: (_a = tabs[selectedIndex]) == null ? void 0 : _a.children })
2920
+ ] });
2921
+ }
2922
+ function ChipsTabsRendererComponent({ margin, tabs }) {
2923
+ var _a;
2924
+ const [selectedIndex, setSelectedIndex] = useState11(0);
2925
+ return /* @__PURE__ */ jsxs29("div", { className: getMargin(margin), children: [
2926
+ /* @__PURE__ */ jsx70("div", { className: "chips-container", children: /* @__PURE__ */ jsx70(
2927
+ Chips,
2928
+ {
2929
+ chips: tabs.map((tab, index) => ({ label: tab.title, value: index })),
2930
+ selected: selectedIndex,
2931
+ onChange: ({ selectedValue }) => setSelectedIndex(Number(selectedValue))
2932
+ }
2933
+ ) }),
2934
+ /* @__PURE__ */ jsx70("div", { className: "m-t-2", children: (_a = tabs[selectedIndex]) == null ? void 0 : _a.children })
2935
+ ] });
2936
+ }
2937
+
2938
+ // ../renderers/src/TextInputRenderer.tsx
2939
+ import { InputGroup as InputGroup3 } from "@transferwise/components";
2940
+
2941
+ // ../renderers/src/components/VariableTextInput.tsx
24
2942
  import {
25
- Header,
26
- getMargin,
27
- getListItemRenderers,
28
- getButtonV2Renderers
29
- } from "@wise/dynamic-flow-renderers";
2943
+ Input as Input5,
2944
+ InputWithDisplayFormat,
2945
+ PhoneNumberInput,
2946
+ TextArea,
2947
+ TextareaWithDisplayFormat
2948
+ } from "@transferwise/components";
2949
+ import { jsx as jsx71 } from "react/jsx-runtime";
2950
+ var commonKeys = [
2951
+ "autoComplete",
2952
+ "autoCapitalize",
2953
+ "placeholder",
2954
+ "control",
2955
+ "disabled",
2956
+ "displayFormat",
2957
+ "id",
2958
+ "onBlur",
2959
+ "onFocus",
2960
+ "placeholder",
2961
+ "value"
2962
+ ];
2963
+ function VariableTextInput(inputProps) {
2964
+ const { id, value, control, onChange } = inputProps;
2965
+ const commonProps = __spreadProps(__spreadValues({}, pick(inputProps, ...commonKeys)), { name: id });
2966
+ switch (control) {
2967
+ case "email":
2968
+ return /* @__PURE__ */ jsx71(TextInput, __spreadProps(__spreadValues({}, commonProps), { type: "email", onChange }));
2969
+ case "password":
2970
+ return /* @__PURE__ */ jsx71(TextInput, __spreadProps(__spreadValues({}, commonProps), { type: "password", onChange }));
2971
+ case "numeric": {
2972
+ const numericProps = __spreadProps(__spreadValues({}, commonProps), { type: "number", onWheel });
2973
+ return /* @__PURE__ */ jsx71(
2974
+ TextInput,
2975
+ __spreadProps(__spreadValues({}, numericProps), {
2976
+ onChange: (newValue) => {
2977
+ const numericValueOrNull = !Number.isNaN(Number.parseFloat(newValue)) ? newValue : null;
2978
+ onChange(numericValueOrNull);
2979
+ }
2980
+ })
2981
+ );
2982
+ }
2983
+ case "phone-number":
2984
+ return /* @__PURE__ */ jsx71(PhoneNumberInput, __spreadProps(__spreadValues({ initialValue: value }, commonProps), { onChange }));
2985
+ default: {
2986
+ return /* @__PURE__ */ jsx71(TextInput, __spreadProps(__spreadValues({}, commonProps), { type: "text", onChange }));
2987
+ }
2988
+ }
2989
+ }
2990
+ function TextInput(props) {
2991
+ const _a = props, { control, displayFormat, onChange } = _a, commonProps = __objRest(_a, ["control", "displayFormat", "onChange"]);
2992
+ const InputWithPattern = control === "textarea" ? TextareaWithDisplayFormat : InputWithDisplayFormat;
2993
+ const InputWithoutPattern = control === "textarea" ? TextArea : Input5;
2994
+ return displayFormat ? /* @__PURE__ */ jsx71(InputWithPattern, __spreadProps(__spreadValues({ displayPattern: displayFormat }, commonProps), { onChange })) : /* @__PURE__ */ jsx71(InputWithoutPattern, __spreadProps(__spreadValues({}, commonProps), { onChange: (e) => onChange(e.target.value) }));
2995
+ }
2996
+
2997
+ // ../renderers/src/TextInputRenderer.tsx
2998
+ import { jsx as jsx72 } from "react/jsx-runtime";
2999
+ var TextInputRenderer = {
3000
+ canRenderType: "input-text",
3001
+ render: (props) => {
3002
+ const _a = props, {
3003
+ id,
3004
+ title,
3005
+ description,
3006
+ help,
3007
+ media,
3008
+ validationState,
3009
+ value: initialValue,
3010
+ onChange
3011
+ } = _a, rest = __objRest(_a, [
3012
+ "id",
3013
+ "title",
3014
+ "description",
3015
+ "help",
3016
+ "media",
3017
+ "validationState",
3018
+ "value",
3019
+ "onChange"
3020
+ ]);
3021
+ const value = initialValue != null ? initialValue : "";
3022
+ const inputProps = __spreadProps(__spreadValues({}, rest), {
3023
+ value,
3024
+ id,
3025
+ onChange: (newValue) => {
3026
+ if ((value != null ? value : "") !== (newValue != null ? newValue : "")) {
3027
+ onChange(newValue);
3028
+ }
3029
+ }
3030
+ });
3031
+ return /* @__PURE__ */ jsx72(
3032
+ FieldInput_default,
3033
+ {
3034
+ id,
3035
+ label: title,
3036
+ description,
3037
+ validation: validationState,
3038
+ help,
3039
+ children: /* @__PURE__ */ jsx72(InputGroup3, { addonStart: getInputGroupAddonStart(media), children: /* @__PURE__ */ jsx72(VariableTextInput, __spreadValues({}, inputProps)) })
3040
+ }
3041
+ );
3042
+ }
3043
+ };
3044
+ var TextInputRenderer_default = TextInputRenderer;
3045
+
3046
+ // ../renderers/src/UploadInputRenderer.tsx
3047
+ import { Upload, UploadInput as UploadInput2 } from "@transferwise/components";
3048
+
3049
+ // ../renderers/src/utils/getRandomId.ts
3050
+ var getRandomId = () => Math.random().toString(36).substring(2);
3051
+
3052
+ // ../renderers/src/UploadInputRenderer.tsx
3053
+ import { jsx as jsx73 } from "react/jsx-runtime";
3054
+ var UploadInputRenderer = {
3055
+ canRenderType: "input-upload",
3056
+ render: (props) => {
3057
+ const { id, accepts, title, description, disabled, maxSize, validationState, onUpload } = props;
3058
+ const onUploadFile = async (formData) => {
3059
+ const file = formData.get("file");
3060
+ return onUpload(file).then(() => ({
3061
+ id: getRandomId()
3062
+ }));
3063
+ };
3064
+ const onDeleteFile = async () => {
3065
+ await onUpload(null);
3066
+ };
3067
+ return (
3068
+ // We don't pass help here as there is no sensible place to display it
3069
+ /* @__PURE__ */ jsx73(
3070
+ UploadFieldInput_default,
3071
+ {
3072
+ id,
3073
+ label: void 0,
3074
+ description: void 0,
3075
+ validation: validationState,
3076
+ children: /* @__PURE__ */ jsx73(
3077
+ UploadInput2,
3078
+ {
3079
+ id,
3080
+ description,
3081
+ disabled,
3082
+ sizeLimit: getSizeLimit(maxSize),
3083
+ fileTypes: acceptsToFileTypes(accepts),
3084
+ uploadButtonTitle: title,
3085
+ onDeleteFile,
3086
+ onUploadFile
3087
+ }
3088
+ )
3089
+ }
3090
+ )
3091
+ );
3092
+ }
3093
+ };
3094
+ var LargeUploadRenderer = {
3095
+ canRenderType: "input-upload",
3096
+ canRender: (props) => props.control === "upload-large",
3097
+ render: (props) => {
3098
+ const _a = props, {
3099
+ id,
3100
+ accepts,
3101
+ control,
3102
+ title,
3103
+ description,
3104
+ disabled,
3105
+ help,
3106
+ type,
3107
+ validationState,
3108
+ maxSize = null,
3109
+ onUpload
3110
+ } = _a, rest = __objRest(_a, [
3111
+ "id",
3112
+ "accepts",
3113
+ "control",
3114
+ "title",
3115
+ "description",
3116
+ "disabled",
3117
+ "help",
3118
+ "type",
3119
+ "validationState",
3120
+ "maxSize",
3121
+ "onUpload"
3122
+ ]);
3123
+ const uploadProps = __spreadProps(__spreadValues({}, rest), { id, name: id, maxSize });
3124
+ const onUploadFile = async (file, fileName) => {
3125
+ try {
3126
+ const convertedFile = file ? await toFile(file, fileName) : null;
3127
+ await onUpload(convertedFile);
3128
+ } catch (e) {
3129
+ await onUpload(null);
3130
+ throw e;
3131
+ }
3132
+ };
3133
+ const filetypes = acceptsToFileTypes(accepts);
3134
+ const usAccept = filetypes === "*" ? "*" : filetypes.join(",");
3135
+ return /* @__PURE__ */ jsx73(
3136
+ FieldInput_default,
3137
+ {
3138
+ id,
3139
+ label: title,
3140
+ description,
3141
+ validation: validationState,
3142
+ help,
3143
+ children: /* @__PURE__ */ jsx73(
3144
+ Upload,
3145
+ __spreadProps(__spreadValues({}, uploadProps), {
3146
+ usAccept,
3147
+ usDisabled: disabled,
3148
+ onSuccess: onUploadFile,
3149
+ onFailure: async () => onUpload(null),
3150
+ onCancel: async () => onUpload(null)
3151
+ })
3152
+ )
3153
+ }
3154
+ );
3155
+ }
3156
+ };
3157
+
3158
+ // ../renderers/src/NewListItem/NewDecisionRenderer.tsx
3159
+ import { ListItem as ListItem4 } from "@transferwise/components";
3160
+
3161
+ // ../renderers/src/NewListItem/getInlineAlert.tsx
3162
+ import { ListItem as ListItem2 } from "@transferwise/components";
3163
+ import { jsx as jsx74 } from "react/jsx-runtime";
3164
+ var getInlineAlert = (inlineAlert) => inlineAlert ? /* @__PURE__ */ jsx74(ListItem2.Prompt, { sentiment: inlineAlert == null ? void 0 : inlineAlert.context, children: inlineAlert.content }) : void 0;
3165
+
3166
+ // ../renderers/src/NewListItem/getAdditionalInfo.tsx
3167
+ import { ListItem as ListItem3 } from "@transferwise/components";
3168
+ import { jsx as jsx75 } from "react/jsx-runtime";
3169
+ var getAdditionalInfo = (additionalInfo) => {
3170
+ if (!additionalInfo) {
3171
+ return void 0;
3172
+ }
3173
+ const { href, text, onClick } = additionalInfo;
3174
+ if (href || onClick) {
3175
+ return /* @__PURE__ */ jsx75(
3176
+ ListItem3.AdditionalInfo,
3177
+ {
3178
+ action: {
3179
+ label: text,
3180
+ href,
3181
+ onClick,
3182
+ target: "_blank"
3183
+ }
3184
+ }
3185
+ );
3186
+ }
3187
+ return /* @__PURE__ */ jsx75(ListItem3.AdditionalInfo, { children: additionalInfo == null ? void 0 : additionalInfo.text });
3188
+ };
3189
+
3190
+ // ../renderers/src/NewListItem/NewDecisionRenderer.tsx
3191
+ import { Fragment as Fragment12, jsx as jsx76 } from "react/jsx-runtime";
3192
+ var DecisionRenderer2 = {
3193
+ canRenderType: "decision",
3194
+ render: (props) => /* @__PURE__ */ jsx76(DecisionWrapper, __spreadProps(__spreadValues({}, props), { renderDecisionList: renderDecisionList2 }))
3195
+ };
3196
+ var renderDecisionList2 = ({ options, control }) => {
3197
+ return /* @__PURE__ */ jsx76(Fragment12, { children: options.map((option) => {
3198
+ const {
3199
+ description,
3200
+ disabled,
3201
+ media,
3202
+ title: itemTitle,
3203
+ tag,
3204
+ href,
3205
+ additionalText,
3206
+ inlineAlert,
3207
+ supportingValues,
3208
+ onClick
3209
+ } = option;
3210
+ return /* @__PURE__ */ jsx76(
3211
+ ListItem4,
3212
+ {
3213
+ title: itemTitle,
3214
+ subtitle: description,
3215
+ spotlight: control === "spotlight" ? tag === "spotlight-active" ? "active" : "inactive" : void 0,
3216
+ disabled,
3217
+ valueTitle: supportingValues == null ? void 0 : supportingValues.value,
3218
+ valueSubtitle: supportingValues == null ? void 0 : supportingValues.subvalue,
3219
+ media: getMedia(media, control === "with-avatar" || tag === "with-avatar"),
3220
+ prompt: getInlineAlert(inlineAlert),
3221
+ additionalInfo: additionalText ? getAdditionalInfo({ text: additionalText }) : void 0,
3222
+ control: href ? /* @__PURE__ */ jsx76(ListItem4.Navigation, { href, target: "_blank" }) : /* @__PURE__ */ jsx76(ListItem4.Navigation, { onClick })
3223
+ },
3224
+ JSON.stringify(option)
3225
+ );
3226
+ }) });
3227
+ };
3228
+ var NewDecisionRenderer_default = DecisionRenderer2;
3229
+
3230
+ // ../renderers/src/NewListItem/NewListRenderer.tsx
3231
+ import { ListItem as ListItem5 } from "@transferwise/components";
3232
+ import { jsx as jsx77, jsxs as jsxs30 } from "react/jsx-runtime";
3233
+ var ListRenderer2 = {
3234
+ canRenderType: "list",
3235
+ render: ({ callToAction, control, margin, items, title }) => /* @__PURE__ */ jsxs30("div", { className: getMargin(margin), children: [
3236
+ /* @__PURE__ */ jsx77(Header7, { title, callToAction }),
3237
+ items.map((item) => {
3238
+ const {
3239
+ title: itemTitle,
3240
+ description,
3241
+ supportingValues,
3242
+ media,
3243
+ tag,
3244
+ additionalInfo,
3245
+ inlineAlert
3246
+ } = item;
3247
+ return /* @__PURE__ */ jsx77(
3248
+ ListItem5,
3249
+ {
3250
+ title: itemTitle,
3251
+ subtitle: description,
3252
+ valueTitle: supportingValues == null ? void 0 : supportingValues.value,
3253
+ valueSubtitle: supportingValues == null ? void 0 : supportingValues.subvalue,
3254
+ media: getMedia(media, control === "with-avatar" || tag === "with-avatar"),
3255
+ prompt: getInlineAlert(inlineAlert),
3256
+ additionalInfo: getAdditionalInfo(additionalInfo)
3257
+ },
3258
+ itemTitle
3259
+ );
3260
+ })
3261
+ ] })
3262
+ };
3263
+ var NewListRenderer_default = ListRenderer2;
3264
+
3265
+ // ../renderers/src/NewListItem/NewReviewRenderer.tsx
3266
+ import { ListItem as ListItem6, Popover } from "@transferwise/components";
3267
+ import { QuestionMarkCircle } from "@transferwise/icons";
3268
+ import { jsx as jsx78, jsxs as jsxs31 } from "react/jsx-runtime";
3269
+ var IGNORED_CONTROLS = [
3270
+ "horizontal",
3271
+ "horizontal-end-aligned",
3272
+ "horizontal-start-aligned",
3273
+ "vertical-two-column"
3274
+ ];
3275
+ var ReviewRenderer2 = {
3276
+ canRenderType: "review",
3277
+ canRender: ({ control }) => control ? !IGNORED_CONTROLS.includes(control) : true,
3278
+ render: ({ callToAction, control, margin, fields, title }) => /* @__PURE__ */ jsxs31("div", { className: getMargin(margin), children: [
3279
+ /* @__PURE__ */ jsx78(Header7, { title, callToAction }),
3280
+ fields.map((field) => {
3281
+ var _a;
3282
+ const {
3283
+ label,
3284
+ value,
3285
+ media,
3286
+ tag,
3287
+ additionalInfo,
3288
+ inlineAlert,
3289
+ help,
3290
+ callToAction: itemCallToAction
3291
+ } = field;
3292
+ return /* @__PURE__ */ jsx78(
3293
+ ListItem6,
3294
+ {
3295
+ title: value,
3296
+ subtitle: label,
3297
+ inverted: true,
3298
+ media: getMedia(media, control === "with-avatar" || tag === "with-avatar"),
3299
+ control: (_a = getCTAControl(itemCallToAction)) != null ? _a : getHelpControl(help),
3300
+ prompt: getInlineAlert(inlineAlert),
3301
+ additionalInfo: getAdditionalInfo(additionalInfo)
3302
+ },
3303
+ JSON.stringify(field)
3304
+ );
3305
+ })
3306
+ ] })
3307
+ };
3308
+ var getCTAControl = (callToAction) => {
3309
+ if (!callToAction) {
3310
+ return void 0;
3311
+ }
3312
+ const { accessibilityDescription, href, title, onClick } = callToAction;
3313
+ if (href) {
3314
+ return /* @__PURE__ */ jsx78(ListItem6.Button, { href, partiallyInteractive: true, "aria-description": accessibilityDescription, children: title });
3315
+ }
3316
+ return /* @__PURE__ */ jsx78(
3317
+ ListItem6.Button,
3318
+ {
3319
+ "aria-description": accessibilityDescription,
3320
+ partiallyInteractive: true,
3321
+ onClick,
3322
+ children: title
3323
+ }
3324
+ );
3325
+ };
3326
+ var getHelpControl = (help) => {
3327
+ if (!help) {
3328
+ return void 0;
3329
+ }
3330
+ return /* @__PURE__ */ jsx78(Popover, { content: help, children: /* @__PURE__ */ jsx78(ListItem6.IconButton, { partiallyInteractive: true, children: /* @__PURE__ */ jsx78(QuestionMarkCircle, {}) }) });
3331
+ };
3332
+ var NewReviewRenderer_default = ReviewRenderer2;
3333
+
3334
+ // ../renderers/src/NewListItem/NewStatusListRenderer.tsx
3335
+ import { AvatarView as AvatarView4, Header as Header10, ListItem as ListItem7 } from "@transferwise/components";
3336
+ import { jsx as jsx79, jsxs as jsxs32 } from "react/jsx-runtime";
3337
+ var NewStatusListRenderer = {
3338
+ canRenderType: "status-list",
3339
+ render: ({ margin, items, title }) => /* @__PURE__ */ jsxs32("div", { className: getMargin(margin), children: [
3340
+ title ? /* @__PURE__ */ jsx79(Header10, { title, className: "m-b-2" }) : null,
3341
+ items.map((item) => {
3342
+ const { callToAction, description, icon, status, title: itemTitle } = item;
3343
+ return /* @__PURE__ */ jsx79(
3344
+ ListItem7,
3345
+ {
3346
+ title: itemTitle,
3347
+ subtitle: description,
3348
+ media: icon && "name" in icon ? /* @__PURE__ */ jsx79(AvatarView4, { badge: { status: mapStatus2(status) }, children: /* @__PURE__ */ jsx79(DynamicIcon_default, { name: icon.name }) }) : void 0,
3349
+ additionalInfo: callToAction ? /* @__PURE__ */ jsx79(
3350
+ ListItem7.AdditionalInfo,
3351
+ {
3352
+ action: {
3353
+ href: callToAction.href,
3354
+ onClick: callToAction.href ? void 0 : callToAction.onClick,
3355
+ label: callToAction.title,
3356
+ target: "_blank"
3357
+ }
3358
+ }
3359
+ ) : void 0
3360
+ },
3361
+ JSON.stringify(item)
3362
+ );
3363
+ })
3364
+ ] })
3365
+ };
3366
+ var mapStatus2 = (status) => {
3367
+ switch (status) {
3368
+ case "done":
3369
+ return "positive";
3370
+ case "pending":
3371
+ return "pending";
3372
+ default:
3373
+ return void 0;
3374
+ }
3375
+ };
3376
+ var NewStatusListRenderer_default = NewStatusListRenderer;
3377
+
3378
+ // ../renderers/src/ButtonRenderer/ButtonRendererV2.tsx
3379
+ import { Button as Button8 } from "@transferwise/components";
3380
+
3381
+ // ../renderers/src/utils/isButtonPriority.ts
3382
+ var validPriorities = ["primary", "secondary", "secondary-neutral", "tertiary"];
3383
+ var isButtonPriority = (control) => validPriorities.includes(control);
3384
+
3385
+ // ../renderers/src/ButtonRenderer/ButtonRendererV2.tsx
3386
+ import { useEffect as useEffect8, useState as useState12 } from "react";
3387
+ import { jsx as jsx80 } from "react/jsx-runtime";
3388
+ var ButtonRendererV2 = {
3389
+ canRenderType: "button",
3390
+ render: ButtonComponent2
3391
+ };
3392
+ function ButtonComponent2(props) {
3393
+ const { control, context, disabled, margin, title, size, stepLoadingState, onClick } = props;
3394
+ const [spinny, setSpinny] = useState12(false);
3395
+ useEffect8(() => {
3396
+ if (stepLoadingState === "idle") {
3397
+ setSpinny(false);
3398
+ }
3399
+ }, [stepLoadingState]);
3400
+ const loading = spinny && stepLoadingState !== "idle";
3401
+ return /* @__PURE__ */ jsx80(
3402
+ Button8,
3403
+ {
3404
+ v2: true,
3405
+ block: true,
3406
+ className: getMargin(margin),
3407
+ disabled,
3408
+ priority: getPriority3(control),
3409
+ loading,
3410
+ size: mapButtonSize(size),
3411
+ sentiment: getSentiment2(context),
3412
+ onClick: () => {
3413
+ setSpinny(true);
3414
+ onClick();
3415
+ },
3416
+ children: title
3417
+ }
3418
+ );
3419
+ }
3420
+ var getSentiment2 = (context) => context === "negative" ? "negative" : "default";
3421
+ var getPriority3 = (control) => control && isButtonPriority(control) ? control : "secondary";
3422
+
3423
+ // ../renderers/src/ProgressRenderer.tsx
3424
+ import { ProgressBar } from "@transferwise/components";
3425
+ import { jsx as jsx81 } from "react/jsx-runtime";
3426
+ var ProgressRenderer = {
3427
+ canRenderType: "progress",
3428
+ render: ({ uid, title, help, progress, progressText, margin, description }) => {
3429
+ return /* @__PURE__ */ jsx81(
3430
+ ProgressBar,
3431
+ {
3432
+ id: uid,
3433
+ className: getMargin(margin),
3434
+ title: title && help ? /* @__PURE__ */ jsx81(LabelContentWithHelp, { text: title, help }) : title,
3435
+ description,
3436
+ progress: {
3437
+ max: 1,
3438
+ value: progress
3439
+ },
3440
+ textEnd: progressText
3441
+ }
3442
+ );
3443
+ }
3444
+ };
3445
+
3446
+ // ../renderers/src/getWiseRenderers.ts
3447
+ var getListItemRenderers = () => [
3448
+ NewDecisionRenderer_default,
3449
+ NewListRenderer_default,
3450
+ NewReviewRenderer_default,
3451
+ NewStatusListRenderer_default
3452
+ ];
3453
+ var getButtonV2Renderers = () => [ButtonRendererV2];
3454
+ var getWiseRenderers = () => [
3455
+ AddressValidationButtonRenderer_default,
3456
+ AlertRenderer_default,
3457
+ CheckboxInputRenderer_default,
3458
+ BoxRenderer_default,
3459
+ ButtonRenderer,
3460
+ ColumnsRenderer_default,
3461
+ DateInputRenderer_default,
3462
+ DecisionRenderer_default,
3463
+ DividerRenderer_default,
3464
+ ExternalConfirmationRenderer_default,
3465
+ FormRenderer_default,
3466
+ FormSectionRenderer_default,
3467
+ HeadingRenderer_default,
3468
+ ImageRenderer_default,
3469
+ InstructionsRenderer_default,
3470
+ IntegerInputRenderer_default,
3471
+ LargeUploadRenderer,
3472
+ ListRenderer_default,
3473
+ LoadingIndicatorRenderer_default,
3474
+ MarkdownRenderer_default,
3475
+ ModalRenderer,
3476
+ ModalLayoutRenderer_default,
3477
+ MultiSelectInputRenderer_default,
3478
+ MultiUploadInputRenderer_default,
3479
+ NumberInputRenderer_default,
3480
+ ParagraphRenderer_default,
3481
+ ProgressRenderer,
3482
+ RepeatableRenderer_default,
3483
+ ReviewRenderer_default,
3484
+ SearchRenderer_default,
3485
+ SelectInputRenderer_default,
3486
+ SectionRenderer_default,
3487
+ StatusListRenderer_default,
3488
+ TabsRenderer,
3489
+ TextInputRenderer_default,
3490
+ UploadInputRenderer,
3491
+ SplashStepRenderer,
3492
+ SplashCelebrationStepRenderer,
3493
+ StepRenderer
3494
+ ];
3495
+
3496
+ // src/dynamicFlow/renderers.ts
3497
+ var Header11 = Header7;
3498
+ var Media2 = Media;
3499
+ var getMargin2 = getMargin;
3500
+ var getListItemRenderers2 = getListItemRenderers;
3501
+ var getButtonV2Renderers2 = getButtonV2Renderers;
30
3502
 
31
3503
  // src/i18n/index.ts
32
3504
  import { translations as coreTranslations } from "@wise/dynamic-flow-client";
@@ -873,14 +4345,13 @@ var translations = languages.reduce(
873
4345
  var i18n_default = translations;
874
4346
 
875
4347
  // src/dynamicFlow/DynamicFlow.tsx
876
- import { forwardRef, useCallback, useMemo } from "react";
877
- import { useIntl } from "react-intl";
4348
+ import { forwardRef, useCallback, useMemo as useMemo2 } from "react";
4349
+ import { useIntl as useIntl12 } from "react-intl";
878
4350
  import {
879
4351
  DynamicFlow as DynamicFlowCoreLegacy,
880
4352
  DynamicFlowCoreRevamp,
881
4353
  DynamicFormCore
882
4354
  } from "@wise/dynamic-flow-client";
883
- import { getWiseRenderers, useSnackBarIfAvailable } from "@wise/dynamic-flow-renderers";
884
4355
 
885
4356
  // src/dynamicFlow/telemetry/app-version.ts
886
4357
  var appVersion = (
@@ -912,7 +4383,6 @@ var logToRollbar = (level, message, extra) => {
912
4383
 
913
4384
  // src/dynamicFlow/telemetry/getTrackEvent.ts
914
4385
  import { isThemeModern } from "@wise/components-theming";
915
- import { ThemeRequiredEventName } from "@wise/dynamic-flow-renderers";
916
4386
  var getTrackEvent = (onEvent, onAnalytics, onThemeChange) => (name, properties) => {
917
4387
  onEvent == null ? void 0 : onEvent(name, properties);
918
4388
  if (name.includes(ThemeRequiredEventName)) {
@@ -926,8 +4396,8 @@ var getTrackEvent = (onEvent, onAnalytics, onThemeChange) => (name, properties)
926
4396
  };
927
4397
 
928
4398
  // src/dynamicFlow/messages.ts
929
- import { defineMessages } from "react-intl";
930
- var messages_default = defineMessages({
4399
+ import { defineMessages as defineMessages10 } from "react-intl";
4400
+ var messages_default = defineMessages10({
931
4401
  copied: {
932
4402
  id: "df.wise.CopyFeedback.copy",
933
4403
  defaultMessage: "Copied to clipboard",
@@ -941,12 +4411,12 @@ var messages_default = defineMessages({
941
4411
  });
942
4412
 
943
4413
  // src/dynamicFlow/DynamicFlow.tsx
944
- import { jsx } from "react/jsx-runtime";
4414
+ import { jsx as jsx82 } from "react/jsx-runtime";
945
4415
  var wiseRenderers = getWiseRenderers();
946
4416
  function DynamicFlowLegacy(props) {
947
4417
  const { customFetch = globalThis.fetch } = props;
948
4418
  const coreProps = __spreadProps(__spreadValues({}, props), { httpClient: customFetch });
949
- return /* @__PURE__ */ jsx(DynamicFlowCoreLegacy, __spreadValues({}, coreProps));
4419
+ return /* @__PURE__ */ jsx82(DynamicFlowCoreLegacy, __spreadValues({}, coreProps));
950
4420
  }
951
4421
  function DynamicFlowRevamp(props) {
952
4422
  const {
@@ -959,12 +4429,12 @@ function DynamicFlowRevamp(props) {
959
4429
  onLink = openLinkInNewTab,
960
4430
  onThemeChange
961
4431
  } = props;
962
- const { formatMessage } = useIntl();
4432
+ const { formatMessage } = useIntl12();
963
4433
  const createSnackBar = useSnackBarIfAvailable();
964
4434
  const httpClient = useWiseHttpClient(customFetch);
965
- const mergedRenderers = useMemo(() => [...renderers != null ? renderers : [], ...wiseRenderers], [renderers]);
966
- const logEvent = useMemo(() => getLogEvent(onLog), [onLog]);
967
- const trackEvent = useMemo(
4435
+ const mergedRenderers = useMemo2(() => [...renderers != null ? renderers : [], ...wiseRenderers], [renderers]);
4436
+ const logEvent = useMemo2(() => getLogEvent(onLog), [onLog]);
4437
+ const trackEvent = useMemo2(
968
4438
  () => getTrackEvent(onEvent, onAnalytics, onThemeChange),
969
4439
  [onEvent, onAnalytics, onThemeChange]
970
4440
  );
@@ -983,7 +4453,7 @@ function DynamicFlowRevamp(props) {
983
4453
  onLink,
984
4454
  onCopy
985
4455
  });
986
- return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(DynamicFlowCoreRevamp, __spreadValues({}, coreProps)) });
4456
+ return /* @__PURE__ */ jsx82("div", { className, children: /* @__PURE__ */ jsx82(DynamicFlowCoreRevamp, __spreadValues({}, coreProps)) });
987
4457
  }
988
4458
  var DynamicForm = forwardRef(function DynamicForm2(props, ref) {
989
4459
  const {
@@ -996,12 +4466,12 @@ var DynamicForm = forwardRef(function DynamicForm2(props, ref) {
996
4466
  onLink = openLinkInNewTab,
997
4467
  onThemeChange
998
4468
  } = props;
999
- const { formatMessage } = useIntl();
4469
+ const { formatMessage } = useIntl12();
1000
4470
  const createSnackBar = useSnackBarIfAvailable();
1001
4471
  const httpClient = useWiseHttpClient(customFetch);
1002
- const mergedRenderers = useMemo(() => [...renderers != null ? renderers : [], ...wiseRenderers], [renderers]);
1003
- const logEvent = useMemo(() => getLogEvent(onLog), [onLog]);
1004
- const trackEvent = useMemo(
4472
+ const mergedRenderers = useMemo2(() => [...renderers != null ? renderers : [], ...wiseRenderers], [renderers]);
4473
+ const logEvent = useMemo2(() => getLogEvent(onLog), [onLog]);
4474
+ const trackEvent = useMemo2(
1005
4475
  () => getTrackEvent(onEvent, onAnalytics, onThemeChange),
1006
4476
  [onEvent, onAnalytics, onThemeChange]
1007
4477
  );
@@ -1020,10 +4490,10 @@ var DynamicForm = forwardRef(function DynamicForm2(props, ref) {
1020
4490
  onLink,
1021
4491
  onCopy
1022
4492
  });
1023
- return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(DynamicFormCore, __spreadProps(__spreadValues({}, coreProps), { ref })) });
4493
+ return /* @__PURE__ */ jsx82("div", { className, children: /* @__PURE__ */ jsx82(DynamicFormCore, __spreadProps(__spreadValues({}, coreProps), { ref })) });
1024
4494
  });
1025
4495
  var useWiseHttpClient = (httpClient) => {
1026
- const { locale } = useIntl();
4496
+ const { locale } = useIntl12();
1027
4497
  return useCallback(
1028
4498
  async (input, init = {}) => {
1029
4499
  const headers = new Headers(init.headers);
@@ -1051,12 +4521,13 @@ export {
1051
4521
  DynamicFlowLegacy,
1052
4522
  DynamicFlowRevamp,
1053
4523
  DynamicForm,
1054
- Header,
4524
+ Header11 as Header,
1055
4525
  JsonSchemaForm,
4526
+ Media2 as Media,
1056
4527
  findRendererPropsByType,
1057
- getButtonV2Renderers,
1058
- getListItemRenderers,
1059
- getMargin,
4528
+ getButtonV2Renderers2 as getButtonV2Renderers,
4529
+ getListItemRenderers2 as getListItemRenderers,
4530
+ getMargin2 as getMargin,
1060
4531
  isValidSchema,
1061
4532
  makeHttpClient as makeCustomFetch,
1062
4533
  i18n_default as translations