tf-checkout-react 2.0.0-beta.1 → 2.0.0-beta.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.
@@ -9,15 +9,13 @@
9
9
  import React, { type FC, type ReactNode } from 'react'
10
10
 
11
11
  import { cx } from './cx'
12
+ import { useT } from './I18nProvider'
12
13
  import { Field, Input } from './Field'
13
14
 
14
15
  // The method descriptor + row shape live in the SDK so both platforms render
15
16
  // the SAME option list. Imported for local use and re-exported for consumers
16
17
  // that already import them from here.
17
- import type {
18
- PaymentMethodId,
19
- PaymentMethodOption,
20
- } from 'tf-checkout-shared'
18
+ import type { PaymentMethodId, PaymentMethodOption } from 'tf-checkout-shared'
21
19
 
22
20
  export type { PaymentMethodId, PaymentMethodOption }
23
21
 
@@ -55,79 +53,87 @@ export const PaymentMethods: FC<PaymentMethodsProps> = ({
55
53
  children,
56
54
  inputSlotFor,
57
55
  className,
58
- }) => (
59
- <div
60
- className={cx('tf-checkout-payment__methods', className)}
61
- role="radiogroup"
62
- aria-label="Payment method"
63
- >
64
- {options.map((o) => {
65
- const isSelected = o.value === selected
66
- const extraValue =
67
- o.extra === 'phoneNumber'
68
- ? extraValues[o.value]?.phoneNumber
69
- : extraValues[o.value]?.cashtag
70
- const extraInvalid =
71
- Boolean(isSelected && o.extra && showValidation) && !extraValue?.trim()
72
- return (
73
- <label
74
- key={o.value}
75
- className={cx(
76
- 'tf-checkout-payment__method',
77
- isSelected && 'tf-checkout-payment__method--selected'
78
- )}
79
- >
80
- <span className="tf-checkout-payment__method-head">
81
- <input
82
- type="radio"
83
- name="tf-pay-method"
84
- className="tf-checkout-payment__method-radio"
85
- checked={isSelected}
86
- onChange={() => onSelect(o.value)}
87
- />
88
- {o.iconUrl && (
89
- <img className="tf-checkout-payment__method-icon" src={o.iconUrl} alt="" />
56
+ }) => {
57
+ const t = useT()
58
+
59
+ return (
60
+ <div
61
+ className={cx('tf-checkout-payment__methods', className)}
62
+ role="radiogroup"
63
+ aria-label={t('payment.method')}
64
+ >
65
+ {options.map((o) => {
66
+ const isSelected = o.value === selected
67
+ const extraValue =
68
+ o.extra === 'phoneNumber'
69
+ ? extraValues[o.value]?.phoneNumber
70
+ : extraValues[o.value]?.cashtag
71
+ const extraInvalid =
72
+ Boolean(isSelected && o.extra && showValidation) && !extraValue?.trim()
73
+ return (
74
+ <label
75
+ key={o.value}
76
+ className={cx(
77
+ 'tf-checkout-payment__method',
78
+ isSelected && 'tf-checkout-payment__method--selected'
90
79
  )}
91
- <span className="tf-checkout-payment__method-label">{o.label}</span>
92
- </span>
80
+ >
81
+ <span className="tf-checkout-payment__method-head">
82
+ <input
83
+ type="radio"
84
+ name="tf-pay-method"
85
+ className="tf-checkout-payment__method-radio"
86
+ checked={isSelected}
87
+ onChange={() => onSelect(o.value)}
88
+ />
89
+ {o.iconUrl && (
90
+ <img
91
+ className="tf-checkout-payment__method-icon"
92
+ src={o.iconUrl}
93
+ alt=""
94
+ />
95
+ )}
96
+ <span className="tf-checkout-payment__method-label">{o.label}</span>
97
+ </span>
93
98
 
94
- {isSelected && (o.value === inputSlotFor || o.extra) && (
95
- <div className="tf-checkout-payment__method-body">
96
- {o.value === inputSlotFor && children}
97
- {o.extra && (
98
- <Field
99
- label={`${EXTRA_LABEL[o.extra]} *`}
100
- error={extraInvalid ? 'This field is required.' : undefined}
101
- invalid={extraInvalid}
102
- >
103
- <Input
104
- inputMode={o.extra === 'phoneNumber' ? 'tel' : 'text'}
105
- required
99
+ {isSelected && (o.value === inputSlotFor || o.extra) && (
100
+ <div className="tf-checkout-payment__method-body">
101
+ {o.value === inputSlotFor && children}
102
+ {o.extra && (
103
+ <Field
104
+ label={`${EXTRA_LABEL[o.extra]} *`}
105
+ error={extraInvalid ? t('billing.fieldRequired') : undefined}
106
106
  invalid={extraInvalid}
107
- aria-invalid={extraInvalid}
108
- placeholder={
109
- o.extra === 'phoneNumber' ? 'e.g. 081234567890' : '$cashtag'
110
- }
111
- value={
112
- o.extra === 'phoneNumber'
113
- ? (extraValues[o.value]?.phoneNumber ?? '')
114
- : (extraValues[o.value]?.cashtag ?? '')
115
- }
116
- onChange={(e) =>
117
- onExtraChange(
118
- o.value,
107
+ >
108
+ <Input
109
+ inputMode={o.extra === 'phoneNumber' ? 'tel' : 'text'}
110
+ required
111
+ invalid={extraInvalid}
112
+ aria-invalid={extraInvalid}
113
+ placeholder={
114
+ o.extra === 'phoneNumber' ? 'e.g. 081234567890' : '$cashtag'
115
+ }
116
+ value={
119
117
  o.extra === 'phoneNumber'
120
- ? { phoneNumber: e.target.value }
121
- : { cashtag: e.target.value }
122
- )
123
- }
124
- />
125
- </Field>
126
- )}
127
- </div>
128
- )}
129
- </label>
130
- )
131
- })}
132
- </div>
133
- )
118
+ ? (extraValues[o.value]?.phoneNumber ?? '')
119
+ : (extraValues[o.value]?.cashtag ?? '')
120
+ }
121
+ onChange={(e) =>
122
+ onExtraChange(
123
+ o.value,
124
+ o.extra === 'phoneNumber'
125
+ ? { phoneNumber: e.target.value }
126
+ : { cashtag: e.target.value }
127
+ )
128
+ }
129
+ />
130
+ </Field>
131
+ )}
132
+ </div>
133
+ )}
134
+ </label>
135
+ )
136
+ })}
137
+ </div>
138
+ )
139
+ }
@@ -7,6 +7,7 @@
7
7
  import React, { useState, type FC } from 'react'
