@12-apps/payments-frontend 3.49.0 → 3.49.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.49.0",
3
+ "version": "3.49.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.",
@@ -380,7 +380,7 @@ export function ListFace(props: ListFaceProps): JSX.Element {
380
380
  return (
381
381
  <Box data-testid="payment-list-step" sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
382
382
  {shown ? (
383
- <TopAndRows rowsShown={rowsShown}>
383
+ <TopAndRows rowsShown={rowsShown} drawn={state.settled}>
384
384
  <ChoiceList copy={list.copy} state={state} door={list.door ?? []} buyer={c.buyer} onBuyerChange={c.setBuyer} provider={props.provider} failure={failure} locked={facts.locked} covered={coveredByHost(list)} top={top} />
385
385
  </TopAndRows>
386
386
  ) : null}
@@ -141,13 +141,23 @@ function RowsShown({ into }: { into: { current: boolean } }): null {
141
141
  * The top and the rows under ONE boundary (FUT-3711): a top drawn with the
142
142
  * first rows lands with them, so its chunk never pushes a row down. Once the
143
143
  * rows have committed, `rowsShown` says so, and a top that appears later
144
- * suspends on its own instead (`TopWithRetry`).
144
+ * suspends on its own instead (`TopWithRetry`). `drawn` is false while the
145
+ * list holds its rows back for the saved cards (FUT-3849): the placeholder
146
+ * committing is not the rows committing.
145
147
  */
146
- export function TopAndRows({ rowsShown, children }: { rowsShown: { current: boolean }; children: ReactNode }): JSX.Element {
148
+ export function TopAndRows({
149
+ rowsShown,
150
+ drawn,
151
+ children,
152
+ }: {
153
+ rowsShown: { current: boolean };
154
+ drawn: boolean;
155
+ children: ReactNode;
156
+ }): JSX.Element {
147
157
  return (
148
158
  <Suspense fallback={<TopLoading />}>
149
159
  {children}
150
- <RowsShown into={rowsShown} />
160
+ {drawn ? <RowsShown into={rowsShown} /> : null}
151
161
  </Suspense>
152
162
  );
153
163
  }
@@ -198,17 +198,36 @@ export function OutcomeHero({
198
198
  );
199
199
  }
200
200
 
201
- /** One label/value row of the paid receipt block. */
202
- function Fact({ label, value, testId }: { label: string; value: string; testId?: string }): JSX.Element {
201
+ /**
202
+ * Under this many pixels of the receipt's OWN width, a fact whose value is a
203
+ * long unbroken word (the e-mail) stands under its label instead of beside it
204
+ * (FUT-3693): side by side at 390px the e-mail broke mid-word and squeezed
205
+ * "Comprovante enviado para" into three lines. The amount and the order
206
+ * reference are short and keep their row. A container measures its content
207
+ * box: a desktop receipt is ~450px inside its padding, so the line sits below
208
+ * that and only a phone stacks.
209
+ */
210
+ export const RECEIPT_STACK_BELOW_PX = 440;
211
+ const STACKED = `@container receipt (max-width: ${RECEIPT_STACK_BELOW_PX - 0.05}px)`;
212
+
213
+ /** One label/value row of the paid receipt block; `long` lets it stack under {@link RECEIPT_STACK_BELOW_PX}. */
214
+ function Fact({ label, value, testId, long = false }: { label: string; value: string; testId?: string; long?: boolean }): JSX.Element {
203
215
  const { Text } = useCheckoutComponents();
204
216
  return (
205
- <Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 2 }}>
206
- <Text variant="body" size="sm" as="span" style={{ opacity: 0.75 }}>
207
- {label}
208
- </Text>
217
+ <Box
218
+ data-testid={testId ? `${testId}-row` : undefined}
219
+ sx={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 2,
220
+ ...(long ? { [STACKED]: { flexDirection: "column", alignItems: "flex-start", gap: 0.25 } } : {}) }}
221
+ >
222
+ {/* A long value never squeezes its label: the label is the shorter, and the one read first. */}
223
+ <Box component="span" sx={long ? { flexShrink: 0 } : undefined}>
224
+ <Text variant="body" size="sm" as="span" style={{ opacity: 0.75 }}>
225
+ {label}
226
+ </Text>
227
+ </Box>
209
228
  {/* A long e-mail breaks rather than pushing the receipt off a 320px
210
229
  phone: an address has no spaces to wrap at. */}
211
- <Box sx={{ minWidth: 0, textAlign: "right", overflowWrap: "anywhere" }}>
230
+ <Box sx={{ minWidth: 0, maxWidth: "100%", textAlign: "right", overflowWrap: "anywhere", ...(long ? { [STACKED]: { textAlign: "left" } } : {}) }}>
212
231
  <Text
213
232
  variant="body"
214
233
  size="sm"
@@ -243,6 +262,8 @@ export function PaidFacts({
243
262
  <Box
244
263
  data-testid="payment-receipt"
245
264
  sx={{
265
+ containerType: "inline-size",
266
+ containerName: "receipt",
246
267
  display: "flex",
247
268
  flexDirection: "column",
248
269
  gap: 1,
@@ -255,7 +276,7 @@ export function PaidFacts({
255
276
  {orderId ? (
256
277
  <Fact label={copy.referenceLabel} value={`#${orderReference(orderId)}`} testId="payment-reference" />
257
278
  ) : null}
258
- {buyerEmail ? <Fact label={copy.receiptEmailLabel} value={buyerEmail} /> : null}
279
+ {buyerEmail ? <Fact label={copy.receiptEmailLabel} value={buyerEmail} testId="payment-receipt-email" long /> : null}
259
280
  </Box>
260
281
  );
261
282
  }