@paypal/checkout-components 5.0.412-alpha-84b7728.0 → 5.0.412
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/button.js +1 -1
- package/dist/saved-payment-methods.js +1 -0
- package/dist/test/button.js +1 -1
- package/package.json +2 -2
- package/src/funding/common.jsx +0 -6
- package/src/funding/itau/config.jsx +5 -15
- package/src/funding/sepa/config.jsx +1 -29
- package/src/lib/appSwitchResume.js +4 -1
- package/src/lib/appSwithResume.test.js +19 -0
- package/src/ui/buttons/config.js +26 -50
- package/src/ui/buttons/poweredBy.jsx +3 -8
- package/src/ui/buttons/props.js +29 -2
- package/src/ui/buttons/props.test.js +42 -0
- package/src/ui/buttons/styles/button.js +3 -21
- package/src/ui/buttons/styles/color.js +41 -59
- package/src/ui/buttons/styles/labels.js +0 -1
- package/src/ui/buttons/styles/responsive.js +39 -69
- package/src/ui/buttons/styles/styleUtils.js +5 -9
- package/src/ui/buttons/styles/styleUtils.test.js +54 -18
- package/src/ui/buttons/tagline.jsx +3 -1
- package/src/ui/saved-payment-methods/index.js +3 -0
- package/src/ui/saved-payment-methods/template.jsx +255 -0
- package/src/ui/saved-payment-methods/template.test.jsx +23 -0
- package/src/zoid/saved-payment-methods/container.jsx +0 -1
- package/src/zoid/saved-payment-methods/prerender.jsx +9 -19
- package/src/ui/buttons/styles/disableMaxHeightConfig.test.js +0 -71
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
/** @jsx node */
|
|
3
|
+
|
|
4
|
+
import { node, type ElementNode } from "@krakenjs/jsx-pragmatic/src";
|
|
5
|
+
import { PPRebrandLogo } from "@paypal/sdk-logos/src";
|
|
6
|
+
|
|
7
|
+
import type { SavedPaymentMethodsStyleInputs } from "../../zoid/saved-payment-methods/props";
|
|
8
|
+
import { validateSavedPaymentMethodsStyle } from "../../zoid/saved-payment-methods/util";
|
|
9
|
+
|
|
10
|
+
export type SavedPaymentMethodsServerRenderProps = {|
|
|
11
|
+
nonce?: string,
|
|
12
|
+
style?: SavedPaymentMethodsStyleInputs,
|
|
13
|
+
|};
|
|
14
|
+
|
|
15
|
+
export function validateSavedPaymentMethodsProps(props: {|
|
|
16
|
+
style?: SavedPaymentMethodsStyleInputs,
|
|
17
|
+
|}) {
|
|
18
|
+
validateSavedPaymentMethodsStyle(props?.style);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const DEFAULT_STYLE_CONFIG = {
|
|
22
|
+
root: {
|
|
23
|
+
backgroundColor: "transparent",
|
|
24
|
+
fontFamily: "Arial, sans-serif",
|
|
25
|
+
textColorBase: "#000000",
|
|
26
|
+
fontSizeBase: "16px",
|
|
27
|
+
primaryColor: "#000000",
|
|
28
|
+
},
|
|
29
|
+
component: {
|
|
30
|
+
height: "32px",
|
|
31
|
+
padding: "6px 9px",
|
|
32
|
+
borderRadius: "6px",
|
|
33
|
+
borderColor: "transparent",
|
|
34
|
+
borderWidth: "0",
|
|
35
|
+
},
|
|
36
|
+
layout: {
|
|
37
|
+
logo: true,
|
|
38
|
+
label: true,
|
|
39
|
+
message: true,
|
|
40
|
+
logoWidth: "45px",
|
|
41
|
+
logoLabelGap: "12px",
|
|
42
|
+
labelFiGap: "8px",
|
|
43
|
+
labelFontSize: "16px",
|
|
44
|
+
fiTextFontSize: "14px",
|
|
45
|
+
iconSize: "28px",
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function getStyleConfig(style?: SavedPaymentMethodsStyleInputs): Object {
|
|
50
|
+
const s = style || {};
|
|
51
|
+
return {
|
|
52
|
+
root: {
|
|
53
|
+
...DEFAULT_STYLE_CONFIG.root,
|
|
54
|
+
...(s.root || {}),
|
|
55
|
+
},
|
|
56
|
+
component: {
|
|
57
|
+
...DEFAULT_STYLE_CONFIG.component,
|
|
58
|
+
...(s.component || {}),
|
|
59
|
+
},
|
|
60
|
+
layout: {
|
|
61
|
+
...DEFAULT_STYLE_CONFIG.layout,
|
|
62
|
+
...(s.layout || {}),
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Server-only render (commonjs2 / web: false) — mirrors smart buttons `Buttons()`.
|
|
69
|
+
* Non-interactive loading shell (styles + tag skeleton) until the iframe hydrates;
|
|
70
|
+
* shared by zoid prerender and server SSR and must match the first client paint.
|
|
71
|
+
*/
|
|
72
|
+
export function SavedPaymentMethods(
|
|
73
|
+
props: SavedPaymentMethodsServerRenderProps
|
|
74
|
+
): ElementNode {
|
|
75
|
+
const { nonce, style } = props;
|
|
76
|
+
const styleConfig = getStyleConfig(style);
|
|
77
|
+
const shouldRenderMessageContainer = Boolean(styleConfig.layout.message);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<div>
|
|
81
|
+
<style nonce={nonce}>
|
|
82
|
+
{`
|
|
83
|
+
body {
|
|
84
|
+
margin: 0;
|
|
85
|
+
}
|
|
86
|
+
* {
|
|
87
|
+
box-sizing: border-box;
|
|
88
|
+
}
|
|
89
|
+
.saved-payment-methods-container {
|
|
90
|
+
background-color: ${styleConfig.root.backgroundColor};
|
|
91
|
+
font-family: ${styleConfig.root.fontFamily};
|
|
92
|
+
color: ${styleConfig.root.textColorBase};
|
|
93
|
+
font-size: ${styleConfig.root.fontSizeBase};
|
|
94
|
+
display: flex;
|
|
95
|
+
align-items: center;
|
|
96
|
+
min-width: 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.spm-content {
|
|
100
|
+
min-width: 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.spm-label {
|
|
104
|
+
font-size: ${styleConfig.layout.labelFontSize};
|
|
105
|
+
font-weight: 600;
|
|
106
|
+
color: #222222;
|
|
107
|
+
margin-right: ${styleConfig.layout.labelFiGap};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.spm-logo {
|
|
111
|
+
width: ${styleConfig.layout.logoWidth};
|
|
112
|
+
margin-right: ${styleConfig.layout.logoLabelGap};
|
|
113
|
+
display: flex;
|
|
114
|
+
align-items: center;
|
|
115
|
+
justify-content: center;
|
|
116
|
+
overflow: hidden;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.spm-logo-frame {
|
|
120
|
+
aspect-ratio: 1.5;
|
|
121
|
+
width: 100%;
|
|
122
|
+
height: 100%;
|
|
123
|
+
min-width: 0;
|
|
124
|
+
min-height: 0;
|
|
125
|
+
display: flex;
|
|
126
|
+
align-items: center;
|
|
127
|
+
justify-content: center;
|
|
128
|
+
border: 1.2px solid #CCCCCC;
|
|
129
|
+
border-radius: 2px;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.spm-logo-frame img {
|
|
133
|
+
width: 100%;
|
|
134
|
+
height: 100%;
|
|
135
|
+
object-fit: contain;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
#spm-app-root {
|
|
139
|
+
display: contents;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.spm-tag {
|
|
143
|
+
display: flex;
|
|
144
|
+
height: ${styleConfig.component.height};
|
|
145
|
+
align-items: center;
|
|
146
|
+
justify-content: space-between;
|
|
147
|
+
background-color: #F5F7FA;
|
|
148
|
+
padding: ${styleConfig.component.padding};
|
|
149
|
+
border-radius: ${styleConfig.component.borderRadius};
|
|
150
|
+
border-width: ${styleConfig.component.borderWidth};
|
|
151
|
+
border-color: ${styleConfig.component.borderColor};
|
|
152
|
+
border-style: solid;
|
|
153
|
+
gap: 8px;
|
|
154
|
+
min-width: 0;
|
|
155
|
+
max-width: 100%;
|
|
156
|
+
cursor: pointer;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.spm-tag-label {
|
|
160
|
+
font-size: ${styleConfig.layout.fiTextFontSize};
|
|
161
|
+
font-weight: 400;
|
|
162
|
+
color: #000000;
|
|
163
|
+
white-space: nowrap;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.spm-tag-label-fallback {
|
|
167
|
+
display: flex;
|
|
168
|
+
align-items: center;
|
|
169
|
+
min-width: 0;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.spm-tag-label-email {
|
|
173
|
+
flex: 1 1 auto;
|
|
174
|
+
min-width: 0;
|
|
175
|
+
overflow: hidden;
|
|
176
|
+
text-overflow: ellipsis;
|
|
177
|
+
white-space: nowrap;
|
|
178
|
+
display: inline-block;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.spm-tag-label-separator {
|
|
182
|
+
flex: 0 0 auto;
|
|
183
|
+
margin: 0 4px;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.spm-tag-label-pay-in-full {
|
|
187
|
+
flex: 0 0 auto;
|
|
188
|
+
white-space: nowrap;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.spm-tag-card-icon {
|
|
192
|
+
width: ${styleConfig.layout.iconSize};
|
|
193
|
+
border-radius: 4px;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.spm-tag-edit-button svg path {
|
|
197
|
+
fill: ${styleConfig.root.primaryColor};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.spm-message {
|
|
201
|
+
height: 35px;
|
|
202
|
+
margin-top: 6px;
|
|
203
|
+
${
|
|
204
|
+
styleConfig.layout.logo
|
|
205
|
+
? `
|
|
206
|
+
margin-left: calc(${styleConfig.layout.logoWidth} + ${styleConfig.layout.logoLabelGap});
|
|
207
|
+
`
|
|
208
|
+
: ""
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.spm-tag-loading {
|
|
213
|
+
display: flex;
|
|
214
|
+
height: ${styleConfig.component.height};
|
|
215
|
+
align-items: center;
|
|
216
|
+
justify-content: space-between;
|
|
217
|
+
background: linear-gradient(to right, #ffffff, #F5F7FA);
|
|
218
|
+
padding: ${styleConfig.component.padding};
|
|
219
|
+
border-radius: ${styleConfig.component.borderRadius};
|
|
220
|
+
border-width: ${styleConfig.component.borderWidth};
|
|
221
|
+
border-color: ${styleConfig.component.borderColor};
|
|
222
|
+
border-style: solid;
|
|
223
|
+
gap: 8px;
|
|
224
|
+
min-width: 124px;
|
|
225
|
+
max-width: 100%;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.spm-tag-loading.spm-tag-loading--hidden {
|
|
229
|
+
display: none !important;
|
|
230
|
+
}
|
|
231
|
+
`}
|
|
232
|
+
</style>
|
|
233
|
+
<div class="saved-payment-methods-container">
|
|
234
|
+
<div class="spm-content">
|
|
235
|
+
<div class="saved-payment-methods-container">
|
|
236
|
+
{styleConfig.layout.logo && (
|
|
237
|
+
<div class="spm-logo" aria-hidden="true">
|
|
238
|
+
<div class="spm-logo-frame">
|
|
239
|
+
<PPRebrandLogo />
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
)}
|
|
243
|
+
{styleConfig.layout.label && <div class="spm-label">PayPal</div>}
|
|
244
|
+
<div id="spm-app-root">
|
|
245
|
+
<div class="spm-tag-loading" />
|
|
246
|
+
</div>
|
|
247
|
+
</div>
|
|
248
|
+
{shouldRenderMessageContainer && (
|
|
249
|
+
<div id="spm-message-root" class="spm-message" aria-hidden="true" />
|
|
250
|
+
)}
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import { html } from "@krakenjs/jsx-pragmatic";
|
|
4
|
+
|
|
5
|
+
import { SavedPaymentMethods } from "./template";
|
|
6
|
+
|
|
7
|
+
describe("SavedPaymentMethods template (UI shell)", () => {
|
|
8
|
+
test("parses SSR markup into DOM with app root and loading skeleton", () => {
|
|
9
|
+
const markup = SavedPaymentMethods({ nonce: "test-nonce" }).render(html());
|
|
10
|
+
|
|
11
|
+
expect(typeof markup).toBe("string");
|
|
12
|
+
expect(markup.length).toBeGreaterThan(0);
|
|
13
|
+
|
|
14
|
+
const host = document.createElement("div");
|
|
15
|
+
host.innerHTML = markup;
|
|
16
|
+
|
|
17
|
+
expect(host.querySelector("style[nonce='test-nonce']")).toBeTruthy();
|
|
18
|
+
expect(host.querySelector(".saved-payment-methods-container")).toBeTruthy();
|
|
19
|
+
expect(host.querySelector("#spm-app-root")).toBeTruthy();
|
|
20
|
+
expect(host.querySelector(".spm-tag-loading")).toBeTruthy();
|
|
21
|
+
expect(host.querySelector(".spm-logo-frame")).toBeTruthy();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
import { node, type ChildType } from "@krakenjs/jsx-pragmatic/src";
|
|
5
5
|
import type { ZoidProps } from "@krakenjs/zoid/src";
|
|
6
6
|
|
|
7
|
+
import { SavedPaymentMethods } from "../../ui/saved-payment-methods/template";
|
|
8
|
+
|
|
7
9
|
import { type SavedPaymentMethodsProps } from "./props";
|
|
8
10
|
|
|
9
11
|
type PrerenderedSavedPaymentMethodsProps = {|
|
|
@@ -13,32 +15,20 @@ type PrerenderedSavedPaymentMethodsProps = {|
|
|
|
13
15
|
|
|
14
16
|
export function PrerenderedSavedPaymentMethods({
|
|
15
17
|
nonce,
|
|
18
|
+
props,
|
|
16
19
|
}: // props,
|
|
17
20
|
PrerenderedSavedPaymentMethodsProps): ChildType {
|
|
21
|
+
const { style } = props;
|
|
18
22
|
return (
|
|
19
23
|
<html>
|
|
20
24
|
<head>
|
|
21
|
-
<
|
|
22
|
-
{`
|
|
23
|
-
* {
|
|
24
|
-
box-sizing: border-box;
|
|
25
|
-
}
|
|
26
|
-
body {
|
|
27
|
-
margin: 0;
|
|
28
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
29
|
-
}
|
|
30
|
-
.saved-payment-methods-loading {
|
|
31
|
-
display: flex;
|
|
32
|
-
align-items: center;
|
|
33
|
-
justify-content: center;
|
|
34
|
-
height: 100vh;
|
|
35
|
-
color: #999;
|
|
36
|
-
}
|
|
37
|
-
`}
|
|
38
|
-
</style>
|
|
25
|
+
<meta charset="utf-8" />
|
|
39
26
|
</head>
|
|
40
27
|
<body>
|
|
41
|
-
<
|
|
28
|
+
<SavedPaymentMethods
|
|
29
|
+
nonce={typeof nonce === "string" ? nonce : undefined}
|
|
30
|
+
style={style}
|
|
31
|
+
/>
|
|
42
32
|
</body>
|
|
43
33
|
</html>
|
|
44
34
|
);
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/* @flow */
|
|
2
|
-
|
|
3
|
-
import { describe, expect, test } from "vitest";
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
BUTTON_REDESIGN_STYLE,
|
|
7
|
-
BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE,
|
|
8
|
-
} from "../config";
|
|
9
|
-
|
|
10
|
-
describe("BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE config", () => {
|
|
11
|
-
test("should include all BUTTON_REDESIGN_STYLE buckets", () => {
|
|
12
|
-
Object.keys(BUTTON_REDESIGN_STYLE).forEach((key) => {
|
|
13
|
-
expect(BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE).toHaveProperty(key);
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
test("should have XL_BIG bucket with correct values", () => {
|
|
18
|
-
expect(BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE.XL_BIG).toEqual({
|
|
19
|
-
minHeight: 60,
|
|
20
|
-
maxHeight: 65,
|
|
21
|
-
gap: 6,
|
|
22
|
-
fontSize: 20,
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
test("should have XXL_SMALL bucket with correct values", () => {
|
|
27
|
-
expect(BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE.XXL_SMALL).toEqual({
|
|
28
|
-
minHeight: 65,
|
|
29
|
-
maxHeight: 70,
|
|
30
|
-
gap: 7,
|
|
31
|
-
fontSize: 22,
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test("should have XXL_BIG bucket with correct values", () => {
|
|
36
|
-
expect(BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE.XXL_BIG).toEqual({
|
|
37
|
-
minHeight: 70,
|
|
38
|
-
maxHeight: 75,
|
|
39
|
-
gap: 7,
|
|
40
|
-
fontSize: 24,
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test("should have XXXL bucket with correct values", () => {
|
|
45
|
-
expect(BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE.XXXL).toEqual({
|
|
46
|
-
minHeight: 75,
|
|
47
|
-
maxHeight: 200,
|
|
48
|
-
gap: 8,
|
|
49
|
-
fontSize: 26,
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test("should have no gaps in height coverage between buckets", () => {
|
|
54
|
-
const buckets = Object.keys(BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE)
|
|
55
|
-
.map((key) => BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE[key])
|
|
56
|
-
.filter((b) => b.minHeight !== undefined && b.maxHeight !== undefined)
|
|
57
|
-
.sort((a, b) => a.minHeight - b.minHeight);
|
|
58
|
-
|
|
59
|
-
for (let i = 1; i < buckets.length; i++) {
|
|
60
|
-
expect(buckets[i].minHeight).toBeLessThanOrEqual(
|
|
61
|
-
buckets[i - 1].maxHeight
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
test("should have continuous height coverage up to 200", () => {
|
|
67
|
-
const keys = Object.keys(BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE);
|
|
68
|
-
const lastKey = keys[keys.length - 1];
|
|
69
|
-
expect(BUTTON_REDESIGN_DISABLEMAXHEIGHT_STYLE[lastKey].maxHeight).toBe(200);
|
|
70
|
-
});
|
|
71
|
-
});
|