8
8
 
9
9
  import { cx } from './cx'
10
+ import { useT } from './I18nProvider'
10
11
 
11
12
  const clock = (s: number) => {
12
13
  const m = String(Math.floor(s / 60)).padStart(2, '0')
@@ -25,9 +26,10 @@ export interface TimerBannerProps {
25
26
  export const TimerBanner: FC<TimerBannerProps> = ({
26
27
  seconds,
27
28
  urgentAt = 60,
28
- message = 'Please complete your purchase before the timer reaches zero.',
29
+ message,
29
30
  className,
30
31
  }) => {
32
+ const t = useT()
31
33
  const [dismissed, setDismissed] = useState(false)
32
34
  if (seconds === undefined || seconds <= 0 || dismissed) return null
33
35
  const urgent = seconds <= urgentAt
@@ -40,12 +42,14 @@ export const TimerBanner: FC<TimerBannerProps> = ({
40
42
  className
41
43
  )}
42
44
  >
43
- <span className="tf-checkout-timerbanner__msg">{message}</span>
45
+ <span className="tf-checkout-timerbanner__msg">
46
+ {message ?? t('timer.completePurchase')}
47
+ </span>
44
48
  <span className="tf-checkout-timerbanner__clock">{clock(seconds)}</span>
45
49
  <button
46
50
  type="button"
47
51
  className="tf-checkout-timerbanner__close"
48
- aria-label="Dismiss"
52
+ aria-label={t('common.dismiss')}
49
53
  onClick={() => setDismissed(true)}
50
54
  >
51
55
  ×