@blocklet/payment-react 1.18.56 → 1.19.1

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.
Files changed (251) hide show
  1. package/es/checkout/donate.d.ts +1 -15
  2. package/es/checkout/donate.js +301 -189
  3. package/es/checkout/form.d.ts +1 -15
  4. package/es/checkout/form.js +5 -13
  5. package/es/checkout/table.js +3 -3
  6. package/es/components/blockchain/gas.d.ts +1 -5
  7. package/es/components/blockchain/gas.js +10 -2
  8. package/es/components/blockchain/tx.d.ts +1 -8
  9. package/es/components/blockchain/tx.js +29 -10
  10. package/es/components/confirm.d.ts +1 -10
  11. package/es/components/confirm.js +4 -10
  12. package/es/components/country-select.d.ts +3 -2
  13. package/es/components/country-select.js +375 -352
  14. package/es/components/date-range-picker.d.ts +13 -0
  15. package/es/components/date-range-picker.js +279 -0
  16. package/es/components/input.d.ts +14 -20
  17. package/es/components/input.js +51 -44
  18. package/es/components/label.d.ts +7 -0
  19. package/es/components/label.js +49 -0
  20. package/es/components/lazy-loader.js +1 -2
  21. package/es/components/link.d.ts +2 -9
  22. package/es/components/link.js +9 -6
  23. package/es/components/livemode.d.ts +2 -8
  24. package/es/components/livemode.js +1 -5
  25. package/es/components/loading-button.d.ts +6 -1
  26. package/es/components/loading-button.js +56 -66
  27. package/es/components/over-due-invoice-payment.d.ts +0 -18
  28. package/es/components/over-due-invoice-payment.js +138 -95
  29. package/es/components/payment-beneficiaries.d.ts +2 -7
  30. package/es/components/payment-beneficiaries.js +86 -40
  31. package/es/components/pricing-item.d.ts +0 -5
  32. package/es/components/pricing-item.js +1 -4
  33. package/es/components/pricing-table.d.ts +2 -10
  34. package/es/components/pricing-table.js +8 -7
  35. package/es/components/resume-subscription.d.ts +0 -10
  36. package/es/components/resume-subscription.js +42 -21
  37. package/es/components/truncated-text.d.ts +2 -9
  38. package/es/components/truncated-text.js +0 -5
  39. package/es/contexts/donate.d.ts +0 -7
  40. package/es/contexts/donate.js +10 -8
  41. package/es/contexts/payment.d.ts +1 -4
  42. package/es/contexts/payment.js +7 -2
  43. package/es/history/credit/grants-list.d.ts +14 -0
  44. package/es/history/credit/grants-list.js +215 -0
  45. package/es/history/credit/transactions-list.d.ts +13 -0
  46. package/es/history/credit/transactions-list.js +255 -0
  47. package/es/history/invoice/list.d.ts +2 -18
  48. package/es/history/invoice/list.js +172 -74
  49. package/es/history/payment/list.js +115 -38
  50. package/es/hooks/keyboard.d.ts +1 -1
  51. package/es/hooks/keyboard.js +2 -4
  52. package/es/index.d.ts +5 -1
  53. package/es/index.js +10 -1
  54. package/es/libs/cached-request.js +2 -4
  55. package/es/libs/phone-validator.js +1 -2
  56. package/es/libs/util.d.ts +2 -0
  57. package/es/libs/util.js +14 -4
  58. package/es/libs/validator.js +2 -4
  59. package/es/locales/en.js +20 -2
  60. package/es/locales/zh.js +20 -2
  61. package/es/payment/amount.d.ts +2 -7
  62. package/es/payment/amount.js +1 -5
  63. package/es/payment/donation-form.d.ts +2 -10
  64. package/es/payment/donation-form.js +196 -160
  65. package/es/payment/error.d.ts +2 -8
  66. package/es/payment/error.js +40 -20
  67. package/es/payment/footer.d.ts +2 -3
  68. package/es/payment/footer.js +19 -6
  69. package/es/payment/form/addon.js +14 -4
  70. package/es/payment/form/address.d.ts +2 -9
  71. package/es/payment/form/address.js +3 -6
  72. package/es/payment/form/currency.js +45 -25
  73. package/es/payment/form/index.d.ts +2 -8
  74. package/es/payment/form/index.js +151 -71
  75. package/es/payment/form/phone.js +2 -4
  76. package/es/payment/form/stripe/form.d.ts +2 -8
  77. package/es/payment/form/stripe/form.js +1 -3
  78. package/es/payment/header.js +38 -16
  79. package/es/payment/index.d.ts +2 -9
  80. package/es/payment/index.js +23 -17
  81. package/es/payment/product-card.d.ts +2 -11
  82. package/es/payment/product-card.js +84 -50
  83. package/es/payment/product-donation.js +175 -114
  84. package/es/payment/product-item.d.ts +9 -9
  85. package/es/payment/product-item.js +320 -145
  86. package/es/payment/product-skeleton.js +2 -2
  87. package/es/payment/skeleton/donation.js +27 -7
  88. package/es/payment/skeleton/overview.js +22 -2
  89. package/es/payment/skeleton/payment.js +33 -5
  90. package/es/payment/success.d.ts +2 -9
  91. package/es/payment/success.js +41 -14
  92. package/es/payment/summary.d.ts +4 -17
  93. package/es/payment/summary.js +193 -111
  94. package/es/theme/index.d.ts +0 -5
  95. package/es/theme/index.js +2 -5
  96. package/es/theme/typography.d.ts +2 -2
  97. package/lib/checkout/donate.d.ts +1 -15
  98. package/lib/checkout/donate.js +75 -54
  99. package/lib/checkout/form.d.ts +1 -15
  100. package/lib/checkout/form.js +7 -15
  101. package/lib/checkout/table.js +4 -4
  102. package/lib/components/blockchain/gas.d.ts +1 -5
  103. package/lib/components/blockchain/gas.js +3 -2
  104. package/lib/components/blockchain/tx.d.ts +1 -8
  105. package/lib/components/blockchain/tx.js +15 -10
  106. package/lib/components/confirm.d.ts +1 -10
  107. package/lib/components/confirm.js +5 -11
  108. package/lib/components/country-select.d.ts +3 -2
  109. package/lib/components/country-select.js +23 -22
  110. package/lib/components/date-range-picker.d.ts +13 -0
  111. package/lib/components/date-range-picker.js +329 -0
  112. package/lib/components/input.d.ts +14 -20
  113. package/lib/components/input.js +28 -27
  114. package/lib/components/label.d.ts +7 -0
  115. package/lib/components/label.js +60 -0
  116. package/lib/components/lazy-loader.js +1 -1
  117. package/lib/components/link.d.ts +2 -9
  118. package/lib/components/link.js +3 -8
  119. package/lib/components/livemode.d.ts +2 -8
  120. package/lib/components/livemode.js +3 -7
  121. package/lib/components/loading-button.d.ts +6 -1
  122. package/lib/components/loading-button.js +9 -17
  123. package/lib/components/over-due-invoice-payment.d.ts +0 -18
  124. package/lib/components/over-due-invoice-payment.js +31 -33
  125. package/lib/components/payment-beneficiaries.d.ts +2 -7
  126. package/lib/components/payment-beneficiaries.js +12 -11
  127. package/lib/components/pricing-item.d.ts +0 -5
  128. package/lib/components/pricing-item.js +2 -5
  129. package/lib/components/pricing-table.d.ts +2 -10
  130. package/lib/components/pricing-table.js +5 -11
  131. package/lib/components/resume-subscription.d.ts +0 -10
  132. package/lib/components/resume-subscription.js +16 -16
  133. package/lib/components/table.js +1 -1
  134. package/lib/components/truncated-text.d.ts +2 -9
  135. package/lib/components/truncated-text.js +1 -6
  136. package/lib/contexts/donate.d.ts +0 -7
  137. package/lib/contexts/donate.js +4 -7
  138. package/lib/contexts/payment.d.ts +1 -4
  139. package/lib/contexts/payment.js +4 -7
  140. package/lib/history/credit/grants-list.d.ts +14 -0
  141. package/lib/history/credit/grants-list.js +277 -0
  142. package/lib/history/credit/transactions-list.d.ts +13 -0
  143. package/lib/history/credit/transactions-list.js +301 -0
  144. package/lib/history/invoice/list.d.ts +2 -18
  145. package/lib/history/invoice/list.js +73 -37
  146. package/lib/history/payment/list.js +30 -16
  147. package/lib/hooks/keyboard.d.ts +1 -1
  148. package/lib/hooks/mobile.js +1 -1
  149. package/lib/hooks/subscription.js +1 -1
  150. package/lib/index.d.ts +5 -1
  151. package/lib/index.js +41 -2
  152. package/lib/libs/api.js +1 -1
  153. package/lib/libs/dayjs.js +1 -1
  154. package/lib/libs/phone-validator.js +0 -2
  155. package/lib/libs/theme.js +1 -1
  156. package/lib/libs/util.d.ts +2 -0
  157. package/lib/libs/util.js +15 -1
  158. package/lib/libs/validator.js +1 -1
  159. package/lib/locales/en.js +21 -3
  160. package/lib/locales/index.js +1 -1
  161. package/lib/locales/zh.js +21 -3
  162. package/lib/payment/amount.d.ts +2 -7
  163. package/lib/payment/amount.js +2 -6
  164. package/lib/payment/donation-form.d.ts +2 -10
  165. package/lib/payment/donation-form.js +33 -38
  166. package/lib/payment/error.d.ts +2 -8
  167. package/lib/payment/error.js +11 -13
  168. package/lib/payment/footer.d.ts +2 -3
  169. package/lib/payment/footer.js +5 -5
  170. package/lib/payment/form/addon.js +5 -3
  171. package/lib/payment/form/address.d.ts +2 -9
  172. package/lib/payment/form/address.js +5 -8
  173. package/lib/payment/form/currency.js +3 -3
  174. package/lib/payment/form/index.d.ts +2 -8
  175. package/lib/payment/form/index.js +64 -21
  176. package/lib/payment/form/phone.js +1 -1
  177. package/lib/payment/form/stripe/form.d.ts +2 -8
  178. package/lib/payment/form/stripe/form.js +3 -6
  179. package/lib/payment/header.js +8 -4
  180. package/lib/payment/index.d.ts +2 -9
  181. package/lib/payment/index.js +27 -18
  182. package/lib/payment/product-card.d.ts +2 -11
  183. package/lib/payment/product-card.js +13 -20
  184. package/lib/payment/product-donation.js +71 -66
  185. package/lib/payment/product-item.d.ts +9 -9
  186. package/lib/payment/product-item.js +168 -29
  187. package/lib/payment/product-skeleton.js +2 -2
  188. package/lib/payment/skeleton/donation.js +8 -4
  189. package/lib/payment/skeleton/overview.js +6 -2
  190. package/lib/payment/skeleton/payment.js +9 -3
  191. package/lib/payment/success.d.ts +2 -9
  192. package/lib/payment/success.js +12 -15
  193. package/lib/payment/summary.d.ts +4 -17
  194. package/lib/payment/summary.js +53 -45
  195. package/lib/theme/index.d.ts +0 -5
  196. package/lib/theme/index.js +2 -5
  197. package/lib/theme/typography.d.ts +2 -2
  198. package/package.json +40 -40
  199. package/src/checkout/donate.tsx +103 -35
  200. package/src/checkout/form.tsx +5 -14
  201. package/src/checkout/table.tsx +3 -3
  202. package/src/components/blockchain/gas.tsx +5 -3
  203. package/src/components/blockchain/tx.tsx +19 -11
  204. package/src/components/confirm.tsx +4 -11
  205. package/src/components/country-select.tsx +391 -378
  206. package/src/components/date-range-picker.tsx +310 -0
  207. package/src/components/input.tsx +61 -46
  208. package/src/components/label.tsx +58 -0
  209. package/src/components/link.tsx +9 -7
  210. package/src/components/livemode.tsx +2 -6
  211. package/src/components/loading-button.tsx +63 -76
  212. package/src/components/over-due-invoice-payment.tsx +43 -28
  213. package/src/components/payment-beneficiaries.tsx +33 -14
  214. package/src/components/pricing-item.tsx +1 -4
  215. package/src/components/pricing-table.tsx +8 -8
  216. package/src/components/resume-subscription.tsx +20 -14
  217. package/src/components/table.tsx +2 -2
  218. package/src/components/truncated-text.tsx +0 -6
  219. package/src/contexts/donate.tsx +6 -7
  220. package/src/contexts/payment.tsx +7 -3
  221. package/src/history/credit/grants-list.tsx +276 -0
  222. package/src/history/credit/transactions-list.tsx +317 -0
  223. package/src/history/invoice/list.tsx +92 -36
  224. package/src/history/payment/list.tsx +53 -16
  225. package/src/hooks/keyboard.ts +1 -1
  226. package/src/index.ts +9 -0
  227. package/src/libs/util.ts +14 -0
  228. package/src/locales/en.tsx +20 -0
  229. package/src/locales/zh.tsx +19 -0
  230. package/src/payment/amount.tsx +1 -6
  231. package/src/payment/donation-form.tsx +47 -29
  232. package/src/payment/error.tsx +16 -8
  233. package/src/payment/footer.tsx +11 -3
  234. package/src/payment/form/addon.tsx +6 -1
  235. package/src/payment/form/address.tsx +3 -7
  236. package/src/payment/form/currency.tsx +12 -2
  237. package/src/payment/form/index.tsx +121 -45
  238. package/src/payment/form/stripe/form.tsx +1 -5
  239. package/src/payment/header.tsx +14 -2
  240. package/src/payment/index.tsx +27 -22
  241. package/src/payment/product-card.tsx +41 -18
  242. package/src/payment/product-donation.tsx +85 -47
  243. package/src/payment/product-item.tsx +198 -28
  244. package/src/payment/product-skeleton.tsx +3 -2
  245. package/src/payment/skeleton/donation.tsx +12 -2
  246. package/src/payment/skeleton/overview.tsx +12 -2
  247. package/src/payment/skeleton/payment.tsx +16 -3
  248. package/src/payment/success.tsx +26 -15
  249. package/src/payment/summary.tsx +87 -44
  250. package/src/theme/index.tsx +5 -8
  251. package/src/theme/typography.ts +2 -2
