@paypal/checkout-components 5.0.412 → 5.0.414

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paypal/checkout-components",
3
- "version": "5.0.412",
3
+ "version": "5.0.414",
4
4
  "description": "PayPal Checkout components, for integrating checkout products.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -123,7 +123,7 @@
123
123
  "@paypal/funding-components": "^1.0.31",
124
124
  "@paypal/sdk-client": "^4.0.199",
125
125
  "@paypal/sdk-constants": "^1.0.156",
126
- "@paypal/sdk-logos": "^2.3.2"
126
+ "@paypal/sdk-logos": "^2.3.7"
127
127
  },
128
128
  "lint-staged": {
129
129
  "**/*": "prettier --write --ignore-unknown"
@@ -118,3 +118,9 @@ export const MESSAGE_ALIGN = {
118
118
  LEFT: ("left": "left"),
119
119
  RIGHT: ("right": "right"),
120
120
  };
121
+
122
+ // Mark variation options (generic for future funding source support)
123
+ export const MARK_VARIATIONS = {
124
+ WORDMARK: ("wordmark": "wordmark"),
125
+ MONOGRAM: ("monogram": "monogram"),
126
+ };
@@ -256,6 +256,8 @@ export const DEFAULT_APM_FUNDING_CONFIG: FundingSourceConfig = {
256
256
  BUTTON_COLOR.SILVER,
257
257
  BUTTON_COLOR.WHITE,
258
258
  BUTTON_COLOR.BLACK,
259
+ BUTTON_COLOR.REBRAND_BLACK,
260
+ BUTTON_COLOR.REBRAND_WHITE,
259
261
  ],
260
262
 
261
263
  logoColors: {
@@ -263,6 +265,8 @@ export const DEFAULT_APM_FUNDING_CONFIG: FundingSourceConfig = {
263
265
  [BUTTON_COLOR.SILVER]: LOGO_COLOR.BLACK,
264
266
  [BUTTON_COLOR.WHITE]: LOGO_COLOR.BLACK,
265
267
  [BUTTON_COLOR.BLACK]: LOGO_COLOR.WHITE,
268
+ [BUTTON_COLOR.REBRAND_BLACK]: LOGO_COLOR.WHITE,
269
+ [BUTTON_COLOR.REBRAND_WHITE]: LOGO_COLOR.BLACK,
266
270
  },
267
271
 
268
272
  textColors: {
@@ -270,6 +274,8 @@ export const DEFAULT_APM_FUNDING_CONFIG: FundingSourceConfig = {
270
274
  [BUTTON_COLOR.BLACK]: TEXT_COLOR.WHITE,
271
275
  [BUTTON_COLOR.SILVER]: TEXT_COLOR.BLACK,
272
276
  [BUTTON_COLOR.WHITE]: TEXT_COLOR.BLACK,
277
+ [BUTTON_COLOR.REBRAND_BLACK]: TEXT_COLOR.WHITE,
278
+ [BUTTON_COLOR.REBRAND_WHITE]: TEXT_COLOR.BLACK,
273
279
  },
274
280
 
275
281
  secondaryColors: {
@@ -24,6 +24,7 @@ type IsFundingEligibleOptions = {|
24
24
  flow: $Values<typeof BUTTON_FLOW>,
25
25
  fundingEligibility: FundingEligibilityType,
26
26
  enableFunding?: $ReadOnlyArray<?$Values<typeof FUNDING>>,
27
+ disableFunding?: $ReadOnlyArray<?$Values<typeof FUNDING>>,
27
28
  components: $ReadOnlyArray<$Values<typeof COMPONENTS>>,
28
29
  onShippingChange: ?Function,
29
30
  onShippingAddressChange: ?Function,
@@ -75,6 +76,7 @@ export function isFundingEligible(
75
76
  fundingSource,
76
77
  fundingEligibility,
77
78
  enableFunding,
79
+ disableFunding,
78
80
  components,
79
81
  onShippingChange,
80
82
  onShippingAddressChange,
@@ -93,10 +95,12 @@ export function isFundingEligible(
93
95
  }: IsFundingEligibleOptions
94
96
  ): boolean {
95
97
  // Temporary: Force credit to be eligible if the experiment is enabled
98
+ // but honor merchant opt-out via disableFunding
96
99
  if (
97
100
  source === FUNDING.CREDIT &&
98
101
  experiment?.paypalCreditButtonCreateVaultSetupTokenExists &&
99
- flow === BUTTON_FLOW.VAULT_WITHOUT_PURCHASE
102
+ flow === BUTTON_FLOW.VAULT_WITHOUT_PURCHASE &&
103
+ !(disableFunding || []).includes(FUNDING.CREDIT)
100
104
  ) {
101
105
  return true;
102
106
  }
@@ -212,6 +216,7 @@ export function determineEligibleFunding({
212
216
  platform,
213
217
  fundingEligibility,
214
218
  enableFunding,
219
+ disableFunding,
215
220
  components,
216
221
  onShippingChange,
217
222
  onShippingAddressChange,
@@ -234,6 +239,7 @@ export function determineEligibleFunding({
234
239
  platform: $Values<typeof PLATFORM>,
235
240
  fundingEligibility: FundingEligibilityType,
236
241
  enableFunding?: $ReadOnlyArray<?$Values<typeof FUNDING>>,
242
+ disableFunding?: $ReadOnlyArray<?$Values<typeof FUNDING>>,
237
243
  components: $ReadOnlyArray<$Values<typeof COMPONENTS>>,
238
244
  onShippingChange?: ?Function,
239
245
  onShippingAddressChange?: ?Function,
@@ -261,6 +267,7 @@ export function determineEligibleFunding({
261
267
  fundingSource,
262
268
  fundingEligibility,
263
269
  enableFunding,
270
+ disableFunding,
264
271
  components,
265
272
  onShippingChange,
266
273
  onShippingAddressChange,
@@ -431,5 +431,74 @@ describe("Funding eligibility", () => {
431
431
  expect(result2).toBe(true);
432
432
  });
433
433
  });
434
+
435
+ describe("createVaultSetupToken credit experiment", () => {
436
+ const creditExperimentOptions = {
437
+ ...defaultMockFundingOptions,
438
+ fundingSource: FUNDING.CREDIT,
439
+ flow: BUTTON_FLOW.VAULT_WITHOUT_PURCHASE,
440
+ experiment: {
441
+ paypalCreditButtonCreateVaultSetupTokenExists: true,
442
+ },
443
+ fundingEligibility: {
444
+ ...defaultMockFundingOptions.fundingEligibility,
445
+ credit: {
446
+ eligible: false,
447
+ branded: false,
448
+ vaultable: false,
449
+ },
450
+ },
451
+ };
452
+
453
+ beforeEach(() => {
454
+ vi.mocked(getFundingConfig).mockReturnValue({
455
+ ...vi.mocked(getFundingConfig)(),
456
+ [FUNDING.CREDIT]: {
457
+ enabled: true,
458
+ automatic: true,
459
+ },
460
+ });
461
+ });
462
+
463
+ test("should force credit eligible when experiment is enabled and disableFunding does not include credit", () => {
464
+ const result = isFundingEligible(FUNDING.CREDIT, {
465
+ ...creditExperimentOptions,
466
+ disableFunding: [],
467
+ });
468
+
469
+ expect(result).toBe(true);
470
+ });
471
+
472
+ test("should not force credit eligible when merchant has disableFunding=credit", () => {
473
+ const result = isFundingEligible(FUNDING.CREDIT, {
474
+ ...creditExperimentOptions,
475
+ disableFunding: [FUNDING.CREDIT],
476
+ });
477
+
478
+ expect(result).toBe(false);
479
+ });
480
+
481
+ test("should not force credit eligible when experiment is disabled", () => {
482
+ const result = isFundingEligible(FUNDING.CREDIT, {
483
+ ...creditExperimentOptions,
484
+ disableFunding: [],
485
+ experiment: {
486
+ paypalCreditButtonCreateVaultSetupTokenExists: false,
487
+ },
488
+ });
489
+
490
+ expect(result).toBe(false);
491
+ });
492
+
493
+ test("should not force credit eligible when flow is not VAULT_WITHOUT_PURCHASE", () => {
494
+ const result = isFundingEligible(FUNDING.CREDIT, {
495
+ ...creditExperimentOptions,
496
+ disableFunding: [],
497
+ flow: BUTTON_FLOW.PURCHASE,
498
+ });
499
+
500
+ expect(result).toBe(false);
501
+ });
502
+ });
434
503
  });
435
504
  });
@@ -8,11 +8,14 @@ import {
8
8
  } from "@paypal/sdk-logos/src";
9
9
 
10
10
  import { BUTTON_COLOR, BUTTON_LAYOUT, DEFAULT } from "../../constants";
11
- import { DEFAULT_FUNDING_CONFIG, type FundingSourceConfig } from "../common";
11
+ import {
12
+ DEFAULT_APM_FUNDING_CONFIG,
13
+ type FundingSourceConfig,
14
+ } from "../common";
12
15
 
13
16
  export function getItauConfig(): FundingSourceConfig {
14
17
  return {
15
- ...DEFAULT_FUNDING_CONFIG,
18
+ ...DEFAULT_APM_FUNDING_CONFIG,
16
19
 
17
20
  layouts: [BUTTON_LAYOUT.HORIZONTAL, BUTTON_LAYOUT.VERTICAL],
18
21
 
@@ -24,22 +27,32 @@ export function getItauConfig(): FundingSourceConfig {
24
27
  return ItauLogoInlineSVG({ logoColor, optional });
25
28
  },
26
29
 
27
- colors: [BUTTON_COLOR.DARKBLUE, BUTTON_COLOR.BLUE, BUTTON_COLOR.BLACK],
30
+ colors: [
31
+ BUTTON_COLOR.DEFAULT,
32
+ BUTTON_COLOR.DARKBLUE,
33
+ BUTTON_COLOR.BLUE,
34
+ BUTTON_COLOR.BLACK,
35
+ BUTTON_COLOR.REBRAND_BLACK,
36
+ BUTTON_COLOR.REBRAND_WHITE,
37
+ ],
28
38
 
29
39
  logoColors: {
40
+ [BUTTON_COLOR.DEFAULT]: LOGO_COLOR.WHITE,
30
41
  [BUTTON_COLOR.DARKBLUE]: LOGO_COLOR.WHITE,
31
42
  [BUTTON_COLOR.BLUE]: LOGO_COLOR.WHITE,
32
43
  [BUTTON_COLOR.BLACK]: LOGO_COLOR.WHITE,
44
+ [BUTTON_COLOR.REBRAND_BLACK]: LOGO_COLOR.WHITE,
45
+ [BUTTON_COLOR.REBRAND_WHITE]: LOGO_COLOR.BLACK,
33
46
  },
34
47
 
35
48
  secondaryColors: {
36
- ...DEFAULT_FUNDING_CONFIG.secondaryColors,
49
+ ...DEFAULT_APM_FUNDING_CONFIG.secondaryColors,
37
50
 
38
- [DEFAULT]: BUTTON_COLOR.DARKBLUE,
39
- [BUTTON_COLOR.GOLD]: BUTTON_COLOR.DARKBLUE,
51
+ [DEFAULT]: BUTTON_COLOR.DEFAULT,
52
+ [BUTTON_COLOR.GOLD]: BUTTON_COLOR.DEFAULT,
40
53
  [BUTTON_COLOR.BLUE]: BUTTON_COLOR.BLUE,
41
- [BUTTON_COLOR.SILVER]: BUTTON_COLOR.DARKBLUE,
42
- [BUTTON_COLOR.WHITE]: BUTTON_COLOR.DARKBLUE,
54
+ [BUTTON_COLOR.SILVER]: BUTTON_COLOR.DEFAULT,
55
+ [BUTTON_COLOR.WHITE]: BUTTON_COLOR.DEFAULT,
43
56
  },
44
57
  };
45
58
  }
@@ -22,8 +22,7 @@ import css from "./style.scoped.scss";
22
22
 
23
23
  function getLabelText(
24
24
  fundingEligibility: FundingEligibilityType,
25
- locale?: LocaleType,
26
- shouldApplyRebrandedStyles?: boolean
25
+ locale?: LocaleType
27
26
  ): ?string {
28
27
  const { paylater } = fundingEligibility;
29
28
  const { lang } = locale || {};
@@ -68,10 +67,12 @@ function getLabelText(
68
67
  }
69
68
 
70
69
  if (
71
- paylater?.products?.payIn4?.eligible &&
72
- paylater?.products?.payIn4?.variant === "FR"
70
+ (paylater?.products?.payIn4?.eligible &&
71
+ paylater?.products?.payIn4?.variant === "FR") ||
72
+ (paylater?.products?.paylater?.eligible &&
73
+ paylater?.products?.paylater?.variant === "FR")
73
74
  ) {
74
- labelText = shouldApplyRebrandedStyles ? "4X" : "4X PayPal";
75
+ labelText = "Payer en plusieurs fois";
75
76
  }
76
77
 
77
78
  return labelText;
@@ -136,13 +137,7 @@ export function getPaylaterConfig(): FundingSourceConfig {
136
137
  ) : (
137
138
  <PPRebrandLogoInlineSVG logoColor={logoColorPP} />
138
139
  )}
139
- <Text>
140
- {getLabelText(
141
- fundingEligibility,
142
- locale,
143
- shouldApplyRebrandedStyles
144
- ) || "Pay Later"}
145
- </Text>
140
+ <Text>{getLabelText(fundingEligibility, locale) || "Pay Later"}</Text>
146
141
  </Style>
147
142
  );
148
143
  },
@@ -0,0 +1,10 @@
1
+ /* @flow */
2
+ /** @jsx node */
3
+
4
+ import { node, type ComponentNode } from "@krakenjs/jsx-pragmatic/src";
5
+ import { PPRebrandLogoExternalImage } from "@paypal/sdk-logos/src";
6
+ import { LOGO_COLOR } from "@paypal/sdk-logos/src/constants";
7
+
8
+ export function PayPalMonogramMark(): ComponentNode<{| logoColor: string |}> {
9
+ return <PPRebrandLogoExternalImage logoColor={LOGO_COLOR.BLUE} />;
10
+ }
@@ -0,0 +1,24 @@
1
+ /* @flow */
2
+ import { describe, test, expect } from "vitest";
3
+
4
+ import { PayPalMonogramMark } from "./monogramMark";
5
+
6
+ describe("PayPalMonogramMark", () => {
7
+ test("should render PayPal monogram mark component", () => {
8
+ const markComponent = PayPalMonogramMark();
9
+
10
+ expect(markComponent).toBeDefined();
11
+ expect(markComponent.type).toBe("component");
12
+ expect(markComponent.props).toBeDefined();
13
+ expect(markComponent.props.logoColor).toBe("blue");
14
+ });
15
+
16
+ test("should return ChildType for type compatibility", () => {
17
+ const markComponent = PayPalMonogramMark();
18
+
19
+ // Should be compatible with ChildType (no type errors)
20
+ expect(typeof markComponent).toBe("object");
21
+ expect(markComponent.type).toBeDefined();
22
+ expect(markComponent.props).toBeDefined();
23
+ });
24
+ });
@@ -4,9 +4,10 @@
4
4
  import {
5
5
  SepaLogoInlineSVG,
6
6
  SepaLogoExternalImage,
7
+ LOGO_COLOR,
7
8
  } from "@paypal/sdk-logos/src";
8
9
 
9
- import { BUTTON_LAYOUT } from "../../constants";
10
+ import { BUTTON_COLOR, BUTTON_LAYOUT, TEXT_COLOR } from "../../constants";
10
11
  import { DEFAULT_FUNDING_CONFIG, type FundingSourceConfig } from "../common";
11
12
 
12
13
  export function getSepaConfig(): FundingSourceConfig {
@@ -15,6 +16,33 @@ export function getSepaConfig(): FundingSourceConfig {
15
16
 
16
17
  layouts: [BUTTON_LAYOUT.VERTICAL],
17
18
 
19
+ colors: [
20
+ BUTTON_COLOR.DEFAULT,
21
+ BUTTON_COLOR.SILVER,
22
+ BUTTON_COLOR.BLACK,
23
+ BUTTON_COLOR.WHITE,
24
+ BUTTON_COLOR.REBRAND_BLACK,
25
+ BUTTON_COLOR.REBRAND_WHITE,
26
+ ],
27
+
28
+ logoColors: {
29
+ [BUTTON_COLOR.DEFAULT]: LOGO_COLOR.BLACK,
30
+ [BUTTON_COLOR.SILVER]: LOGO_COLOR.BLACK,
31
+ [BUTTON_COLOR.WHITE]: LOGO_COLOR.BLACK,
32
+ [BUTTON_COLOR.BLACK]: LOGO_COLOR.WHITE,
33
+ [BUTTON_COLOR.REBRAND_BLACK]: LOGO_COLOR.WHITE,
34
+ [BUTTON_COLOR.REBRAND_WHITE]: LOGO_COLOR.BLACK,
35
+ },
36
+
37
+ textColors: {
38
+ [BUTTON_COLOR.DEFAULT]: TEXT_COLOR.BLACK,
39
+ [BUTTON_COLOR.SILVER]: TEXT_COLOR.BLACK,
40
+ [BUTTON_COLOR.WHITE]: TEXT_COLOR.BLACK,
41
+ [BUTTON_COLOR.BLACK]: TEXT_COLOR.WHITE,
42
+ [BUTTON_COLOR.REBRAND_BLACK]: TEXT_COLOR.WHITE,
43
+ [BUTTON_COLOR.REBRAND_WHITE]: TEXT_COLOR.BLACK,
44
+ },
45
+
18
46
  Logo: ({ logoColor, optional }) => {
19
47
  if (__WEB__) {
20
48
  return SepaLogoExternalImage({ logoColor, optional });
@@ -19,6 +19,7 @@ import {
19
19
  import { getRememberedFunding } from "@paypal/funding-components/src";
20
20
  import {
21
21
  getEnableFunding,
22
+ getDisableFunding,
22
23
  getComponents,
23
24
  getFundingEligibility,
24
25
  getEnv,
@@ -29,7 +30,7 @@ import type {
29
30
  OnShippingAddressChange,
30
31
  OnShippingOptionsChange,
31
32
  } from "../ui/buttons/props";
32
- import { BUTTON_LAYOUT, BUTTON_FLOW } from "../constants";
33
+ import { BUTTON_LAYOUT, BUTTON_FLOW, MARK_VARIATIONS } from "../constants";
33
34
  import { determineEligibleFunding, isFundingEligible } from "../funding";
34
35
  import {
35
36
  supportsVenmoPopups,
@@ -52,6 +53,7 @@ type MarksInstance = {|
52
53
 
53
54
  type MarksProps = {|
54
55
  fundingSource?: ?$Values<typeof FUNDING>,
56
+ markVariation?: ?$Values<typeof MARK_VARIATIONS>,
55
57
  onShippingChange?: OnShippingChange,
56
58
  onShippingAddressChange?: OnShippingAddressChange,
57
59
  onShippingOptionsChange?: OnShippingOptionsChange,
@@ -64,6 +66,7 @@ export type MarksComponent = (MarksProps) => MarksInstance;
64
66
  export const getMarksComponent: () => MarksComponent = memoize(() => {
65
67
  function Marks({
66
68
  fundingSource,
69
+ markVariation,
67
70
  onShippingChange,
68
71
  onShippingAddressChange,
69
72
  onShippingOptionsChange,
@@ -76,6 +79,7 @@ export const getMarksComponent: () => MarksComponent = memoize(() => {
76
79
  const remembered = getRememberedFunding();
77
80
  const layout = BUTTON_LAYOUT.VERTICAL;
78
81
  const enableFunding = getEnableFunding();
82
+ const disableFunding = getDisableFunding();
79
83
  const components = getComponents();
80
84
  const flow = BUTTON_FLOW.PURCHASE;
81
85
  const applePaySupport = fundingEligibility?.applepay?.eligible
@@ -101,6 +105,7 @@ export const getMarksComponent: () => MarksComponent = memoize(() => {
101
105
  fundingSource,
102
106
  fundingEligibility,
103
107
  enableFunding,
108
+ disableFunding,
104
109
  components,
105
110
  platform,
106
111
  remembered,
@@ -132,6 +137,7 @@ export const getMarksComponent: () => MarksComponent = memoize(() => {
132
137
  fundingSource,
133
138
  fundingEligibility,
134
139
  enableFunding,
140
+ disableFunding,
135
141
  components,
136
142
  onShippingChange,
137
143
  onShippingAddressChange,
@@ -163,6 +169,7 @@ export const getMarksComponent: () => MarksComponent = memoize(() => {
163
169
  <MarksElementRebrand
164
170
  fundingEligibility={fundingEligibility}
165
171
  fundingSources={fundingSources}
172
+ markVariation={markVariation}
166
173
  height={height}
167
174
  experiment={experiment}
168
175
  env={env}
@@ -12,10 +12,12 @@ import { toPx } from "@krakenjs/belter/src";
12
12
 
13
13
  import type { Experiment } from "../types";
14
14
  import { getFundingConfig } from "../funding";
15
- import { CLASS } from "../constants";
15
+ import { CLASS, MARK_VARIATIONS } from "../constants";
16
+ import { PayPalMonogramMark } from "../funding/paypal/monogramMark";
16
17
 
17
18
  type MarkOptions = {|
18
19
  fundingSource: $Values<typeof FUNDING>,
20
+ markVariation?: ?$Values<typeof MARK_VARIATIONS>,
19
21
  fundingEligibility: FundingEligibilityType,
20
22
  experiment: Experiment,
21
23
  env: $Values<typeof ENV>,
@@ -23,6 +25,7 @@ type MarkOptions = {|
23
25
 
24
26
  function Mark({
25
27
  fundingSource,
28
+ markVariation,
26
29
  fundingEligibility,
27
30
  experiment,
28
31
  env,
@@ -53,7 +56,8 @@ function Mark({
53
56
  backgroundClasses += " paypal-mark-rebrand-own-border-and-padding";
54
57
  }
55
58
 
56
- return (
59
+ // Helper function to render wordmark (Logo)
60
+ const renderWordmark = () => (
57
61
  <div class={backgroundClasses}>
58
62
  {marksDefined && MarkLogo ? (
59
63
  <MarkLogo shouldApplyRebrandedStyles={true} />
@@ -68,11 +72,30 @@ function Mark({
68
72
  )}
69
73
  </div>
70
74
  );
75
+
76
+ // Helper function to render PayPal monogram
77
+ const renderPayPalMonogram = () => (
78
+ <div class="paypal-mark-rebrand paypal-mark-rebrand-white">
79
+ <PayPalMonogramMark />
80
+ </div>
81
+ );
82
+
83
+ // Handle PayPal variations - only check for monogram, everything else defaults to wordmark
84
+ if (
85
+ fundingSource === FUNDING.PAYPAL &&
86
+ markVariation === MARK_VARIATIONS.MONOGRAM
87
+ ) {
88
+ return renderPayPalMonogram();
89
+ }
90
+
91
+ // Default logic for all other cases (handles undefined, null, "wordmark", invalid values)
92
+ return renderWordmark();
71
93
  }
72
94
 
73
95
  type MarksElementOptions = {|
74
96
  fundingEligibility: FundingEligibilityType,
75
97
  fundingSources: $ReadOnlyArray<$Values<typeof FUNDING>>,
98
+ markVariation?: ?$Values<typeof MARK_VARIATIONS>,
76
99
  height: number,
77
100
  experiment: Experiment,
78
101
  env: $Values<typeof ENV>,
@@ -81,6 +104,7 @@ type MarksElementOptions = {|
81
104
  export function MarksElementRebrand({
82
105
  fundingEligibility,
83
106
  fundingSources,
107
+ markVariation,
84
108
  experiment,
85
109
  env,
86
110
  }: MarksElementOptions): ElementNode {
@@ -160,6 +184,11 @@ export function MarksElementRebrand({
160
184
  .paypal-mark-rebrand .paypal-logo:last-child {
161
185
  margin-right: 0px;
162
186
  }
187
+
188
+ .paypal-mark-rebrand .paypal-logo-paypal-rebrand {
189
+ padding-top: 2px;
190
+ margin-right: ${toPx(rebrandHeight / 5)};
191
+ }
163
192
  `}
164
193
  </style>
165
194
  <div class="paypal-marks-rebrand">
@@ -167,6 +196,7 @@ export function MarksElementRebrand({
167
196
  <Mark
168
197
  fundingEligibility={fundingEligibility}
169
198
  fundingSource={fundingSource}
199
+ markVariation={markVariation}
170
200
  experiment={experiment}
171
201
  env={env}
172
202
  />
@@ -0,0 +1,101 @@
1
+ /* @noflow */
2
+ import { describe, test, expect, vi } from "vitest";
3
+ import { FUNDING, ENV } from "@paypal/sdk-constants/src";
4
+
5
+ import { MARK_VARIATIONS } from "../constants";
6
+
7
+ import { MarksElementRebrand } from "./templateRebrand";
8
+
9
+ // Mock dependencies
10
+ vi.mock("@paypal/sdk-client/src", () => ({
11
+ getLocale: vi.fn(() => ({ country: "US", lang: "en" })),
12
+ }));
13
+
14
+ vi.mock("../funding", () => ({
15
+ getFundingConfig: vi.fn(() => ({
16
+ [FUNDING.PAYPAL]: {
17
+ Logo: vi.fn(() => ({ type: "PayPalLogo", props: {} })),
18
+ Mark: vi.fn(() => ({ type: "PayPalMark", props: {} })),
19
+ },
20
+ [FUNDING.VENMO]: {
21
+ Logo: vi.fn(() => ({ type: "VenmoLogo", props: {} })),
22
+ },
23
+ [FUNDING.CREDIT]: {
24
+ Logo: vi.fn(() => ({ type: "CreditLogo", props: {} })),
25
+ },
26
+ })),
27
+ }));
28
+
29
+ vi.mock("../funding/paypal/monogramMark", () => ({
30
+ PayPalMonogramMark: vi.fn(() => ({ type: "PayPalMonogramMark", props: {} })),
31
+ }));
32
+
33
+ describe("templateRebrand Mark variation logic", () => {
34
+ const baseProps = {
35
+ fundingEligibility: { paypal: { eligible: true, branded: true } },
36
+ experiment: { isPaypalRebrandEnabled: true },
37
+ env: ENV.SANDBOX,
38
+ height: 32,
39
+ };
40
+
41
+ // Helper to get the Mark component props
42
+ const getMarkProps = (fundingSource, markVariation) => {
43
+ const element = MarksElementRebrand({
44
+ ...baseProps,
45
+ fundingSources: [fundingSource],
46
+ markVariation,
47
+ });
48
+
49
+ const marksDiv = element.children.find(
50
+ (child) => child?.props?.class === "paypal-marks-rebrand"
51
+ );
52
+
53
+ return marksDiv?.children?.[0]?.props;
54
+ };
55
+
56
+ // 1. Monogram renders when variationName: "monogram" with FUNDING.PAYPAL
57
+ test("renders monogram when markVariation is 'monogram' with FUNDING.PAYPAL", () => {
58
+ const props = getMarkProps(FUNDING.PAYPAL, MARK_VARIATIONS.MONOGRAM);
59
+
60
+ expect(props.fundingSource).toBe(FUNDING.PAYPAL);
61
+ expect(props.markVariation).toBe(MARK_VARIATIONS.MONOGRAM);
62
+ });
63
+
64
+ // 2. Wordmark renders when variationName is undefined or "wordmark"
65
+ test("renders wordmark when markVariation is undefined", () => {
66
+ const props = getMarkProps(FUNDING.PAYPAL, undefined);
67
+
68
+ expect(props.fundingSource).toBe(FUNDING.PAYPAL);
69
+ expect(props.markVariation).toBeUndefined();
70
+ });
71
+
72
+ test("renders wordmark when markVariation is 'wordmark'", () => {
73
+ const props = getMarkProps(FUNDING.PAYPAL, MARK_VARIATIONS.WORDMARK);
74
+
75
+ expect(props.fundingSource).toBe(FUNDING.PAYPAL);
76
+ expect(props.markVariation).toBe(MARK_VARIATIONS.WORDMARK);
77
+ });
78
+
79
+ // 3. Non-PayPal funding sources ignore markVariation entirely
80
+ test("ignores markVariation for FUNDING.VENMO", () => {
81
+ const props = getMarkProps(FUNDING.VENMO, MARK_VARIATIONS.MONOGRAM);
82
+
83
+ expect(props.fundingSource).toBe(FUNDING.VENMO);
84
+ expect(props.markVariation).toBe(MARK_VARIATIONS.MONOGRAM);
85
+ });
86
+
87
+ test("ignores markVariation for FUNDING.CREDIT", () => {
88
+ const props = getMarkProps(FUNDING.CREDIT, MARK_VARIATIONS.MONOGRAM);
89
+
90
+ expect(props.fundingSource).toBe(FUNDING.CREDIT);
91
+ expect(props.markVariation).toBe(MARK_VARIATIONS.MONOGRAM);
92
+ });
93
+
94
+ // 4. Fallback to wordmark for unrecognized markVariation values
95
+ test("falls back to wordmark for unrecognized markVariation values", () => {
96
+ const props = getMarkProps(FUNDING.PAYPAL, "invalid-variation");
97
+
98
+ expect(props.fundingSource).toBe(FUNDING.PAYPAL);
99
+ expect(props.markVariation).toBe("invalid-variation");
100
+ });
101
+ });
@@ -143,6 +143,7 @@ export function Buttons(props: ButtonsProps): ElementNode {
143
143
  components,
144
144
  content,
145
145
  customerId,
146
+ disableFunding,
146
147
  displayOnly,
147
148
  enableFunding,
148
149
  env,
@@ -181,6 +182,7 @@ export function Buttons(props: ButtonsProps): ElementNode {
181
182
  platform,
182
183
  fundingEligibility,
183
184
  enableFunding,
185
+ disableFunding,
184
186
  components,
185
187
  onShippingChange,
186
188
  onShippingAddressChange,