@paypal/checkout-components 5.0.400 → 5.0.402

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.400",
3
+ "version": "5.0.402",
4
4
  "description": "PayPal Checkout components, for integrating checkout products.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -54,4 +54,6 @@ export const CLASS = {
54
54
 
55
55
  BUTTON_MESSAGE_RESERVE:
56
56
  ("paypal-button-message-reserved": "paypal-button-message-reserved"),
57
+
58
+ DISABLED: ("paypal-button-disabled": "paypal-button-disabled"),
57
59
  };
@@ -72,6 +72,7 @@ type IndividualButtonProps = {|
72
72
  instrument: ?WalletInstrument,
73
73
  showPayLabel: boolean,
74
74
  showLoadingSpinner?: boolean,
75
+ disabled?: boolean,
75
76
  |};
76
77
 
77
78
  export function Button({
@@ -97,6 +98,7 @@ export function Button({
97
98
  userIDToken,
98
99
  vault,
99
100
  showLoadingSpinner = false,
101
+ disabled = false,
100
102
  }: IndividualButtonProps): ElementNode {
101
103
  const { layout, shape, borderRadius } = style;
102
104
 
@@ -311,6 +313,7 @@ export function Button({
311
313
  CLASS.BUTTON,
312
314
  `${shouldApplyRebrandedStyles ? CLASS.BUTTON_REBRAND : ""}`,
313
315
  `${showLoadingSpinner ? CLASS.LOADING : ""}`,
316
+ `${disabled ? CLASS.DISABLED : ""}`,
314
317
  `${CLASS.NUMBER}-${i}`,
315
318
  `${CLASS.LAYOUT}-${layout}`,
316
319
  `${CLASS.NUMBER}-${
@@ -326,7 +329,8 @@ export function Button({
326
329
  onClick={clickHandler}
327
330
  onRender={onButtonRender}
328
331
  onKeyPress={keypressHandler}
329
- tabindex="0"
332
+ tabindex={showLoadingSpinner || disabled ? "-1" : "0"}
333
+ aria-disabled={showLoadingSpinner || disabled ? "true" : "false"}
330
334
  aria-label={labelText}
331
335
  >
332
336
  <div class={CLASS.BUTTON_LABEL} aria-hidden="true">
@@ -0,0 +1,59 @@
1
+ /* @flow */
2
+ import { describe, test, expect } from "vitest";
3
+ import { noop } from "@krakenjs/belter/src";
4
+
5
+ import { CLASS } from "../../constants/class";
6
+
7
+ import { Button } from "./button";
8
+
9
+ describe("Button", () => {
10
+ test("should apply the disabled class if the disabled prop is passed", () => {
11
+ const mockedButtonProps = {
12
+ buyerCountry: "US",
13
+ commit: false,
14
+ content: null,
15
+ customerId: null,
16
+ env: "test",
17
+ experiment: {},
18
+ flow: "purchase",
19
+ fundingEligibility: {},
20
+ fundingSource: "paypal",
21
+ i: 0,
22
+ instrument: null,
23
+ locale: "en_US",
24
+ multiple: false,
25
+ nonce: "",
26
+ onClick: noop,
27
+ personalization: null,
28
+ showPayLabel: false,
29
+ style: {
30
+ layout: "horizontal",
31
+ shape: "rect",
32
+ borderRadius: 0,
33
+ color: "gold",
34
+ label: "paypal",
35
+ },
36
+ tagline: false,
37
+ userIDToken: null,
38
+ vault: false,
39
+ disabled: true,
40
+ };
41
+
42
+ // $FlowFixMe
43
+ const jsxElem = Button(mockedButtonProps);
44
+
45
+ // Check that the button has the disabled class
46
+ const buttonElement = jsxElem?.children?.find(
47
+ // $FlowFixMe
48
+ (elem) => elem?.props?.class?.includes(CLASS.DISABLED)
49
+ );
50
+
51
+ expect(buttonElement).toBeDefined();
52
+ expect(
53
+ jsxElem?.children?.some(
54
+ // $FlowFixMe
55
+ (elem) => elem?.props?.class?.includes(CLASS.DISABLED)
56
+ )
57
+ ).toBe(true);
58
+ });
59
+ });
@@ -128,6 +128,7 @@ type ButtonsProps = ButtonPropsInputs & {|
128
128
  onClick?: Function,
129
129
  wallet?: ?Wallet,
130
130
  showLoadingSpinner?: boolean,
131
+ disabled?: boolean,
131
132
  |};
132
133
 
133
134
  export function validateButtonProps(props: ButtonPropsInputs) {
@@ -135,7 +136,11 @@ export function validateButtonProps(props: ButtonPropsInputs) {
135
136
  }
136
137
 
137
138
  export function Buttons(props: ButtonsProps): ElementNode {
138
- const { onClick = noop, showLoadingSpinner = false } = props;
139
+ const {
140
+ onClick = noop,
141
+ showLoadingSpinner = false,
142
+ disabled = false,
143
+ } = props;
139
144
  const {
140
145
  applePaySupport,
141
146
  buyerCountry,
@@ -296,6 +301,7 @@ export function Buttons(props: ButtonsProps): ElementNode {
296
301
  instrument={instruments[source]}
297
302
  showPayLabel={showPayLabel}
298
303
  showLoadingSpinner={showLoadingSpinner}
304
+ disabled={disabled}
299
305
  />
300
306
  ))}
301
307
 
@@ -568,6 +568,14 @@ type ThrowErrorForInvalidButtonColorArgs = {|
568
568
  export type ButtonProps = {|
569
569
  // app switch properties
570
570
  appSwitchWhenAvailable: boolean,
571
+
572
+ // Disabled state
573
+ disabled?: boolean,
574
+
575
+ preferences?: {|
576
+ appSwitchWhenAvailable?: boolean,
577
+ launchAppSwitchIn?: "newTab" | "sameTab",
578
+ |},
571
579
  listenForHashChanges: () => void,
572
580
  removeListenerForHashChanges: () => void,
573
581
  // Not passed to child iframe
@@ -35,6 +35,13 @@ export const buttonStyle = `
35
35
  overflow: hidden;
36
36
  }
37
37
 
38
+
39
+ .${CLASS.BUTTON}.${CLASS.DISABLED} {
40
+ pointer-events: none !important;
41
+ cursor: not-allowed !important;
42
+ opacity: 0.6 !important;
43
+ }
44
+
38
45
  .${CLASS.BUTTON} * {
39
46
  cursor: pointer;
40
47
  }
@@ -11,7 +11,7 @@ import { getContainerStyle, getSandboxStyle } from "./style";
11
11
  type OverlayProps = {|
12
12
  buttonSessionID: string,
13
13
  close: () => ZalgoPromise<void>,
14
- focus: () => ZalgoPromise<void>,
14
+ focus?: () => ZalgoPromise<void>,
15
15
  |};
16
16
 
17
17
  export function PayPalAppSwitchOverlay({
@@ -47,7 +47,9 @@ export function PayPalAppSwitchOverlay({
47
47
  e.preventDefault();
48
48
  e.stopPropagation();
49
49
 
50
- focus();
50
+ if (focus) {
51
+ focus();
52
+ }
51
53
  }
52
54
 
53
55
  const setupShowAnimation = () => (el) => {
@@ -90,14 +92,16 @@ export function PayPalAppSwitchOverlay({
90
92
  <div class="paypal-checkout-message">
91
93
  {content.windowMessage}
92
94
  </div>
93
- <div class="paypal-checkout-continue">
94
- {/* This handler should be guarded with e.stopPropagation.
95
- This will stop the event from bubbling up to the overlay click handler
96
- and causing unexpected behavior. */}
97
- <a onClick={focusCheckout} href="#">
98
- {content.continueMessage}
99
- </a>
100
- </div>
95
+ {focus ? (
96
+ <div class="paypal-checkout-continue">
97
+ {/* This handler should be guarded with e.stopPropagation.
98
+ This will stop the event from bubbling up to the overlay click handler
99
+ and causing unexpected behavior. */}
100
+ <a onClick={focusCheckout} href="#">
101
+ {content.continueMessage}
102
+ </a>
103
+ </div>
104
+ ) : null}
101
105
  </div>
102
106
  <style nonce={nonce}>{getContainerStyle({ uid })}</style>
103
107
  </div>
@@ -325,12 +325,25 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
325
325
  },
326
326
 
327
327
  props: {
328
+ disabled: {
329
+ type: "boolean",
330
+ queryParam: true,
331
+ required: false,
332
+ },
333
+
328
334
  appSwitchWhenAvailable: {
329
335
  type: "boolean",
330
336
  queryParam: true,
331
337
  required: false,
332
338
  },
333
339
 
340
+ preferences: {
341
+ type: "object",
342
+ queryParam: true,
343
+ required: false,
344
+ serialization: "json",
345
+ },
346
+
334
347
  showPayPalAppSwitchOverlay: {
335
348
  type: "function",
336
349
  queryParam: false,