@@ -0,0 +1,310 @@
1
+ /* eslint-disable @typescript-eslint/indent */
2
+ import { useState, useRef } from 'react';
3
+ import {
4
+ TextField,
5
+ Stack,
6
+ Typography,
7
+ useMediaQuery,
8
+ useTheme,
9
+ Popover,
10
+ Dialog,
11
+ DialogTitle,
12
+ DialogContent,
13
+ DialogActions,
14
+ Button,
15
+ Box,
16
+ IconButton,
17
+ } from '@mui/material';
18
+ import { DateRange, Close, Clear } from '@mui/icons-material';
19
+ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
20
+ import FormLabel from './label';
21
+ import { formatToDate } from '../libs/util';
22
+
23
+ export interface DateRangeValue {
24
+ start: number | undefined;
25
+ end: number | undefined;
26
+ }
27
+
28
+ export interface DateRangePickerProps {
29
+ value: DateRangeValue;
30
+ onChange: (value: DateRangeValue) => void;
31
+ label?: string;
32
+ size?: 'small' | 'medium';
33
+ fullWidth?: boolean;
34
+ disabled?: boolean;
35
+ }
36
+
37
+ interface DatePickerContentProps {
38
+ tempValue: { startDate: string; endDate: string };
39
+ setTempValue: (
40
+ value:
41
+ | { startDate: string; endDate: string }
42
+ | ((prev: { startDate: string; endDate: string }) => { startDate: string; endDate: string })
43
+ ) => void;
44
+ handleCancel: () => void;
45
+ handleApply: () => void;
46
+ handleClear: () => void;
47
+ }
48
+
49
+ // 日期选择器内容组件
50
+ function DatePickerContent({
51
+ tempValue,
52
+ setTempValue,
53
+ handleCancel,
54
+ handleApply,
55
+ handleClear,
56
+ }: DatePickerContentProps) {
57
+ const { t } = useLocaleContext();
58
+ return (
59
+ <Box sx={{ p: 2, minWidth: 320 }}>
60
+ <Stack spacing={2}>
61
+ <Box>
62
+ <FormLabel>{t('common.startDate')}</FormLabel>
63
+ <TextField
64
+ type="date"
65
+ value={tempValue.startDate}
66
+ onChange={(e) => setTempValue((prev) => ({ ...prev, startDate: e.target.value }))}
67
+ size="small"
68
+ fullWidth
69
+ slotProps={{
70
+ inputLabel: { shrink: true },
71
+ }}
72
+ />
73
+ </Box>
74
+ <Box>
75
+ <FormLabel>{t('common.endDate')}</FormLabel>
76
+ <TextField
77
+ type="date"
78
+ value={tempValue.endDate}
79
+ onChange={(e) => setTempValue((prev) => ({ ...prev, endDate: e.target.value }))}
80
+ size="small"
81
+ fullWidth
82
+ slotProps={{
83
+ inputLabel: { shrink: true },
84
+ }}
85
+ />
86
+ </Box>
87
+
88
+ <Stack
89
+ direction="row"
90
+ spacing={1}
91
+ sx={{
92
+ justifyContent: 'space-between',
93
+ }}>
94
+ <Button variant="text" onClick={handleClear} size="small" color="secondary" sx={{ px: 0.5, minWidth: 0 }}>
95
+ {t('common.clear')}
96
+ </Button>
97
+ <Stack direction="row" spacing={1}>
98
+ <Button variant="outlined" onClick={handleCancel} size="small">
99
+ {t('common.cancel')}
100
+ </Button>
101
+ <Button variant="contained" onClick={handleApply} size="small">
102
+ {t('common.confirm')}
103
+ </Button>
104
+ </Stack>
105
+ </Stack>
106
+ </Stack>
107
+ </Box>
108
+ );
109
+ }
110
+
111
+ const DateFormat = 'YYYY-MM-DD';
112
+
113
+ export default function DateRangePicker({
114
+ value,
115
+ onChange,
116
+ label = '',
117
+ size = 'small',
118
+ fullWidth = false,
119
+ disabled = false,
120
+ }: DateRangePickerProps) {
121
+ const theme = useTheme();
122
+ const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
123
+ const [open, setOpen] = useState(false);
124
+ const { t, locale } = useLocaleContext();
125
+ // 内部使用字符串格式的临时值
126
+ const [tempValue, setTempValue] = useState<{ startDate: string; endDate: string }>({
127
+ startDate: value.start ? formatToDate(value.start * 1000, locale, DateFormat) : '',
128
+ endDate: value.end ? formatToDate(value.end * 1000, locale, DateFormat) : '',
129
+ });
130
+ const anchorRef = useRef<HTMLDivElement>(null);
131
+
132
+ const formatDisplayValue = (startUnix: number | undefined, endUnix: number | undefined) => {
133
+ if (!startUnix || !endUnix) return t('common.selectTimeRange');
134
+ const start = formatToDate(startUnix * 1000, locale, DateFormat);
135
+ const end = formatToDate(endUnix * 1000, locale, DateFormat);
136
+ return `${start} ~ ${end}`;
137
+ };
138
+
139
+ const handleOpen = () => {
140
+ if (disabled) return;
141
+ setTempValue({
142
+ startDate: value.start ? formatToDate(value.start * 1000, locale, DateFormat) : '',
143
+ endDate: value.end ? formatToDate(value.end * 1000, locale, DateFormat) : '',
144
+ });
145
+ setOpen(true);
146
+ };
147
+
148
+ const handleClose = () => {
149
+ setOpen(false);
150
+ };
151
+
152
+ const handleApply = () => {
153
+ const unixValue: DateRangeValue = {
154
+ start: tempValue.startDate ? Math.floor(new Date(`${tempValue.startDate}T00:00:00`).getTime() / 1000) : 0,
155
+ end: tempValue.endDate ? Math.floor(new Date(`${tempValue.endDate}T23:59:59`).getTime() / 1000) : 0,
156
+ };
157
+ onChange(unixValue);
158
+ setOpen(false);
159
+ };
160
+
161
+ const handleCancel = () => {
162
+ setTempValue({
163
+ startDate: value.start ? formatToDate(value.start * 1000, locale, DateFormat) : '',
164
+ endDate: value.end ? formatToDate(value.end * 1000, locale, DateFormat) : '',
165
+ });
166
+ setOpen(false);
167
+ };
168
+
169
+ const handleClear = () => {
170
+ const emptyValue: DateRangeValue = { start: undefined, end: undefined };
171
+ onChange(emptyValue);
172
+ setTempValue({ startDate: '', endDate: '' });
173
+ setOpen(false);
174
+ };
175
+
176
+ const hasValue = !!value.start && !!value.end;
177
+
178
+ return (
179
+ <>
180
+ <TextField
181
+ ref={anchorRef}
182
+ label={label}
183
+ value={formatDisplayValue(value.start, value.end)}
184
+ size={size}
185
+ fullWidth={fullWidth}
186
+ disabled={disabled}
187
+ sx={{
188
+ '& .MuiInputBase-input': {
189
+ cursor: disabled ? 'default' : 'pointer',
190
+ },
191
+ }}
192
+ onClick={handleOpen}
193
+ placeholder={t('common.selectTimeRange')}
194
+ slotProps={{
195
+ input: {
196
+ readOnly: true,
197
+ startAdornment: <DateRange fontSize="small" sx={{ mr: 1, color: 'text.secondary' }} />,
198
+ endAdornment: hasValue && !disabled && (
199
+ <IconButton
200
+ size="small"
201
+ onClick={(e) => {
202
+ e.stopPropagation();
203
+ handleClear();
204
+ }}
205
+ sx={{
206
+ color: 'text.secondary',
207
+
208
+ '&:hover': { color: 'text.primary' },
209
+ }}>
210
+ <Clear fontSize="small" />
211
+ </IconButton>
212
+ ),
213
+ },
214
+
215
+ inputLabel: { shrink: true },
216
+ }}
217
+ />
218
+ {/* 桌面端使用 Popover */}
219
+ {!isMobile && (
220
+ <Popover
221
+ open={open}
222
+ anchorEl={anchorRef.current}
223
+ onClose={handleClose}
224
+ anchorOrigin={{
225
+ vertical: 'bottom',
226
+ horizontal: 'left',
227
+ }}
228
+ transformOrigin={{
229
+ vertical: 'top',
230
+ horizontal: 'left',
231
+ }}
232
+ sx={{
233
+ '& .MuiPaper-root': {
234
+ boxShadow: theme.shadows[8],
235
+ border: `1px solid ${theme.palette.divider}`,
236
+ },
237
+ }}>
238
+ <DatePickerContent
239
+ tempValue={tempValue}
240
+ setTempValue={setTempValue}
241
+ handleCancel={handleCancel}
242
+ handleApply={handleApply}
243
+ handleClear={handleClear}
244
+ />
245
+ </Popover>
246
+ )}
247
+ {/* 移动端使用 Dialog */}
248
+ {isMobile && (
249
+ <Dialog
250
+ open={open}
251
+ onClose={handleClose}
252
+ fullWidth
253
+ maxWidth="sm"
254
+ PaperProps={{
255
+ sx: {
256
+ m: 1,
257
+ maxHeight: 'calc(100% - 64px)',
258
+ },
259
+ }}>
260
+ <DialogTitle
261
+ sx={{
262
+ display: 'flex',
263
+ justifyContent: 'space-between',
264
+ alignItems: 'center',
265
+ pb: 1,
266
+ }}>
267
+ <Typography variant="h6">{t('common.selectTimeRange')}</Typography>
268
+ <IconButton edge="end" color="inherit" onClick={handleClose} aria-label="close" size="small">
269
+ <Close />
270
+ </IconButton>
271
+ </DialogTitle>
272
+ <DialogContent sx={{ pb: 1 }}>
273
+ <Stack spacing={2} sx={{ mt: 1 }}>
274
+ <FormLabel>{t('common.startDate')}</FormLabel>
275
+ <TextField
276
+ type="date"
277
+ value={tempValue.startDate}
278
+ onChange={(e) => setTempValue((prev) => ({ ...prev, startDate: e.target.value }))}
279
+ size="small"
280
+ fullWidth
281
+ slotProps={{
282
+ inputLabel: { shrink: true },
283
+ }}
284
+ />
285
+ <FormLabel>{t('common.endDate')}</FormLabel>
286
+ <TextField
287
+ type="date"
288
+ value={tempValue.endDate}
289
+ onChange={(e) => setTempValue((prev) => ({ ...prev, endDate: e.target.value }))}
290
+ size="small"
291
+ fullWidth
292
+ slotProps={{
293
+ inputLabel: { shrink: true },
294
+ }}
295
+ />
296
+ </Stack>
297
+ </DialogContent>
298
+ <DialogActions sx={{ px: 3, pb: 2 }}>
299
+ <Button onClick={handleCancel} color="inherit">
300
+ {t('common.cancel')}
301
+ </Button>
302
+ <Button onClick={handleApply} variant="contained">
303
+ {t('common.confirm')}
304
+ </Button>
305
+ </DialogActions>
306
+ </Dialog>
307
+ )}
308
+ </>
309
+ );
310
+ }
@@ -1,9 +1,10 @@
1
- import React, { forwardRef, type ReactNode, useImperativeHandle, useRef } from 'react';
2
- import { Box, FormLabel, InputAdornment, TextField, Typography } from '@mui/material';
1
+ import React, { type ReactNode, useImperativeHandle, useRef } from 'react';
2
+ import { Box, InputAdornment, TextField, Typography } from '@mui/material';
3
3
  import get from 'lodash/get';
