@paypal/checkout-components 5.0.412 → 5.0.413

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.413",
4
4
  "description": "PayPal Checkout components, for integrating checkout products.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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
+ };
@@ -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
+ });
@@ -29,7 +29,7 @@ import type {
29
29
  OnShippingAddressChange,
30
30
  OnShippingOptionsChange,
31
31
  } from "../ui/buttons/props";
32
- import { BUTTON_LAYOUT, BUTTON_FLOW } from "../constants";
32
+ import { BUTTON_LAYOUT, BUTTON_FLOW, MARK_VARIATIONS } from "../constants";
33
33
  import { determineEligibleFunding, isFundingEligible } from "../funding";
34
34
  import {
35
35
  supportsVenmoPopups,
@@ -52,6 +52,7 @@ type MarksInstance = {|
52
52
 
53
53
  type MarksProps = {|
54
54
  fundingSource?: ?$Values<typeof FUNDING>,
55
+ markVariation?: ?$Values<typeof MARK_VARIATIONS>,
55
56
  onShippingChange?: OnShippingChange,
56
57
  onShippingAddressChange?: OnShippingAddressChange,
57
58
  onShippingOptionsChange?: OnShippingOptionsChange,
@@ -64,6 +65,7 @@ export type MarksComponent = (MarksProps) => MarksInstance;
64
65
  export const getMarksComponent: () => MarksComponent = memoize(() => {
65
66
  function Marks({
66
67
  fundingSource,
68
+ markVariation,
67
69
  onShippingChange,
68
70
  onShippingAddressChange,
69
71
  onShippingOptionsChange,
@@ -163,6 +165,7 @@ export const getMarksComponent: () => MarksComponent = memoize(() => {
163
165
  <MarksElementRebrand
164
166
  fundingEligibility={fundingEligibility}
165
167
  fundingSources={fundingSources}
168
+ markVariation={markVariation}
166
169
  height={height}
167
170
  experiment={experiment}
168
171
  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
+ });