@paypal/checkout-components 5.0.412-alpha-84b7728.0 → 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.
Files changed (32) hide show
  1. package/dist/button.js +1 -1
  2. package/dist/saved-payment-methods.js +1 -0
  3. package/dist/test/button.js +1 -1
  4. package/package.json +2 -2
  5. package/src/constants/button.js +6 -0
  6. package/src/funding/common.jsx +0 -6
  7. package/src/funding/itau/config.jsx +5 -15
  8. package/src/funding/paypal/monogramMark.jsx +10 -0
  9. package/src/funding/paypal/monogramMark.test.jsx +24 -0
  10. package/src/funding/sepa/config.jsx +1 -29
  11. package/src/lib/appSwitchResume.js +4 -1
  12. package/src/lib/appSwithResume.test.js +19 -0
  13. package/src/marks/component.jsx +4 -1
  14. package/src/marks/templateRebrand.jsx +32 -2
  15. package/src/marks/templateRebrand.test.jsx +101 -0
  16. package/src/ui/buttons/config.js +26 -50
  17. package/src/ui/buttons/poweredBy.jsx +3 -8
  18. package/src/ui/buttons/props.js +29 -2
  19. package/src/ui/buttons/props.test.js +42 -0
  20. package/src/ui/buttons/styles/button.js +3 -21
  21. package/src/ui/buttons/styles/color.js +41 -59
  22. package/src/ui/buttons/styles/labels.js +0 -1
  23. package/src/ui/buttons/styles/responsive.js +39 -69
  24. package/src/ui/buttons/styles/styleUtils.js +5 -9
  25. package/src/ui/buttons/styles/styleUtils.test.js +54 -18
  26. package/src/ui/buttons/tagline.jsx +3 -1
  27. package/src/ui/saved-payment-methods/index.js +3 -0
  28. package/src/ui/saved-payment-methods/template.jsx +255 -0
  29. package/src/ui/saved-payment-methods/template.test.jsx +23 -0
  30. package/src/zoid/saved-payment-methods/container.jsx +0 -1
  31. package/src/zoid/saved-payment-methods/prerender.jsx +9 -19
  32. package/src/ui/buttons/styles/disableMaxHeightConfig.test.js +0 -71
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paypal/checkout-components",
3
- "version": "5.0.412-alpha-84b7728.0",
3
+ "version": "5.0.413",
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.5"
126
+ "@paypal/sdk-logos": "^2.3.2"
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,8 +256,6 @@ 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,
261
259
  ],
262
260
 
