@wf-financing/ui 4.6.2 → 4.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ui.css CHANGED
@@ -1 +1 @@
1
- :root,:host{--app-theme-key: wayflyer;--app-override-key: wayflyer;--defaults-borderRadius: 8px;--defaults-button-borderRadius: 8px;--defaults-button-sizes-normal: 40px;--defaults-button-sizes-small: 32px;--defaults-modal-large-width-lg: 900px;--defaults-modal-large-width-md: 900px;--defaults-modal-normal-width-lg: 600px;--defaults-modal-normal-width-md: 504px;--defaults-page-width: 968px;--sizes-spacing-0: 0px;--sizes-spacing-0-5: 2px;--sizes-spacing-1: 4px;--sizes-spacing-1-5: 6px;--sizes-spacing-2: 8px;--sizes-spacing-3: 12px;--sizes-spacing-4: 16px;--sizes-spacing-5: 20px;--sizes-spacing-6: 24px;--sizes-spacing-7: 28px;--sizes-spacing-8: 32px;--sizes-spacing-9: 36px;--sizes-spacing-10: 40px;--sizes-spacing-11: 44px;--sizes-spacing-12: 48px;--sizes-spacing-13: 52px;--sizes-spacing-14: 56px;--sizes-spacing-15: 60px;--sizes-spacing-16: 64px;--sizes-spacing-17: 68px;--sizes-spacing-18: 72px;--sizes-spacing-19: 76px;--sizes-spacing-20: 80px;--sizes-spacing-24: 96px;--sizes-spacing-32: 128px;--sizes-spacing-auto: auto;--cta-content: default;--cta-surface: light;--effects-blur: blur(6px);--effects-focus: 0px 0px 0px 1px #FFFFFF, 0px 0px 0px 2px var(--palette-border-interactive-focusRingOuter);--effects-shadow: 0px 2px 20px rgba(22, 21, 23, .08);--palette-bg-accent-strong: #001eff;--palette-bg-accent-subtle: #e4edff;--palette-bg-interactive-active: #000000;--palette-bg-interactive-activeInverse: #ffffff;--palette-bg-interactive-activeSubtle: #000000;--palette-bg-interactive-activeSubtleInverse: #ffffff;--palette-bg-interactive-hover: #000000;--palette-bg-interactive-hoverInverse: #ffffff;--palette-bg-interactive-hoverSubtle: #000000;--palette-bg-interactive-hoverSubtleInverse: #ffffff;--palette-bg-neutral-base: #ffffff;--palette-bg-neutral-inverse: #333333;--palette-bg-neutral-overlay: #000000;--palette-bg-neutral-strong: #d9d9d9;--palette-bg-neutral-subtle: #f5f5f5;--palette-bg-status-critical: #fde4e4;--palette-bg-status-criticalStrong: #cf2048;--palette-bg-status-info: #dcf0fe;--palette-bg-status-neutral: #ededed;--palette-bg-status-positive: #d8f3d8;--palette-bg-status-warning: #ffe4d7;--palette-border-accent-strong: #001eff;--palette-border-interactive-active: #000000;--palette-border-interactive-activeInverse: #ffffff;--palette-border-interactive-focusRingInner: #ffffff;--palette-border-interactive-focusRingInnerInverse: #333333;--palette-border-interactive-focusRingOuter: #001eff;--palette-border-interactive-focusRingOuterInverse: #f0f5ff;--palette-border-interactive-hover: #000000;--palette-border-interactive-hoverInverse: #ffffff;--palette-border-neutral-inverse: #333333;--palette-border-neutral-onInverse: #ffffff;--palette-border-neutral-strong: #8d8d8d;--palette-border-neutral-subtle: #d9d9d9;--palette-border-status-critical: #cf2048;--palette-border-status-info: #3090c7;--palette-border-status-neutral: #8d8d8d;--palette-border-status-positive: #4e9655;--palette-border-status-warning: #eb5029;--palette-content-accent-onAccent: #ffffff;--palette-content-accent-strong: #001eff;--palette-content-interactive-active: #000000;--palette-content-interactive-activeInverse: #ffffff;--palette-content-interactive-hover: #000000;--palette-content-interactive-hoverInverse: #ffffff;--palette-content-neutral-onInverse: #ffffff;--palette-content-neutral-strong: #333333;--palette-content-neutral-subtle: #737373;--palette-content-status-critical: #cf2048;--palette-content-status-info: #3090c7;--palette-content-status-neutral: #333333;--palette-content-status-onCritical: #ffffff;--palette-content-status-positive: #4e9655;--palette-content-status-warning: #eb5029;--palette-datavis-accent: #001eff;--palette-datavis-accentStrong: #000b6a;--palette-datavis-accentSubtle: #82aaff;--sizes-blur-100: 12px;--sizes-breakpoint-lg: 1280px;--sizes-breakpoint-md: 1024px;--sizes-breakpoint-sm: 768px;--sizes-breakpoint-xl: 1536px;--sizes-breakpoint-xs: 640px;--sizes-breakpoint-xxl: 1920px;--sizes-breakpoint-xxs: 375px;--sizes-breakpoint-xxxl: 2560px;--sizes-breakpoint-xxxs: 320px;--sizes-radius-2xl: 24px;--sizes-radius-full: 9999px;--sizes-radius-lg: 12px;--sizes-radius-md: 8px;--sizes-radius-none: 0px;--sizes-radius-sm: 4px;--sizes-radius-xl: 16px;--sizes-stroke-default: 1px;--sizes-stroke-focusRing: 2px;--sizes-stroke-strong: 2px;--typography-fontFamily-primaryTypeface: Inter;--typography-fontFamily-secondaryTypeface: Inter;--typography-fontSize-2xl: 22px;--typography-fontSize-3xl: 24px;--typography-fontSize-4xl: 28px;--typography-fontSize-5xl: 32px;--typography-fontSize-6xl: 36px;--typography-fontSize-lg: 18px;--typography-fontSize-md: 16px;--typography-fontSize-sm: 14px;--typography-fontSize-xl: 20px;--typography-fontSize-xs: 12px;--typography-fontWeight-medium: 500;--typography-fontWeight-mediumItalic: 500;--typography-fontWeight-regular: 400;--typography-fontWeight-regularItalic: 400;--typography-fontWeight-semibold: 600;--typography-fontWeight-semiboldItalic: 600;--typography-lineHeight-loose: 1.5;--typography-lineHeight-none: 1;--typography-lineHeight-normal: 1.4;--typography-lineHeight-tight: 1.2;--extendedPalette-chart-background: #fff;--extendedPalette-chart-boxShadow: 0 3px 6px -4px rgba(0, 0, 0, .12), 0 6px 16px 0 rgba(0, 0, 0, .08), 0 9px 28px 8px rgba(0, 0, 0, .05);--extendedPalette-chart-color: fade(@black, 85%);--extendedPalette-chart-colors-deselectedColor: #C0C0C0;--extendedPalette-chart-colors-gridColor: #E8E8E8;--extendedPalette-chart-colors-primaryColor: #54C4FC;--extendedPalette-chart-colors-primaryLabelColor: #262626;--extendedPalette-chart-colors-secondaryColor: #FCB779;--extendedPalette-chart-colors-secondaryColorPaler: #ada8ae;--extendedPalette-chart-colors-secondaryLabelColor: #8c8c8c;--extendedPalette-chart-delta-negative: #AD0000;--extendedPalette-chart-delta-positive: #0D610C;--extendedPalette-chart-multichartColors-chart1: #6B7280;--extendedPalette-chart-multichartColors-chart10: #6366F1;--extendedPalette-chart-multichartColors-chart11: #8B5CF6;--extendedPalette-chart-multichartColors-chart12: #EC4899;--extendedPalette-chart-multichartColors-chart13: #F43F5E;--extendedPalette-chart-multichartColors-chart2: #EF4444;--extendedPalette-chart-multichartColors-chart3: #F97316;--extendedPalette-chart-multichartColors-chart4: #F59E0B;--extendedPalette-chart-multichartColors-chart5: #0D610C;--extendedPalette-chart-multichartColors-chart6: #14B8A6;--extendedPalette-chart-multichartColors-chart7: #06B6D4;--extendedPalette-chart-multichartColors-chart8: #0EA5E9;--extendedPalette-chart-multichartColors-chart9: #3B82F6;--extendedPalette-chart-multiLineBarChartColors-bar-color1: #A7F3D0;--extendedPalette-chart-multiLineBarChartColors-bar-color2: #34D399;--extendedPalette-chart-multiLineBarChartColors-bar-color3: #059669;--extendedPalette-chart-multiLineBarChartColors-bar-color4: #06B6D4;--extendedPalette-chart-multiLineBarChartColors-bar-color5: #0EA5E9;--extendedPalette-chart-multiLineBarChartColors-bar-color6: #3B82F6;--extendedPalette-chart-multiLineBarChartColors-line-color1: #F59E0B;--extendedPalette-chart-multiLineBarChartColors-line-color2: #6366F1;--extendedPalette-chart-multiLineBarChartColors-line-color3: #EF4444;--extendedPalette-chart-multiLineBarChartColors-line-color4: #10B981;--extendedPalette-chart-multiLineBarChartColors-line-color5: #EC4899;--extendedPalette-chart-multiLineBarChartColors-line-color6: #F43F5E;--extendedPalette-chart-shadowColor: rgba(0, 0, 0, .15);--extendedPalette-pinnedMetrics-borderColor-default: #FFFFFF;--extendedPalette-pinnedMetrics-borderColor-sorted: #1D44CE;--extendedPalette-pinnedMetrics-borderColor-summary: #0D610C;--extendedPalette-pinnedMetrics-borderStyle: solid;--extendedPalette-pinnedMetrics-borderWidth: 2;--extendedPalette-scaler-iconColor: #ffffff;--extendedPalette-task-completed: #059669;--extendedPalette-task-pending: #faad14}
1
+ :root,:host{--app-theme-key: wayflyer;--app-override-key: wayflyer;--defaults-borderRadius: 8px;--defaults-button-borderRadius: 9999px;--defaults-button-sizes-normal: 40px;--defaults-button-sizes-small: 32px;--defaults-modal-large-width-lg: 900px;--defaults-modal-large-width-md: 900px;--defaults-modal-normal-width-lg: 600px;--defaults-modal-normal-width-md: 504px;--defaults-page-width: 968px;--sizes-spacing-0: 0px;--sizes-spacing-0-5: 2px;--sizes-spacing-1: 4px;--sizes-spacing-1-5: 6px;--sizes-spacing-2: 8px;--sizes-spacing-3: 12px;--sizes-spacing-4: 16px;--sizes-spacing-5: 20px;--sizes-spacing-6: 24px;--sizes-spacing-7: 28px;--sizes-spacing-8: 32px;--sizes-spacing-9: 36px;--sizes-spacing-10: 40px;--sizes-spacing-11: 44px;--sizes-spacing-12: 48px;--sizes-spacing-13: 52px;--sizes-spacing-14: 56px;--sizes-spacing-15: 60px;--sizes-spacing-16: 64px;--sizes-spacing-17: 68px;--sizes-spacing-18: 72px;--sizes-spacing-19: 76px;--sizes-spacing-20: 80px;--sizes-spacing-24: 96px;--sizes-spacing-32: 128px;--sizes-spacing-auto: auto;--cta-content: default;--cta-surface: light;--effects-blur: blur(6px);--effects-focus: 0px 0px 0px 1px #FFFFFF, 0px 0px 0px 2px var(--palette-border-interactive-focusRingOuter);--effects-shadow: 0px 2px 20px rgba(22, 21, 23, .08);--palette-bg-accent-strong: #001eff;--palette-bg-accent-subtle: #e4edff;--palette-bg-interactive-active: #000000;--palette-bg-interactive-activeInverse: #ffffff;--palette-bg-interactive-activeSubtle: #000000;--palette-bg-interactive-activeSubtleInverse: #ffffff;--palette-bg-interactive-hover: #000000;--palette-bg-interactive-hoverInverse: #ffffff;--palette-bg-interactive-hoverSubtle: #000000;--palette-bg-interactive-hoverSubtleInverse: #ffffff;--palette-bg-neutral-base: #ffffff;--palette-bg-neutral-inverse: #333333;--palette-bg-neutral-medium: #f5f5f5;--palette-bg-neutral-overlay: #000000;--palette-bg-neutral-step: #929292;--palette-bg-neutral-strong: #d9d9d9;--palette-bg-neutral-subtle: #f9f9f8;--palette-bg-status-critical: #fde4e4;--palette-bg-status-criticalStrong: #cf2048;--palette-bg-status-info: #dcf0fe;--palette-bg-status-neutral: #ededed;--palette-bg-status-positive: #d8f3d8;--palette-bg-status-positiveStrong: #48834d;--palette-bg-status-warning: #ffe4d7;--palette-bg-status-warningStrong: #c94f30;--palette-border-accent-strong: #001eff;--palette-border-interactive-active: #000000;--palette-border-interactive-activeInverse: #ffffff;--palette-border-interactive-focusRingInner: #ffffff;--palette-border-interactive-focusRingInnerInverse: #333333;--palette-border-interactive-focusRingOuter: #001eff;--palette-border-interactive-focusRingOuterInverse: #f0f5ff;--palette-border-interactive-hover: #000000;--palette-border-interactive-hoverInverse: #ffffff;--palette-border-neutral-inverse: #333333;--palette-border-neutral-onInverse: #ffffff;--palette-border-neutral-strong: #8d8d8d;--palette-border-neutral-subtle: #d9d9d9;--palette-border-status-critical: #cf2048;--palette-border-status-info: #117baf;--palette-border-status-neutral: #8d8d8d;--palette-border-status-positive: #48834d;--palette-border-status-warning: #c94f30;--palette-content-accent-onAccent: #ffffff;--palette-content-accent-strong: #001eff;--palette-content-interactive-active: #000000;--palette-content-interactive-activeInverse: #ffffff;--palette-content-interactive-hover: #000000;--palette-content-interactive-hoverInverse: #ffffff;--palette-content-neutral-onInverse: #ffffff;--palette-content-neutral-strong: #333333;--palette-content-neutral-subtle: #737373;--palette-content-status-critical: #cf2048;--palette-content-status-info: #117baf;--palette-content-status-neutral: #333333;--palette-content-status-onCritical: #ffffff;--palette-content-status-positive: #48834d;--palette-content-status-warning: #c94f30;--palette-datavis-accent: #001eff;--palette-datavis-accentStrong: #000b6a;--palette-datavis-accentSubtle: #82aaff;--sizes-blur-100: 12px;--sizes-breakpoint-lg: 1280px;--sizes-breakpoint-md: 1024px;--sizes-breakpoint-sm: 768px;--sizes-breakpoint-xl: 1536px;--sizes-breakpoint-xs: 640px;--sizes-breakpoint-xxl: 1920px;--sizes-breakpoint-xxs: 375px;--sizes-breakpoint-xxxl: 2560px;--sizes-breakpoint-xxxs: 320px;--sizes-radius-2xl: 24px;--sizes-radius-full: 9999px;--sizes-radius-lg: 12px;--sizes-radius-md: 8px;--sizes-radius-none: 0px;--sizes-radius-sm: 4px;--sizes-radius-xl: 16px;--sizes-stroke-default: 1px;--sizes-stroke-focusRing: 2px;--sizes-stroke-strong: 2px;--typography-fontFamily-primaryTypeface: Inter;--typography-fontFamily-secondaryTypeface: Inter;--typography-fontSize-2xl: 22px;--typography-fontSize-3xl: 24px;--typography-fontSize-4xl: 28px;--typography-fontSize-5xl: 32px;--typography-fontSize-6xl: 36px;--typography-fontSize-lg: 18px;--typography-fontSize-md: 16px;--typography-fontSize-sm: 14px;--typography-fontSize-xl: 20px;--typography-fontSize-xs: 12px;--typography-fontWeight-medium: 500;--typography-fontWeight-mediumItalic: 500;--typography-fontWeight-regular: 400;--typography-fontWeight-regularItalic: 400;--typography-fontWeight-semibold: 600;--typography-fontWeight-semiboldItalic: 600;--typography-lineHeight-loose: 1.5;--typography-lineHeight-none: 1;--typography-lineHeight-normal: 1.4;--typography-lineHeight-tight: 1.2;--extendedPalette-chart-background: #fff;--extendedPalette-chart-boxShadow: 0 3px 6px -4px rgba(0, 0, 0, .12), 0 6px 16px 0 rgba(0, 0, 0, .08), 0 9px 28px 8px rgba(0, 0, 0, .05);--extendedPalette-chart-color: fade(@black, 85%);--extendedPalette-chart-colors-deselectedColor: #C0C0C0;--extendedPalette-chart-colors-gridColor: #E8E8E8;--extendedPalette-chart-colors-primaryColor: #54C4FC;--extendedPalette-chart-colors-primaryLabelColor: #262626;--extendedPalette-chart-colors-secondaryColor: #FCB779;--extendedPalette-chart-colors-secondaryColorPaler: #ada8ae;--extendedPalette-chart-colors-secondaryLabelColor: #8c8c8c;--extendedPalette-chart-delta-negative: #AD0000;--extendedPalette-chart-delta-positive: #0D610C;--extendedPalette-chart-multichartColors-chart1: #6B7280;--extendedPalette-chart-multichartColors-chart10: #6366F1;--extendedPalette-chart-multichartColors-chart11: #8B5CF6;--extendedPalette-chart-multichartColors-chart12: #EC4899;--extendedPalette-chart-multichartColors-chart13: #F43F5E;--extendedPalette-chart-multichartColors-chart2: #EF4444;--extendedPalette-chart-multichartColors-chart3: #F97316;--extendedPalette-chart-multichartColors-chart4: #F59E0B;--extendedPalette-chart-multichartColors-chart5: #0D610C;--extendedPalette-chart-multichartColors-chart6: #14B8A6;--extendedPalette-chart-multichartColors-chart7: #06B6D4;--extendedPalette-chart-multichartColors-chart8: #0EA5E9;--extendedPalette-chart-multichartColors-chart9: #3B82F6;--extendedPalette-chart-multiLineBarChartColors-bar-color1: #A7F3D0;--extendedPalette-chart-multiLineBarChartColors-bar-color2: #34D399;--extendedPalette-chart-multiLineBarChartColors-bar-color3: #059669;--extendedPalette-chart-multiLineBarChartColors-bar-color4: #06B6D4;--extendedPalette-chart-multiLineBarChartColors-bar-color5: #0EA5E9;--extendedPalette-chart-multiLineBarChartColors-bar-color6: #3B82F6;--extendedPalette-chart-multiLineBarChartColors-line-color1: #F59E0B;--extendedPalette-chart-multiLineBarChartColors-line-color2: #6366F1;--extendedPalette-chart-multiLineBarChartColors-line-color3: #EF4444;--extendedPalette-chart-multiLineBarChartColors-line-color4: #10B981;--extendedPalette-chart-multiLineBarChartColors-line-color5: #EC4899;--extendedPalette-chart-multiLineBarChartColors-line-color6: #F43F5E;--extendedPalette-chart-shadowColor: rgba(0, 0, 0, .15);--extendedPalette-pinnedMetrics-borderColor-default: #FFFFFF;--extendedPalette-pinnedMetrics-borderColor-sorted: #1D44CE;--extendedPalette-pinnedMetrics-borderColor-summary: #0D610C;--extendedPalette-pinnedMetrics-borderStyle: solid;--extendedPalette-pinnedMetrics-borderWidth: 2;--extendedPalette-scaler-iconColor: #ffffff;--extendedPalette-task-completed: #059669;--extendedPalette-task-pending: #faad14}
package/global.d.ts CHANGED
@@ -4,5 +4,7 @@ declare global {
4
4
  interface Window {
5
5
  WayflyerUiSdk: IWayflyerUiSdkConstructor;
6
6
  WayflyerHeadlessSdk: IWayflyerHeadlessSdkConstructor;
7
+
8
+ WayflyerHostedCapitalBaseUrl: string;
7
9
  }
8
10
  }
package/index.ts CHANGED
@@ -5,7 +5,8 @@ const addUiSdkToWindow = () => {
5
5
 
6
6
  window.WayflyerUiSdk = WayflyerUiSdk;
7
7
  /**
8
- * Trigger event handler in entry point that notifies it that the SDK is ready to use. See packages/ui-sdk-entry/utils/loadUiSdkScript.ts
8
+ * Trigger event handler in entry point that notifies it that the SDK is ready to use.
9
+ * See packages/ui-sdk-entry/utils/loadUiSdkScript.ts
9
10
  */
10
11
  window.dispatchEvent(new CustomEvent(UI_SDK_READY_EVENT));
11
12
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wf-financing/ui",
3
- "version": "4.6.2",
3
+ "version": "4.7.1",
4
4
  "exports": {
5
5
  ".": {
6
6
  "import": "./dist/index.es.js",
@@ -38,8 +38,10 @@
38
38
  "react-markdown": "^10.1.0",
39
39
  "styled-components": "^6.1.19",
40
40
  "@wf-financing/embedded-types": "1.1.1",
41
+ "@wf-financing/headless": "3.3.3",
41
42
  "@wf-financing/logger": "2.2.2",
42
- "@wf-financing/ui-assets": "1.1.3"
43
+ "@wf-financing/ui-assets": "1.1.3",
44
+ "@wf-financing/embedded-journey": "0.2.0"
43
45
  },
44
46
  "publishConfig": {
45
47
  "access": "public"
@@ -48,6 +50,7 @@
48
50
  "clean": "rm -rf dist",
49
51
  "dev": "vite",
50
52
  "build": "vite build",
53
+ "build-dev": "NODE_ENV=development vite build --mode development",
51
54
  "preview": "vite preview",
52
55
  "analyze": "vite build --mode analyze-html && npx http-server dist/bundle-stats -p 8083",
53
56
  "publish-sdk-cta-ui": "pnpm clean && pnpm build && pnpm publish --access public --no-git-checks",
package/src/CtaWidget.tsx CHANGED
@@ -1,11 +1,11 @@
1
- import { useState } from 'react';
1
+ import { useState, lazy, Suspense, ComponentProps } from 'react';
2
2
  import type { CtaResponseType, ContinueHostedApplicationResponseType } from '@wf-financing/embedded-types';
3
3
  import type { Copy } from '@wf-financing/ui-assets';
4
4
 
5
5
  import { CtaBanner } from './components/banner/CtaBanner';
6
- import { ConsentModal } from './components/modal/ConsentModal.tsx';
7
6
  import { buildCtaUiProps } from './utils';
8
- import { useContinueHostedApplication, useNotificationOnRender } from './hooks';
7
+ import { useContinueHostedApplication, useNotificationOnRender, usePartnerContext } from './hooks';
8
+ import { IS_EMBEDDED_JOURNEY } from './config';
9
9
 
10
10
  type CtaWidgetProps = {
11
11
  cta: Exclude<CtaResponseType, null>;
@@ -13,12 +13,16 @@ type CtaWidgetProps = {
13
13
  skipAnimation: boolean;
14
14
  };
15
15
 
16
+ const EmbeddedJourneyPanel = lazy(() => import('@wf-financing/embedded-journey/embedded-journey-panel'));
17
+ const ConsentModal = lazy(() => import('./components/modal/ConsentModal'));
18
+
16
19
  export const CtaWidget = ({ cta, copy, skipAnimation }: CtaWidgetProps) => {
17
- const [isModalOpen, setIsModalOpen] = useState(false);
20
+ const [isWidgetOpen, setIsWidgetOpen] = useState(false);
18
21
  const { mutate: continueHostedApplicationMutation } = useContinueHostedApplication();
19
22
  const sendNotification = useNotificationOnRender();
23
+ const { portalContainer } = usePartnerContext();
20
24
 
21
- const handleIsModalOpen = () => setIsModalOpen(() => !isModalOpen);
25
+ const toggleIsWidgetOpen = () => setIsWidgetOpen((isOpen) => !isOpen);
22
26
  const handleContinueHostedApplication = () => {
23
27
  continueHostedApplicationMutation(undefined, {
24
28
  onSuccess: (nextUrl: ContinueHostedApplicationResponseType) => {
@@ -34,16 +38,30 @@ export const CtaWidget = ({ cta, copy, skipAnimation }: CtaWidgetProps) => {
34
38
  const { bannerProps, consentModalProps, partnerTemplateProps } = buildCtaUiProps(
35
39
  cta,
36
40
  copy,
37
- handleIsModalOpen,
41
+ toggleIsWidgetOpen,
38
42
  handleContinueHostedApplication,
39
43
  );
40
44
 
41
45
  sendNotification(cta, bannerProps);
42
46
 
47
+ const embeddedJourneyPanelProps: ComponentProps<typeof EmbeddedJourneyPanel> = {
48
+ portalContainer,
49
+ isOpen: isWidgetOpen,
50
+ closePanel: () => toggleIsWidgetOpen(),
51
+ };
52
+
43
53
  return (
44
54
  <>
45
55
  <CtaBanner skipAnimation={skipAnimation} {...bannerProps} />
46
- {consentModalProps && <ConsentModal {...consentModalProps} {...partnerTemplateProps} isModalOpen={isModalOpen} />}
56
+ <Suspense fallback={null}>
57
+ {IS_EMBEDDED_JOURNEY ? (
58
+ <EmbeddedJourneyPanel {...embeddedJourneyPanelProps} />
59
+ ) : (
60
+ consentModalProps && (
61
+ <ConsentModal {...consentModalProps} {...partnerTemplateProps} isModalOpen={isWidgetOpen} />
62
+ )
63
+ )}
64
+ </Suspense>
47
65
  </>
48
66
  );
49
67
  };
@@ -1,52 +1,47 @@
1
- import { afterEach, describe, expect, Mock, test, vi } from 'vitest';
1
+ import { beforeEach, describe, expect, test, vi } from 'vitest';
2
2
 
3
- vi.mock('./getHeadlessSdkInstance', () => ({
4
- getHeadlessSdkInstance: vi.fn(),
3
+ const mockSetCompanyToken = vi.fn();
4
+ const MockHeadlessSdk = vi.fn(() => ({
5
+ setCompanyToken: mockSetCompanyToken,
5
6
  }));
6
7
 
7
- import { getHeadlessSdkInstance } from './getHeadlessSdkInstance';
8
- import { startHostedApplication } from './startHostedApplication';
9
-
10
- const fakeSdk = {
11
- getCta: vi.fn(),
12
- startHostedApplication: vi.fn(),
13
- };
14
-
15
- const options = {
16
- isSandbox: true,
17
- };
8
+ vi.mock('@wf-financing/headless/sdk', () => ({
9
+ HeadlessSdk: MockHeadlessSdk,
10
+ }));
18
11
 
19
- describe('startHostedApplication', () => {
20
- afterEach(() => {
12
+ describe('getHeadlessSdkInstance', () => {
13
+ beforeEach(() => {
21
14
  vi.clearAllMocks();
15
+ vi.resetModules();
22
16
  });
23
17
 
24
- test('calls sdk.startHostedApplication with partnerData and returns nextUrl', async () => {
25
- const fakePartnerData = { foo: 1 };
26
- const fakeNextUrl = '/next-url';
27
- const partnerCallback = vi.fn().mockResolvedValue(fakePartnerData);
28
-
29
- (getHeadlessSdkInstance as unknown as Mock).mockResolvedValueOnce(fakeSdk);
30
- fakeSdk.startHostedApplication.mockResolvedValueOnce(fakeNextUrl);
18
+ test('creates a new HeadlessSdk instance on first call', async () => {
19
+ const { getHeadlessSdkInstance } = await import('./getHeadlessSdkInstance');
31
20
 
32
- const result = await startHostedApplication('TOKEN', partnerCallback, options);
21
+ const sdk = await getHeadlessSdkInstance('TOKEN_1');
33
22
 
34
- expect(getHeadlessSdkInstance).toHaveBeenCalledWith('TOKEN', options);
35
- expect(partnerCallback).toHaveBeenCalled();
36
- expect(fakeSdk.startHostedApplication).toHaveBeenCalledWith(fakePartnerData);
37
- expect(result).toBe(fakeNextUrl);
23
+ expect(MockHeadlessSdk).toHaveBeenCalledWith('TOKEN_1', undefined);
24
+ expect(sdk).toEqual(expect.objectContaining({ setCompanyToken: expect.any(Function) }));
38
25
  });
39
26
 
40
- test('calls sdk.startHostedApplication with empty object if partnerCallback returns falsy', async () => {
41
- const partnerCallback = vi.fn().mockResolvedValue(undefined);
42
- const fakeNextUrl = '/next-url';
27
+ test('creates a new HeadlessSdk instance with options', async () => {
28
+ const { getHeadlessSdkInstance } = await import('./getHeadlessSdkInstance');
29
+ const options = { isSandbox: true };
30
+
31
+ const sdk = await getHeadlessSdkInstance('TOKEN_1', options);
32
+
33
+ expect(MockHeadlessSdk).toHaveBeenCalledWith('TOKEN_1', options);
34
+ expect(sdk).toEqual(expect.objectContaining({ setCompanyToken: expect.any(Function) }));
35
+ });
43
36
 
44
- (getHeadlessSdkInstance as unknown as Mock).mockResolvedValueOnce(fakeSdk);
45
- fakeSdk.startHostedApplication.mockResolvedValueOnce(fakeNextUrl);
37
+ test('returns cached instance and calls setCompanyToken on subsequent calls', async () => {
38
+ const { getHeadlessSdkInstance } = await import('./getHeadlessSdkInstance');
46
39
 
47
- const result = await startHostedApplication('TOKEN', partnerCallback);
40
+ const firstSdk = await getHeadlessSdkInstance('TOKEN_1');
41
+ const secondSdk = await getHeadlessSdkInstance('TOKEN_2');
48
42
 
49
- expect(fakeSdk.startHostedApplication).toHaveBeenCalledWith({});
50
- expect(result).toBe(fakeNextUrl);
43
+ expect(MockHeadlessSdk).toHaveBeenCalledTimes(1);
44
+ expect(firstSdk).toBe(secondSdk);
45
+ expect(mockSetCompanyToken).toHaveBeenCalledWith('TOKEN_2');
51
46
  });
52
47
  });
@@ -1,43 +1,17 @@
1
- import { IWayflyerHeadlessSdk, HeadlessSdkOptions } from '@wf-financing/embedded-types';
2
-
3
- import { Logger } from '@wf-financing/logger';
4
- import { HEADLESS_SDK_URL, WAYFLYER_HEADLESS_SDK_ID } from '../config';
5
- import { initializeHeadlessSdk, loadScriptAndInitializeSdk } from '../utils';
1
+ import { HeadlessSdk } from '@wf-financing/headless/sdk';
2
+ import type { IWayflyerHeadlessSdk, HeadlessSdkOptions } from '@wf-financing/embedded-types';
6
3
 
7
4
  let cachedSdkInstance: IWayflyerHeadlessSdk | null = null;
8
5
 
9
- export const getHeadlessSdkInstance = async (companyToken: string, options?: HeadlessSdkOptions) => {
10
- try {
11
- if (cachedSdkInstance) {
12
- cachedSdkInstance.setCompanyToken(companyToken);
13
-
14
- return cachedSdkInstance;
15
- }
16
-
17
- const existingScript = document.getElementById(WAYFLYER_HEADLESS_SDK_ID) as HTMLScriptElement;
18
-
19
- if (window.WayflyerHeadlessSdk) {
20
- return initializeHeadlessSdk(companyToken, options);
21
- }
22
-
23
- if (existingScript) {
24
- return loadScriptAndInitializeSdk(existingScript, companyToken, options);
25
- }
26
-
27
- const script = document.createElement('script');
28
- script.src = HEADLESS_SDK_URL;
29
- script.type = 'module';
30
- script.id = WAYFLYER_HEADLESS_SDK_ID;
31
- script.async = true;
32
- script.onerror = () => Logger.logError('Error in loading headless SDK script');
33
-
34
- document.head.appendChild(script);
35
- const headlessSdk: IWayflyerHeadlessSdk = await loadScriptAndInitializeSdk(script, companyToken, options);
36
- cachedSdkInstance = headlessSdk;
37
-
38
- return headlessSdk;
39
- } catch {
40
- Logger.logError('Error in loading headless SDK');
41
- throw new Error('Failed to load script');
6
+ export const getHeadlessSdkInstance = async (
7
+ companyToken: string,
8
+ options?: HeadlessSdkOptions,
9
+ ): Promise<IWayflyerHeadlessSdk> => {
10
+ if (cachedSdkInstance) {
11
+ cachedSdkInstance.setCompanyToken(companyToken);
12
+ return cachedSdkInstance;
42
13
  }
14
+
15
+ cachedSdkInstance = new HeadlessSdk(companyToken, options);
16
+ return cachedSdkInstance;
43
17
  };
@@ -1,7 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
2
 
3
3
  import { PartnerContext } from '../../utils';
4
- import { ConsentModal } from './ConsentModal.tsx';
4
+ import ConsentModal from './ConsentModal.tsx';
5
5
 
6
6
  const portalContainer = document.createElement('div');
7
7
  document.body.append(portalContainer);
@@ -6,7 +6,7 @@ import { Modal } from './Modal.tsx';
6
6
 
7
7
  type ConsentModalProps = ModalProps & { isModalOpen: boolean; partnerLogoUrl?: string };
8
8
 
9
- export const ConsentModal = ({
9
+ const ConsentModal = ({
10
10
  isModalOpen,
11
11
  logoUrl,
12
12
  button,
@@ -24,3 +24,5 @@ export const ConsentModal = ({
24
24
  </Modal>
25
25
  );
26
26
  };
27
+
28
+ export default ConsentModal;
@@ -29,7 +29,7 @@ export const Modal = ({ isModalOpen, setIsModalOpen, children }: ModalProps) =>
29
29
  <PortalProvider getContainer={() => portalContainer}>
30
30
  <MotionModalPrimitive
31
31
  isDismissable
32
- shouldCloseOnInteractOutside={(el: HTMLElement) => el.getAttribute('data-id') === 'modal-mask'}
32
+ shouldCloseOnInteractOutside={(el: Element) => el.getAttribute('data-id') === 'modal-mask'}
33
33
  isOpen={isModalOpen}
34
34
  onOpenChange={() => setIsModalOpen(false)}
35
35
  $size="normal"
@@ -1,4 +1,3 @@
1
1
  export { ROOTS_CONFIG } from './rootsParameters';
2
- export { WAYFLYER_HEADLESS_SDK_ID } from './scriptId';
3
- export { HEADLESS_SDK_URL } from './url';
4
2
  export { APPLICATION_VERSION } from './applicationVersion';
3
+ export { IS_EMBEDDED_JOURNEY } from './isEmbeddedJourney';
@@ -0,0 +1 @@
1
+ export const IS_EMBEDDED_JOURNEY: string | undefined = import.meta.env.VITE_IS_EMBEDDED_JOURNEY;
@@ -1,8 +1,6 @@
1
1
  export { applyStyles } from './applyStyles';
2
2
  export { createRoots } from './createRoots';
3
3
  export { getPartnerIdFromToken } from './getPartnerIdFromToken';
4
- export { initializeHeadlessSdk } from './initializeHeadlessSdk';
5
- export { loadScriptAndInitializeSdk } from './loadScriptAndInitializeSdk';
6
4
  export { PartnerContext, type PartnerContextType } from './partnerContext';
7
5
  export { replacePlaceholdersForMainText } from './replacePlaceholdersForMainText.ts';
8
6
  export { getModalItems } from './getModalItems';
@@ -1 +0,0 @@
1
- export const WAYFLYER_HEADLESS_SDK_ID = 'wayflyer-headless-sdk';
package/src/config/url.ts DELETED
@@ -1 +0,0 @@
1
- export const HEADLESS_SDK_URL = 'https://embedded-finance-frontend.vercel.app/npm/@wf-financing/headless@3';
@@ -1,17 +0,0 @@
1
- import { IWayflyerHeadlessSdk, HeadlessSdkOptions } from '@wf-financing/embedded-types';
2
-
3
- export const initializeHeadlessSdk = (companyToken: string, options?: HeadlessSdkOptions): IWayflyerHeadlessSdk => {
4
- if (!window.WayflyerHeadlessSdk) {
5
- throw new Error('Failed to load WayflyerHeadlessSdk from the script.');
6
- }
7
-
8
- const WayflyerHeadlessSdk = window.WayflyerHeadlessSdk;
9
-
10
- if (options) {
11
- const wayflyerSdk = new WayflyerHeadlessSdk(companyToken, options);
12
-
13
- return wayflyerSdk;
14
- }
15
-
16
- return new WayflyerHeadlessSdk(companyToken);
17
- };
@@ -1,19 +0,0 @@
1
- import { IWayflyerHeadlessSdk, HeadlessSdkOptions } from '@wf-financing/embedded-types';
2
-
3
- import { initializeHeadlessSdk } from './initializeHeadlessSdk';
4
-
5
- export const loadScriptAndInitializeSdk = (
6
- script: HTMLScriptElement,
7
- companyToken: string,
8
- options?: HeadlessSdkOptions,
9
- ): Promise<IWayflyerHeadlessSdk> => {
10
- return new Promise<IWayflyerHeadlessSdk>((resolve, reject) => {
11
- script.onload = () => {
12
- try {
13
- resolve(initializeHeadlessSdk(companyToken, options));
14
- } catch (error) {
15
- reject(error);
16
- }
17
- };
18
- });
19
- };