@12-apps/payments-frontend 3.27.0 → 3.27.2
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": "@12-apps/payments-frontend",
|
|
3
|
-
"version": "3.27.
|
|
3
|
+
"version": "3.27.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "Browser half of the vendor-agnostic payments platform: plug-and-play MUI components for the per-provider settings page (credential form from each provider's schema, masked hints, verify/enable) and the checkout page (PIX QR + polling, card tokenization, hosted-checkout redirect), plus the headless hooks and fetch clients they build on. Talks only to the host's payments HTTP surface — never to a provider directly. Microfrontend-ready: no app coupling, host injects theme and auth.",
|
|
@@ -51,6 +51,7 @@ export function TenderChoice<T extends string>({
|
|
|
51
51
|
gap: 0.75,
|
|
52
52
|
p: 1.5,
|
|
53
53
|
minHeight: 74,
|
|
54
|
+
container: 'tender-card / inline-size',
|
|
54
55
|
textAlign: 'left',
|
|
55
56
|
borderRadius: CARD_RADIUS,
|
|
56
57
|
border: 1.5,
|
|
@@ -102,6 +103,7 @@ export function PickedTender<T extends string>({
|
|
|
102
103
|
gap: 1,
|
|
103
104
|
p: 1.5,
|
|
104
105
|
minWidth: 0,
|
|
106
|
+
container: 'tender-card / inline-size',
|
|
105
107
|
borderRadius: CARD_RADIUS,
|
|
106
108
|
border: 1.5,
|
|
107
109
|
borderColor: 'primary.main',
|
|
@@ -118,43 +120,98 @@ export function PickedTender<T extends string>({
|
|
|
118
120
|
>
|
|
119
121
|
<CloseIcon fontSize="small" />
|
|
120
122
|
</IconButton>
|
|
121
|
-
<
|
|
123
|
+
<AmountField
|
|
124
|
+
label={copy.amountLabel(tender.label)}
|
|
122
125
|
value={value}
|
|
123
|
-
|
|
124
|
-
onFocus={(event: FocusEvent<HTMLInputElement>) => event.target.select()}
|
|
126
|
+
currencySign={currencySign}
|
|
125
127
|
autoFocus={autoFocus}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
'aria-label': copy.amountLabel(tender.label),
|
|
129
|
-
'data-testid': `${testId}-amount`,
|
|
130
|
-
}}
|
|
131
|
-
startAdornment={
|
|
132
|
-
<Typography variant="caption" color="text.secondary" noWrap sx={{ mr: 0.5 }}>
|
|
133
|
-
{shared ? `${currencySign} ${copy.sharedHint}` : currencySign}
|
|
134
|
-
</Typography>
|
|
135
|
-
}
|
|
136
|
-
sx={{
|
|
137
|
-
borderBottom: 1.5,
|
|
138
|
-
borderColor: 'divider',
|
|
139
|
-
fontWeight: 500,
|
|
140
|
-
fontVariantNumeric: 'tabular-nums',
|
|
141
|
-
'&.Mui-focused': { borderColor: 'primary.main' },
|
|
142
|
-
'& input': { textAlign: 'right', py: 0.375, minWidth: 0 },
|
|
143
|
-
}}
|
|
128
|
+
testId={`${testId}-amount`}
|
|
129
|
+
onType={onType}
|
|
144
130
|
/>
|
|
131
|
+
{/* Under the field rather than beside it, where a narrow card had no room
|
|
132
|
+
for it and the amount both. */}
|
|
133
|
+
{shared ? (
|
|
134
|
+
<Typography variant="caption" color="text.secondary" sx={{ mt: -0.5 }}>
|
|
135
|
+
{copy.sharedHint}
|
|
136
|
+
</Typography>
|
|
137
|
+
) : null}
|
|
145
138
|
</Box>
|
|
146
139
|
);
|
|
147
140
|
}
|
|
148
141
|
|
|
142
|
+
/** A picked card's amount: the currency sign in front, never squeezed. */
|
|
143
|
+
function AmountField({
|
|
144
|
+
label,
|
|
145
|
+
value,
|
|
146
|
+
currencySign,
|
|
147
|
+
autoFocus,
|
|
148
|
+
testId,
|
|
149
|
+
onType,
|
|
150
|
+
}: {
|
|
151
|
+
label: string;
|
|
152
|
+
value: string;
|
|
153
|
+
currencySign: string;
|
|
154
|
+
autoFocus: boolean;
|
|
155
|
+
testId: string;
|
|
156
|
+
onType: (typed: string) => void;
|
|
157
|
+
}) {
|
|
158
|
+
return (
|
|
159
|
+
<InputBase
|
|
160
|
+
value={value}
|
|
161
|
+
onChange={(event) => onType(event.target.value)}
|
|
162
|
+
onFocus={(event: FocusEvent<HTMLInputElement>) => event.target.select()}
|
|
163
|
+
autoFocus={autoFocus}
|
|
164
|
+
inputProps={{
|
|
165
|
+
inputMode: 'decimal',
|
|
166
|
+
'aria-label': label,
|
|
167
|
+
'data-testid': testId,
|
|
168
|
+
}}
|
|
169
|
+
startAdornment={
|
|
170
|
+
// Never shrunk: squeezed by the amount beside it, the sign read "R."
|
|
171
|
+
<Typography variant="caption" color="text.secondary" sx={{ mr: 0.5, flexShrink: 0 }}>
|
|
172
|
+
{currencySign}
|
|
173
|
+
</Typography>
|
|
174
|
+
}
|
|
175
|
+
sx={{
|
|
176
|
+
borderBottom: 1.5,
|
|
177
|
+
borderColor: 'divider',
|
|
178
|
+
fontWeight: 500,
|
|
179
|
+
fontVariantNumeric: 'tabular-nums',
|
|
180
|
+
'&.Mui-focused': { borderColor: 'primary.main' },
|
|
181
|
+
'& input': { textAlign: 'right', py: 0.375, minWidth: 0 },
|
|
182
|
+
}}
|
|
183
|
+
/>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The glyph and the name. Side by side on a card with room; on a narrow one
|
|
189
|
+
* (a 320px phone halves to ~88px) the glyph goes on top, beside the remove
|
|
190
|
+
* control, so the name gets the whole width and breaks only between words.
|
|
191
|
+
*/
|
|
149
192
|
function TenderHeading<T extends string>({ tender }: { tender: TenderOption<T> }) {
|
|
150
193
|
return (
|
|
151
|
-
<Box
|
|
194
|
+
<Box
|
|
195
|
+
sx={{
|
|
196
|
+
display: 'flex',
|
|
197
|
+
flexDirection: 'column',
|
|
198
|
+
alignItems: 'flex-start',
|
|
199
|
+
gap: 0.75,
|
|
200
|
+
minWidth: 0,
|
|
201
|
+
'@container tender-card (min-width: 120px)': {
|
|
202
|
+
flexDirection: 'row',
|
|
203
|
+
alignItems: 'center',
|
|
204
|
+
gap: 1,
|
|
205
|
+
pr: 3,
|
|
206
|
+
},
|
|
207
|
+
}}
|
|
208
|
+
>
|
|
152
209
|
{tender.icon === null ? null : (
|
|
153
210
|
<Box component="span" aria-hidden sx={{ display: 'flex', color: 'primary.main' }}>
|
|
154
211
|
{tender.icon}
|
|
155
212
|
</Box>
|
|
156
213
|
)}
|
|
157
|
-
<Typography component="span" sx={{ fontWeight: 500, overflowWrap: '
|
|
214
|
+
<Typography component="span" sx={{ fontWeight: 500, overflowWrap: 'break-word' }}>
|
|
158
215
|
{tender.label}
|
|
159
216
|
</Typography>
|
|
160
217
|
</Box>
|
|
@@ -169,7 +169,13 @@ function Actions({
|
|
|
169
169
|
return (
|
|
170
170
|
<Box sx={{ display: 'flex', justifyContent: onCancel ? 'space-between' : 'flex-end', gap: 1 }}>
|
|
171
171
|
{onCancel ? (
|
|
172
|
-
<Button
|
|
172
|
+
<Button
|
|
173
|
+
variant="text"
|
|
174
|
+
color="inherit"
|
|
175
|
+
onClick={onCancel}
|
|
176
|
+
data-testid={`${testId}-cancel`}
|
|
177
|
+
sx={{ textTransform: 'none' }}
|
|
178
|
+
>
|
|
173
179
|
{copy.cancel}
|
|
174
180
|
</Button>
|
|
175
181
|
) : null}
|
|
@@ -178,6 +184,9 @@ function Actions({
|
|
|
178
184
|
disabled={onConfirm === null}
|
|
179
185
|
onClick={onConfirm ?? undefined}
|
|
180
186
|
data-testid={`${testId}-confirm`}
|
|
187
|
+
// The confirm reads a sentence with a figure in it — "Falta R$ 2,00" —
|
|
188
|
+
// which MUI's default capitals would shout.
|
|
189
|
+
sx={{ textTransform: 'none' }}
|
|
181
190
|
>
|
|
182
191
|
{label}
|
|
183
192
|
</Button>
|