4
4
  import { Controller, useFormContext } from 'react-hook-form';
5
5
  import type { TextFieldProps } from '@mui/material';
6
6
  import type { RegisterOptions } from 'react-hook-form';
7
+ import FormLabel from './label';
7
8
 
8
9
  type InputProps = TextFieldProps & {
9
10
  name: string;
@@ -12,6 +13,9 @@ type InputProps = TextFieldProps & {
12
13
  errorPosition?: 'right' | 'bottom';
13
14
  rules?: RegisterOptions;
14
15
  wrapperStyle?: React.CSSProperties;
16
+ required?: boolean;
17
+ tooltip?: ReactNode | string;
18
+ description?: ReactNode | string;
15
19
  };
16
20
 
17
21
  function FormInputError({ error }: { error: string }) {
@@ -24,50 +28,61 @@ function FormInputError({ error }: { error: string }) {
24
28
  );
25
29
  }
26
30
 
27
- const FormInput = forwardRef<HTMLInputElement, InputProps>(
28
- ({ name, label, placeholder, rules, errorPosition, wrapperStyle, ...rest }, ref) => {
29
- const { control, formState } = useFormContext();
30
- const inputRef = useRef<HTMLInputElement | null>(null);
31
- useImperativeHandle(ref, () => {
32
- return inputRef.current as HTMLInputElement;
33
- });
34
- const error = get(formState.errors, name)?.message as string;
31
+ export default function FormInput({
32
+ ref = undefined,
33
+ name,
34
+ label = '',
35
+ placeholder = '',
36
+ rules = {},
37
+ errorPosition = 'bottom',
38
+ wrapperStyle = {},
39
+ inputProps = {},
40
+ required = false,
41
+ tooltip = '',
42
+ description = '',
43
+ ...rest
44
+ }: InputProps & {
45
+ ref?: React.RefObject<HTMLInputElement | null>;
46
+ inputProps?: TextFieldProps['inputProps'];
47
+ }) {
48
+ const { control, formState } = useFormContext();
49
+ const inputRef = useRef<HTMLInputElement | null>(null);
50
+ useImperativeHandle(ref, () => {
51
+ return inputRef.current as HTMLInputElement;
52
+ });
53
+ const error = get(formState.errors, name)?.message as string;
35
54
 
36
- return (
37
- <Controller
38
- name={name}
39
- control={control}
40
- rules={rules}
41
- render={({ field }) => (
42
- <Box sx={{ width: '100%', ...wrapperStyle }}>
43
- {!!label && <FormLabel sx={{ color: 'text.primary' }}>{label}</FormLabel>}
44
- <TextField
45
- fullWidth
46
- error={!!get(formState.errors, name)}
47
- helperText={errorPosition === 'bottom' && error ? error : ''}
48
- placeholder={placeholder}
49
- size="small"
50
- {...field}
51
- {...rest}
52
- inputRef={inputRef}
53
- InputProps={Object.assign(
55
+ return (
56
+ <Controller
57
+ name={name}
58
+ control={control}
59
+ rules={rules}
60
+ render={({ field }) => (
61
+ <Box sx={{ width: '100%', ...wrapperStyle }}>
62
+ {!!label && (
63
+ <FormLabel required={required} tooltip={tooltip} description={description}>
64
+ {label}
65
+ </FormLabel>
66
+ )}
67
+ <TextField
68
+ fullWidth
69
+ error={!!get(formState.errors, name)}
70
+ helperText={errorPosition === 'bottom' && error ? error : ''}
71
+ placeholder={placeholder}
72
+ size="small"
73
+ {...field}
74
+ {...rest}
75
+ inputRef={inputRef}
76
+ slotProps={{
77
+ htmlInput: inputProps,
78
+ input: Object.assign(
54
79
  rest.InputProps || {},
55
80
  errorPosition === 'right' && error ? { endAdornment: <FormInputError error={error} /> } : {}
56
- )}
57
- />
58
- </Box>
59
- )}
60
- />
61
- );
62
- }
63
- );
64
-
65
- FormInput.defaultProps = {
66
- label: '',
67
- placeholder: '',
68
- errorPosition: 'bottom',
69
- rules: {},
70
- wrapperStyle: {},
71
- };
72
-
73
- export default FormInput;
81
+ ),
82
+ }}
83
+ />
84
+ </Box>
85
+ )}
86
+ />
87
+ );
88
+ }
@@ -0,0 +1,58 @@
1
+ import { InfoOutlined } from '@mui/icons-material';
2
+ import { Box, FormLabel, Tooltip, Typography } from '@mui/material';
3
+ import type { FormLabelProps } from '@mui/material';
4
+ import type { ReactNode } from 'react';
5
+
6
+ export default function CustomFormLabel({
7
+ children,
8
+ required = false,
9
+ tooltip = '',
10
+ description = '',
11
+ ...props
12
+ }: FormLabelProps & { required?: boolean; tooltip?: ReactNode | string; description?: ReactNode | string }) {
13
+ return (
14
+ <Box sx={{ mb: 1, width: '100%' }}>
15
+ <FormLabel
16
+ {...props}
17
+ sx={{
18
+ display: 'flex',
19
+ alignItems: 'center',
20
+ gap: 0.5,
21
+ fontWeight: 500,
22
+ color: 'text.primary',
23
+ '&.MuiFormLabel-root': {
24
+ display: 'flex',
25
+ alignItems: 'center',
26
+ gap: 0.5,
27
+ fontWeight: 500,
28
+ color: 'text.primary',
29
+ },
30
+ ...(props.sx || {}),
31
+ }}>
32
+ {children}
33
+ {required && (
34
+ <Typography component="span" color="error">
35
+ *
36
+ </Typography>
37
+ )}
38
+ {tooltip &&
39
+ (typeof tooltip === 'string' ? (
40
+ <Tooltip title={tooltip}>
41
+ <InfoOutlined fontSize="small" sx={{ opacity: 0.7 }} />
42
+ </Tooltip>
43
+ ) : (
44
+ tooltip
45
+ ))}
46
+ </FormLabel>
47
+ {description && (
48
+ <Typography
49
+ variant="caption"
50
+ sx={{
51
+ color: 'text.secondary',
52
+ }}>
53
+ {description}
54
+ </Typography>
55
+ )}
56
+ </Box>
57
+ );
58
+ }
@@ -10,7 +10,15 @@ interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
10
10
  outLink?: boolean;
11
11
  }