263
261
  logoColors: {
@@ -265,8 +263,6 @@ export const DEFAULT_APM_FUNDING_CONFIG: FundingSourceConfig = {
265
263
  [BUTTON_COLOR.SILVER]: LOGO_COLOR.BLACK,
266
264
  [BUTTON_COLOR.WHITE]: LOGO_COLOR.BLACK,
267
265
  [BUTTON_COLOR.BLACK]: LOGO_COLOR.WHITE,
268
- [BUTTON_COLOR.REBRAND_BLACK]: LOGO_COLOR.WHITE,
269
- [BUTTON_COLOR.REBRAND_WHITE]: LOGO_COLOR.BLACK,
270
266
  },
271
267
 
272
268
  textColors: {
@@ -274,8 +270,6 @@ export const DEFAULT_APM_FUNDING_CONFIG: FundingSourceConfig = {
274
270
  [BUTTON_COLOR.BLACK]: TEXT_COLOR.WHITE,
275
271
  [BUTTON_COLOR.SILVER]: TEXT_COLOR.BLACK,
276
272
  [BUTTON_COLOR.WHITE]: TEXT_COLOR.BLACK,
277
- [BUTTON_COLOR.REBRAND_BLACK]: TEXT_COLOR.WHITE,
278
- [BUTTON_COLOR.REBRAND_WHITE]: TEXT_COLOR.BLACK,
279
273
  },
280
274
 
281
275
  secondaryColors: {
@@ -24,32 +24,22 @@ export function getItauConfig(): FundingSourceConfig {
24
24
  return ItauLogoInlineSVG({ logoColor, optional });
25
25
  },
26
26
 
27
- colors: [
28
- BUTTON_COLOR.DEFAULT,
29
- BUTTON_COLOR.DARKBLUE,
30
- BUTTON_COLOR.BLUE,
31
- BUTTON_COLOR.BLACK,
32
- BUTTON_COLOR.REBRAND_BLACK,
33
- BUTTON_COLOR.REBRAND_WHITE,
34
- ],
27
+ colors: [BUTTON_COLOR.DARKBLUE, BUTTON_COLOR.BLUE, BUTTON_COLOR.BLACK],
35
28
 
36
29
  logoColors: {
37
- [BUTTON_COLOR.DEFAULT]: LOGO_COLOR.WHITE,
38
30
  [BUTTON_COLOR.DARKBLUE]: LOGO_COLOR.WHITE,
39
31
  [BUTTON_COLOR.BLUE]: LOGO_COLOR.WHITE,
40
32
  [BUTTON_COLOR.BLACK]: LOGO_COLOR.WHITE,
41
- [BUTTON_COLOR.REBRAND_BLACK]: LOGO_COLOR.WHITE,
42
- [BUTTON_COLOR.REBRAND_WHITE]: LOGO_COLOR.BLACK,
43
33
  },
44
34
 
45
35
  secondaryColors: {
46
36
  ...DEFAULT_FUNDING_CONFIG.secondaryColors,
47
37
 
48
- [DEFAULT]: BUTTON_COLOR.DEFAULT,
49
- [BUTTON_COLOR.GOLD]: BUTTON_COLOR.DEFAULT,
38
+ [DEFAULT]: BUTTON_COLOR.DARKBLUE,
39
+ [BUTTON_COLOR.GOLD]: BUTTON_COLOR.DARKBLUE,
50
40
  [BUTTON_COLOR.BLUE]: BUTTON_COLOR.BLUE,
51
- [BUTTON_COLOR.SILVER]: BUTTON_COLOR.DEFAULT,
52
- [BUTTON_COLOR.WHITE]: BUTTON_COLOR.DEFAULT,
41
+ [BUTTON_COLOR.SILVER]: BUTTON_COLOR.DARKBLUE,
42
+ [BUTTON_COLOR.WHITE]: BUTTON_COLOR.DARKBLUE,
53
43
  },
54
44
  };
55
45
  }
@@ -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,10 +4,9 @@
4
4
  import {
5
5
  SepaLogoInlineSVG,
6
6
  SepaLogoExternalImage,
7
- LOGO_COLOR,
8
7
  } from "@paypal/sdk-logos/src";
9
8
 
10
- import { BUTTON_COLOR, BUTTON_LAYOUT, TEXT_COLOR } from "../../constants";
9
+ import { BUTTON_LAYOUT } from "../../constants";
11
10
  import { DEFAULT_FUNDING_CONFIG, type FundingSourceConfig } from "../common";
12
11
 
13
12
  export function getSepaConfig(): FundingSourceConfig {
@@ -16,33 +15,6 @@ export function getSepaConfig(): FundingSourceConfig {
16
15
 
17
16
  layouts: [BUTTON_LAYOUT.VERTICAL],
18
17
 
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
-
46
18
  Logo: ({ logoColor, optional }) => {
47
19
  if (__WEB__) {
48
20
  return SepaLogoExternalImage({ logoColor, optional });
@@ -44,7 +44,10 @@ function parseHashFragment(): {| hash: string, queryString: string |} {
44
44
  ) {
45
45
  return {
46
46
  hash: possibleAction,
47
- queryString: hashString.slice(ampersandIndex + 1),
47
+ // Normalize embedded ? → & so parseQuery can extract all params.
48
+ // XOOS bug appends ?token=... inside a fragment, producing
49
+ // "merchantHash?token=EC-123" instead of "merchantHash&token=EC-123".
50
+ queryString: hashString.slice(ampersandIndex + 1).replace("?", "&"),
48
51
  };
49
52
  }
50
53
  }
@@ -424,6 +424,25 @@ describe("app switch resume flow", () => {
424
424
  expect(isAppSwitchResumeFlow()).toEqual(true);
425
425
  });
426
426
 
427
+ test("#onCancel&hash?token=... - XOOS malformed URL with token after merchant hash", () => {
428
+ // DTXOOS-3741: XOOS appends ?token=... after the merchant's hash fragment,
429
+ // producing hash?token=EC-123. The embedded ? must be normalized to & so that
430
+ // parseQuery can extract the token correctly.
431
+ vi.spyOn(window, "location", "get").mockReturnValue({
432
+ hash: `#onCancel&hash?token=${orderID}&button_session_id=${buttonSessionID}`,
433
+ search: "",
434
+ });
435
+
436
+ const params = getAppSwitchResumeParams();
437
+
438
+ expect(params).toEqual({
439
+ buttonSessionID,
440
+ checkoutState: "onCancel",
441
+ orderID,
442
+ });
443
+ expect(isAppSwitchResumeFlow()).toEqual(true);
444
+ });
445
+
427
446
  test("#onApprove?token=...&hash?param=value - native app return with ? delimiter and merchant hash containing ?", () => {
428
447
  // Native app uses ? delimiter, and merchant hash also contains ?.
429
448
  // The first ? splits action from params; the second ? is just part of param values.
@@ -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
+ });
@@ -27,22 +27,6 @@ export const BUTTON_RELATIVE_STYLE = {
27
27
  VERTICAL_MARGIN: 30,
28
28
  };
29
29
 
30
- // Rebrand label container height as a ratio of button height (0.5 = 50%).
31
- // The PayPal logo's translateY is derived from this value to keep the logo
32
- // visually centered. If this ratio changes, the translateY percentage must
33
- // be recalculated: translateY = LOGO_VISUAL_OFFSET / LABEL_HEIGHT_RATIO.
34
- // Additionally, the Venmo and Card glyph viewBox/height in @paypal/sdk-logos
35
- // must be updated to match the new label container height.
36
- export const REBRAND_LABEL_HEIGHT_RATIO = 0.5;
37
-
38
- // Fixed visual offset of the PayPal logo as a fraction of total button height.
39
- // translateY percentage = LOGO_VISUAL_OFFSET / LABEL_HEIGHT_RATIO
40
- // Current: 0.06 / 0.5 = 0.12 (12%)
41
- const LOGO_VISUAL_OFFSET = 0.06;
42
- export const REBRAND_LOGO_TRANSLATE_Y: number = Math.round(
43
- (LOGO_VISUAL_OFFSET / REBRAND_LABEL_HEIGHT_RATIO) * 100
44
- );
45
-
46
30
  type ButtonStyleMap = {
47
31
  [$Values<typeof BUTTON_SIZE>]: {|
48
32
  defaultWidth: number,
@@ -69,8 +53,8 @@ type ButtonRedesignStyleMap = {
69
53
  maxHeight: number,
70
54
  minWidth: number,
71
55
  maxWidth: number,
72
- gap: number,
73
- fontSize: number,
56
+ gap?: number,
57
+ fontSize?: number,
74
58
  |},
75
59
  };
76
60
 
@@ -185,7 +169,7 @@ export const BUTTON_REDESIGN_STYLE: ButtonRedesignStyleMap = {
185
169
  minWidth: 50,
186
170
  maxWidth: 75,
187
171
  gap: 3,
188
- fontSize: 10,
172
+ fontSize: 12,
189
173
  },
190
174
 
191
175
  [BUTTON_REDESIGN_SIZE.TINY]: {
@@ -195,7 +179,7 @@ export const BUTTON_REDESIGN_STYLE: ButtonRedesignStyleMap = {
195
179
  minWidth: 75,
196
180
  maxWidth: 200,
197
181
  gap: 3,
198
- fontSize: 10,
182
+ fontSize: 12,
199
183
  },
200
184
 
201
185
  [BUTTON_REDESIGN_SIZE.SMALL]: {
@@ -204,8 +188,8 @@ export const BUTTON_REDESIGN_STYLE: ButtonRedesignStyleMap = {
204
188
  maxHeight: 35,
205
189
  minWidth: 200,
206
190
  maxWidth: 250,
207
- gap: 4,
208
- fontSize: 12,
191
+ gap: 3,
192
+ fontSize: 14,
209
193
  },
210
194
 
211
195
  [BUTTON_REDESIGN_SIZE.MEDIUM_SMALL]: {
@@ -215,7 +199,7 @@ export const BUTTON_REDESIGN_STYLE: ButtonRedesignStyleMap = {
215
199
  minWidth: 250,
216
200
  maxWidth: 300,
217
201
  gap: 4,
218
- fontSize: 14,
202
+ fontSize: 16,
219
203
  },
220
204
 
221
205
  [BUTTON_REDESIGN_SIZE.MEDIUM_BIG]: {
@@ -224,8 +208,8 @@ export const BUTTON_REDESIGN_STYLE: ButtonRedesignStyleMap = {
224
208
  maxHeight: 45,
225
209
  minWidth: 300,
226
210
  maxWidth: 350,
227
- gap: 5,
228
- fontSize: 14,
211
+ gap: 4,
212
+ fontSize: 16,
229
213
  },
230
214
 
231
215
  [BUTTON_REDESIGN_SIZE.LARGE_SMALL]: {
@@ -235,17 +219,17 @@ export const BUTTON_REDESIGN_STYLE: ButtonRedesignStyleMap = {
235
219
  minWidth: 350,
236
220
  maxWidth: 425,
237
221
  gap: 5,
238
- fontSize: 16,
222
+ fontSize: 18,
239
223
  },
240
224
 
241
225
  [BUTTON_REDESIGN_SIZE.LARGE_BIG]: {
242
- defaultHeight: 50,
226
+ defaultHeight: 45,
243
227
  minHeight: 50,
244
228
  maxHeight: 55,
245
229
  minWidth: 425,
246
230
  maxWidth: 500,
247
231
  gap: 5,
248
- fontSize: 18,
232
+ fontSize: 20,
249
233
  },
250
234
 
251
235
  [BUTTON_REDESIGN_SIZE.XL_SMALL]: {
@@ -253,36 +237,28 @@ export const BUTTON_REDESIGN_STYLE: ButtonRedesignStyleMap = {
253
237
  minHeight: 55,
254
238
  maxHeight: 60,
255
239
  minWidth: 500,
256
- maxWidth: 750,
240
+ maxWidth: 550,
257
241
  gap: 6,
258
- fontSize: 18,
242
+ fontSize: 22,
259
243
  },
260
- };
261
244
 
262
- export const BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE = {
263
- ...BUTTON_REDESIGN_STYLE,
264
- XL_BIG: {
245
+ [BUTTON_REDESIGN_SIZE.XL_BIG]: {
246
+ defaultHeight: 55,
265
247
  minHeight: 60,
266
248
  maxHeight: 65,
267
- gap: 6,
268
- fontSize: 20,
269
- },
270
- XXL_SMALL: {
271
- minHeight: 65,
272
- maxHeight: 70,
273
- gap: 7,
274
- fontSize: 22,
275
- },
276
- XXL_BIG: {
277
- minHeight: 70,
278
- maxHeight: 75,
249
+ minWidth: 550,
250
+ maxWidth: 650,
279
251
  gap: 7,
280
252
  fontSize: 24,
281
253
  },
282
- XXXL: {
283
- minHeight: 75,
284
- maxHeight: 200,
285
- gap: 8,
254
+
255
+ [BUTTON_REDESIGN_SIZE.XXL]: {
256
+ defaultHeight: 55,
257
+ minHeight: 65,
258
+ maxHeight: 100,
259
+ minWidth: 650,
260
+ maxWidth: 750,
261
+ gap: 7,
286
262
  fontSize: 26,
287
263
  },
288
264
  };
@@ -9,7 +9,6 @@ import { CLASS, BUTTON_COLOR_REBRAND } from "../../constants";
9
9
  import { Text } from "../text";
10
10
 
11
11
  import { buttonContent } from "./content";
12
- import { REBRAND_LOGO_TRANSLATE_Y } from "./config";
13
12
 
14
13
  const POWERED_BY_PAYPAL_STYLE = `
15
14
  .${CLASS.POWERED_BY} {
@@ -82,7 +81,7 @@ export function PoweredByPayPal({
82
81
  .${CLASS.POWERED_BY} {
83
82
  text-align: center;
84
83
  margin: 10px auto;
85
- height: 12px;
84
+ height: 18px;
86
85
  font-family: PayPal Plain, system-ui, -apple-system, Roboto, "Segoe UI", Helvetica-Neue, Helvetica, Arial, sans-serif;
87
86
  font-size: 10px;
88
87
  font-weight: 400;
@@ -97,13 +96,9 @@ export function PoweredByPayPal({
97
96
  .${CLASS.POWERED_BY} > .${LOGO_CLASS.LOGO} {
98
97
  display: inline-block;
99
98
  vertical-align: middle;
100
- height: 12px;
101
- line-height: 12px;
99
+ height: 18px;
100
+ line-height: 18px;
102
101
  font-size: 10px;
103
- }
104
-
105
- .${CLASS.POWERED_BY} > .${LOGO_CLASS.LOGO} {
106
- transform: translateY(${REBRAND_LOGO_TRANSLATE_Y}%);
107
102
  }
108
103
  `;
109
104
 
@@ -813,6 +813,27 @@ export function determineRandomButtonColor({
813
813
  };
814
814
  }
815
815
 
816
+ export function hasInvalidScriptOptionsForFullRedesign({
817
+ fundingSource,
818
+ }: {|
819
+ fundingSource?: ?$Values<typeof FUNDING>,
820
+ |}): boolean {
821
+ const validFundingSourcesForRedesign = [
822
+ undefined,
823
+ FUNDING.PAYPAL,
824
+ FUNDING.VENMO,
825
+ FUNDING.PAYLATER,
826
+ FUNDING.CREDIT,
827
+ FUNDING.CARD,
828
+ ];
829
+
830
+ if (validFundingSourcesForRedesign.includes(fundingSource)) {
831
+ return false;
832
+ }
833
+
834
+ return true;
835
+ }
836
+
816
837
  export function throwErrorForInvalidButtonColor({
817
838
  fundingSource,
818
839
  fundingSourceColors,
@@ -897,10 +918,13 @@ export function getColorForFullRedesign({
897
918
  [BUTTON_COLOR.BLUE]: BUTTON_COLOR.REBRAND_BLUE,
898
919
  [BUTTON_COLOR.DARKBLUE]: BUTTON_COLOR.REBRAND_BLUE,
899
920
  [BUTTON_COLOR.GOLD]: BUTTON_COLOR.REBRAND_BLUE,
921
+
922
+ // not mapped yet since the styles are not setup
923
+ // These should never be hit since legacy experience should be set
900
924
  [BUTTON_COLOR.BLACK]: BUTTON_COLOR.REBRAND_BLACK,
901
925
  [BUTTON_COLOR.WHITE]: BUTTON_COLOR.REBRAND_WHITE,
902
926
  [BUTTON_COLOR.SILVER]: BUTTON_COLOR.REBRAND_WHITE,
903
- [BUTTON_COLOR.DEFAULT]: BUTTON_COLOR.DEFAULT,
927
+ [BUTTON_COLOR.DEFAULT]: BUTTON_COLOR.REBRAND_BLUE,
904
928
 
905
929
  // normalizeButtonStyle gets called multiple times and
906
930
  // it can be called after color is already be mapped to rebranded style
@@ -940,6 +964,9 @@ export function getButtonColorExperience({
940
964
  }: GetButtonColorExperienceArgs): "abTest" | "fullRebrand" | "legacy" {
941
965
  const { isPaypalRebrandEnabled, isPaypalRebrandABTestEnabled } =
942
966
  experiment || {};
967
+ const rejectRedesign = hasInvalidScriptOptionsForFullRedesign({
968
+ fundingSource,
969
+ });
943
970
 
944
971
  if (!isPaypalRebrandEnabled) {
945
972
  return "legacy";
@@ -950,7 +977,7 @@ export function getButtonColorExperience({
950
977
  return fundingSource === FUNDING.PAYPAL ? "abTest" : "legacy";
951
978
  }
952
979
 
953
- return "fullRebrand";
980
+ return rejectRedesign ? "legacy" : "fullRebrand";
954
981
  }
955
982
 
956
983
  export function getButtonColor({