12
12
 
13
- export default function Link({ to, children, onClick, replace, target, outLink = false, ...props }: LinkProps) {
13
+ export default function Link({
14
+ to,
15
+ children,
16
+ onClick,
17
+ replace = false,
18
+ target = undefined,
19
+ outLink = false,
20
+ ...props
21
+ }: LinkProps) {
14
22
  const navigate = useNavigate();
15
23
 
16
24
  const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
@@ -32,9 +40,3 @@ export default function Link({ to, children, onClick, replace, target, outLink =
32
40
  </a>
33
41
  );
34
42
  }
35
-
36
- Link.defaultProps = {
37
- replace: false,
38
- target: undefined,
39
- outLink: false,
40
- };
@@ -7,7 +7,8 @@ type Props = {
7
7
  backgroundColor?: string;
8
8
  } & ChipOwnProps;
9
9
 
10
- export default function Livemode({ color, backgroundColor, sx }: Props) {
10
+ // @ts-ignore
11
+ export default function Livemode({ color = '#bb5504', backgroundColor = '#ffde92', sx }: Props) {
11
12
  const { t } = useLocaleContext();
12
13
  return (
13
14
  <Chip
@@ -29,8 +30,3 @@ export default function Livemode({ color, backgroundColor, sx }: Props) {
29
30
  />
30
31
  );
31
32
  }
32
-
33
- Livemode.defaultProps = {
34
- color: '#bb5504',
35
- backgroundColor: '#ffde92',
36
- };