@btndprojects/loam-ui-native 0.1.1 → 0.2.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 (262) hide show
  1. package/dist/accordion/index.js +5 -3
  2. package/dist/adaptive/index.js +6 -2
  3. package/dist/alert/index.js +5 -2
  4. package/dist/analyzer/index.js +9 -6
  5. package/dist/announcement/index.js +8 -5
  6. package/dist/audio-player/index.js +5 -3
  7. package/dist/avatar/index.js +5 -2
  8. package/dist/avatar-group/index.js +7 -3
  9. package/dist/badge/index.js +7 -4
  10. package/dist/banner/index.js +5 -2
  11. package/dist/board/index.js +11 -6
  12. package/dist/button/index.js +6 -3
  13. package/dist/camera-permission/index.js +15 -12
  14. package/dist/capture-result/index.js +19 -16
  15. package/dist/card/index.js +6 -3
  16. package/dist/card-form/index.js +12 -8
  17. package/dist/carousel/index.js +4 -2
  18. package/dist/chart/index.js +8 -5
  19. package/dist/charts/index.js +8 -6
  20. package/dist/chat/index.js +16 -0
  21. package/dist/checkbox/index.js +6 -4
  22. package/dist/checklist/index.js +11 -8
  23. package/dist/checkout/index.js +16 -11
  24. package/dist/chip/index.js +7 -4
  25. package/dist/{chunk-XNUVB5OL.js → chunk-2OLKPG4E.js} +92 -28
  26. package/dist/{chunk-RUZHTGKB.js → chunk-2PKYGLQ6.js} +71 -40
  27. package/dist/{chunk-UC2WGUP3.js → chunk-2SWKL3AJ.js} +91 -252
  28. package/dist/{chunk-AI4DWZCD.js → chunk-2SY63FCH.js} +63 -16
  29. package/dist/{chunk-F5XNPWS7.js → chunk-2TXERVVA.js} +92 -35
  30. package/dist/chunk-36EC2T6P.js +581 -0
  31. package/dist/chunk-3DUWIYV5.js +437 -0
  32. package/dist/{chunk-JNY4ZHAR.js → chunk-3QMEOFW5.js} +275 -71
  33. package/dist/chunk-3WEZCGHX.js +265 -0
  34. package/dist/chunk-46MMSDGL.js +194 -0
  35. package/dist/{chunk-7O2FMUPT.js → chunk-4IZXHVFJ.js} +297 -92
  36. package/dist/{chunk-LAECSR4H.js → chunk-5LAAAXFP.js} +14 -8
  37. package/dist/{chunk-2A5NIQAK.js → chunk-5RENVKBQ.js} +134 -46
  38. package/dist/{chunk-2ZZ7TDJ4.js → chunk-5UTRIXQ6.js} +37 -31
  39. package/dist/{chunk-LOE5YNN3.js → chunk-5VFZRGVD.js} +37 -10
  40. package/dist/{chunk-52X2VYTD.js → chunk-67IZZ2MJ.js} +115 -60
  41. package/dist/{chunk-UYG5L34B.js → chunk-6YAQBXB3.js} +10 -4
  42. package/dist/{chunk-BTTFCMKG.js → chunk-74FLKD24.js} +94 -23
  43. package/dist/{chunk-ITTYJZWX.js → chunk-7BUIKDD6.js} +73 -18
  44. package/dist/{chunk-423B7SPN.js → chunk-7OVVSVEZ.js} +273 -109
  45. package/dist/chunk-AEB7KCHQ.js +287 -0
  46. package/dist/chunk-APCWFOZW.js +28 -0
  47. package/dist/chunk-AWKQIE5I.js +139 -0
  48. package/dist/{chunk-VCDBXW5H.js → chunk-B7N4ASYE.js} +86 -42
  49. package/dist/{chunk-IVNRBPGC.js → chunk-C4GTDLRC.js} +104 -20
  50. package/dist/{chunk-4ZAHCY44.js → chunk-C6APNDVA.js} +12 -5
  51. package/dist/{chunk-4SZYY6AN.js → chunk-CMTVNF3D.js} +18 -13
  52. package/dist/{chunk-HZ6CNMAF.js → chunk-CPTOADB2.js} +151 -96
  53. package/dist/chunk-D5N5QWI7.js +1325 -0
  54. package/dist/{chunk-IIQTAY3J.js → chunk-DN7MNQIP.js} +113 -29
  55. package/dist/{chunk-47FWHGUN.js → chunk-DVGBZ3TX.js} +84 -23
  56. package/dist/chunk-DW3L54DQ.js +305 -0
  57. package/dist/{chunk-3ARE4TES.js → chunk-E2E3I5W2.js} +69 -18
  58. package/dist/{chunk-DHWADYZX.js → chunk-EDCBJV7J.js} +41 -28
  59. package/dist/{chunk-WSW6ZFAQ.js → chunk-ENP3BMZU.js} +4 -4
  60. package/dist/{chunk-OOPPQH27.js → chunk-EVOIGUBI.js} +43 -19
  61. package/dist/{chunk-VEAYTRPX.js → chunk-EY4DD67D.js} +165 -97
  62. package/dist/{chunk-223Q2T2Q.js → chunk-F3H33DQX.js} +132 -61
  63. package/dist/{chunk-CYRBHQQZ.js → chunk-F5B3UINI.js} +68 -35
  64. package/dist/{chunk-6X6PQ443.js → chunk-FAJI7BSC.js} +20 -9
  65. package/dist/{chunk-MOUJOP55.js → chunk-FUMHAAF3.js} +96 -29
  66. package/dist/{chunk-6HT2LP62.js → chunk-FV6HMP7W.js} +192 -73
  67. package/dist/{chunk-S7F6XLTK.js → chunk-FYWNRX4F.js} +76 -47
  68. package/dist/{chunk-YG3ZJHGU.js → chunk-FZGAAOKS.js} +30 -8
  69. package/dist/{chunk-YDGVJETP.js → chunk-G3AFC24V.js} +1 -1
  70. package/dist/{chunk-EJBDRVIH.js → chunk-G6UESEVN.js} +15 -8
  71. package/dist/chunk-GDKVKNR2.js +339 -0
  72. package/dist/chunk-GEIGMWNF.js +10 -0
  73. package/dist/{chunk-JUAMLEHX.js → chunk-H7DWSL4O.js} +24 -12
  74. package/dist/chunk-HJFFOOJ4.js +1 -0
  75. package/dist/{chunk-RW6ZL2FQ.js → chunk-HJLPZA4X.js} +106 -21
  76. package/dist/chunk-HYEOQWT7.js +647 -0
  77. package/dist/chunk-I2KLQ2HA.js +19 -0
  78. package/dist/{chunk-CJ5EOYZE.js → chunk-I4FHVKEC.js} +11 -5
  79. package/dist/{chunk-JNH2TYIN.js → chunk-IDM7JJMO.js} +19 -5
  80. package/dist/{chunk-O4AEHWII.js → chunk-IPUNJMAQ.js} +141 -49
  81. package/dist/{chunk-J7Q7VCVC.js → chunk-IT6FUXXG.js} +13 -6
  82. package/dist/{chunk-QJJ6MADV.js → chunk-IVKMZ7BB.js} +80 -28
  83. package/dist/{chunk-Z7H7VSFZ.js → chunk-IXKWIFWZ.js} +17 -6
  84. package/dist/chunk-J64KGCGX.js +55 -0
  85. package/dist/chunk-JBMLWFSJ.js +270 -0
  86. package/dist/{chunk-4BXMXBJO.js → chunk-JJLPBRVZ.js} +22 -11
  87. package/dist/chunk-JLC6PM5S.js +406 -0
  88. package/dist/chunk-JUYWSSKW.js +335 -0
  89. package/dist/{chunk-7CFF4HXS.js → chunk-JV5YOTOB.js} +49 -11
  90. package/dist/{chunk-LZLHELAG.js → chunk-KFJGFLMW.js} +29 -8
  91. package/dist/{chunk-O7AE6DAF.js → chunk-KQZ3GLHR.js} +18 -8
  92. package/dist/{chunk-N32RGOA5.js → chunk-LKFC4CS7.js} +80 -24
  93. package/dist/{chunk-YC6WORFL.js → chunk-LMPHCVJJ.js} +82 -50
  94. package/dist/{chunk-3WPW4KUN.js → chunk-LQP4KEXZ.js} +45 -13
  95. package/dist/{chunk-TKQYWZ5V.js → chunk-LUMVGO2K.js} +47 -31
  96. package/dist/{chunk-AWJOCGFZ.js → chunk-M656FYNH.js} +25 -13
  97. package/dist/{chunk-35OFI3JG.js → chunk-MKSNFG7H.js} +73 -20
  98. package/dist/{chunk-4GBOGOTV.js → chunk-NBEF4EPJ.js} +16 -6
  99. package/dist/chunk-NNCOFLNE.js +24 -0
  100. package/dist/{chunk-4YQOR7JM.js → chunk-NTQ2F3AU.js} +73 -20
  101. package/dist/{chunk-QCDXZBC5.js → chunk-O5V4TG3V.js} +126 -44
  102. package/dist/{chunk-U7TFM2JA.js → chunk-OJQUBQWA.js} +3 -3
  103. package/dist/{chunk-VQHPQEUH.js → chunk-OWAMM2DK.js} +13 -6
  104. package/dist/chunk-PID3NJB7.js +405 -0
  105. package/dist/{chunk-HET4LLMX.js → chunk-PMMTGBBS.js} +27 -17
  106. package/dist/{chunk-RIBDXGUG.js → chunk-PNF3NKB5.js} +49 -16
  107. package/dist/{chunk-JXJB2X6M.js → chunk-Q6NKEPRE.js} +81 -32
  108. package/dist/chunk-QDZGFXQD.js +176 -0
  109. package/dist/{chunk-SYNOJOQO.js → chunk-QEYFDRHR.js} +60 -26
  110. package/dist/{chunk-VBOXAEPI.js → chunk-QHAITQIF.js} +97 -22
  111. package/dist/{chunk-VXDZFJGP.js → chunk-QHTVYA65.js} +230 -76
  112. package/dist/{chunk-TUTI5HOZ.js → chunk-QIKT7LIB.js} +14 -8
  113. package/dist/{chunk-3ENTMPQY.js → chunk-QP3KMOVF.js} +82 -42
  114. package/dist/{chunk-GNNJ4GCC.js → chunk-QPWDDJJ4.js} +62 -148
  115. package/dist/{chunk-QWCMU5B2.js → chunk-QRUMA22E.js} +205 -80
  116. package/dist/{chunk-ZVFE5QGU.js → chunk-QYPE5JX3.js} +50 -10
  117. package/dist/{chunk-PUPM2YGF.js → chunk-ROCUG24E.js} +76 -36
  118. package/dist/{chunk-NQYBUO3K.js → chunk-RU3ZPNL6.js} +333 -142
  119. package/dist/{chunk-TOXAGRDQ.js → chunk-RXSCIO6W.js} +14 -5
  120. package/dist/{chunk-FMYDDECK.js → chunk-SATMR6SG.js} +631 -203
  121. package/dist/{chunk-4YIP3CWS.js → chunk-SHHY5OMK.js} +7 -5
  122. package/dist/chunk-SKWO3SZF.js +2284 -0
  123. package/dist/{chunk-YF4NSSMT.js → chunk-SWS5JQIF.js} +41 -13
  124. package/dist/{chunk-CUMUNPXY.js → chunk-T5LTPKX6.js} +15 -7
  125. package/dist/{chunk-H6NIOQHK.js → chunk-TDMG26JI.js} +26 -6
  126. package/dist/{chunk-UWFLYMAR.js → chunk-TLCIR6RG.js} +267 -126
  127. package/dist/{chunk-SBMNWWBV.js → chunk-TN2ZNJUI.js} +47 -9
  128. package/dist/{chunk-5YNTNN5A.js → chunk-TQVAIKFD.js} +106 -41
  129. package/dist/chunk-TRGFFU6A.js +1456 -0
  130. package/dist/{chunk-2GK6PHGE.js → chunk-TY4MTKQJ.js} +100 -22
  131. package/dist/{chunk-AZRX6SAC.js → chunk-U23FYWME.js} +15 -7
  132. package/dist/{chunk-PZXZJBMP.js → chunk-U5NLHYV6.js} +26 -12
  133. package/dist/chunk-UQEN55EY.js +1 -0
  134. package/dist/chunk-UQGBTPXH.js +218 -0
  135. package/dist/chunk-UXGIW7OK.js +116 -0
  136. package/dist/{chunk-PJXUJYS6.js → chunk-UYGDJWMN.js} +55 -30
  137. package/dist/{chunk-QDYDBCFP.js → chunk-V2OEB75Z.js} +50 -51
  138. package/dist/{chunk-LSS54GLJ.js → chunk-VAOAKWUK.js} +34 -13
  139. package/dist/{chunk-DM5QUKKO.js → chunk-VDPK5CY4.js} +18 -6
  140. package/dist/chunk-W23G6JLF.js +37 -0
  141. package/dist/{chunk-CDRZHT42.js → chunk-W63AJTM7.js} +276 -12
  142. package/dist/{chunk-XXXEFXY5.js → chunk-W74TXYFB.js} +13 -5
  143. package/dist/{chunk-LRJNDEIA.js → chunk-WRDSPUE7.js} +144 -29
  144. package/dist/{chunk-C2NTXVWM.js → chunk-XBZGDDMR.js} +11 -4
  145. package/dist/{chunk-BV3B2HYZ.js → chunk-XIDTBCBA.js} +189 -131
  146. package/dist/{chunk-YTFKPRUK.js → chunk-XN4KG3P4.js} +348 -153
  147. package/dist/chunk-XQXMLMH3.js +211 -0
  148. package/dist/{chunk-HPPW424V.js → chunk-XTORZWRF.js} +19 -8
  149. package/dist/{chunk-P23EQNRQ.js → chunk-YAAHPATV.js} +181 -30
  150. package/dist/{chunk-KMI5ML5I.js → chunk-YXOAPXMU.js} +57 -18
  151. package/dist/{chunk-RJQOOHT2.js → chunk-ZECZOOSB.js} +59 -28
  152. package/dist/{chunk-QKXCPTFS.js → chunk-ZLTO5VQI.js} +121 -31
  153. package/dist/{chunk-BEDBFJND.js → chunk-ZVATDZOM.js} +16 -18
  154. package/dist/coachmark/index.js +6 -3
  155. package/dist/code-block/index.js +5 -3
  156. package/dist/color-field/index.js +6 -4
  157. package/dist/commerce/index.js +19 -16
  158. package/dist/connectivity/index.js +5 -2
  159. package/dist/context-menu/index.js +5 -3
  160. package/dist/copy-button/index.js +4 -2
  161. package/dist/data-grid/index.js +21 -16
  162. package/dist/date-range-picker/index.js +11 -8
  163. package/dist/description-list/index.js +3 -1
  164. package/dist/dialog/index.js +4 -2
  165. package/dist/empty-state/index.js +4 -2
  166. package/dist/error-summary/index.js +4 -2
  167. package/dist/fab/index.js +5 -2
  168. package/dist/file-manager/index.js +28 -0
  169. package/dist/file-upload/index.js +10 -7
  170. package/dist/filter-bar/index.js +9 -6
  171. package/dist/flow-run/index.js +15 -12
  172. package/dist/form/index.js +5 -3
  173. package/dist/gallery/index.js +5 -2
  174. package/dist/hold-to-confirm/index.js +4 -2
  175. package/dist/index.d.ts +9557 -2985
  176. package/dist/index.js +355 -122
  177. package/dist/infinite-list/index.js +4 -2
  178. package/dist/inline-edit/index.js +6 -4
  179. package/dist/input/index.js +5 -3
  180. package/dist/interactions/index.js +2 -1
  181. package/dist/invoice/index.js +13 -9
  182. package/dist/kbd/index.js +5 -1
  183. package/dist/keyboard/index.js +4 -2
  184. package/dist/list-row/index.js +6 -4
  185. package/dist/log-viewer/index.js +4 -2
  186. package/dist/map-view/index.js +5 -3
  187. package/dist/markdown/index.js +9 -6
  188. package/dist/metric/index.js +7 -4
  189. package/dist/money/index.js +9 -3
  190. package/dist/nav-drawer/index.js +4 -2
  191. package/dist/nav-header/index.js +9 -0
  192. package/dist/navigation/index.js +5 -2
  193. package/dist/notification-center/index.js +12 -10
  194. package/dist/number-roll/index.js +5 -2
  195. package/dist/one-handed/index.js +5 -3
  196. package/dist/os-surfaces/index.js +6 -3
  197. package/dist/otp/index.js +7 -4
  198. package/dist/page-header/index.js +1 -0
  199. package/dist/pagination/index.js +6 -0
  200. package/dist/payment-method/index.js +14 -10
  201. package/dist/payment-status/index.js +17 -14
  202. package/dist/permission/index.js +5 -2
  203. package/dist/picker/index.js +11 -6
  204. package/dist/progress/index.js +6 -3
  205. package/dist/pull-to-refresh/index.js +4 -2
  206. package/dist/radio-group/index.js +6 -4
  207. package/dist/rating/index.js +5 -2
  208. package/dist/receivables/index.js +21 -16
  209. package/dist/refund/index.js +18 -14
  210. package/dist/save-status/index.js +5 -3
  211. package/dist/scroll-area/index.js +3 -1
  212. package/dist/search-field/index.js +8 -0
  213. package/dist/segmented-control/index.js +4 -3
  214. package/dist/sheet/index.js +5 -3
  215. package/dist/skeleton/index.js +3 -1
  216. package/dist/slider/index.js +4 -2
  217. package/dist/sortable/index.js +7 -0
  218. package/dist/spinner/index.js +3 -1
  219. package/dist/split-button/index.js +9 -6
  220. package/dist/spotlight/index.js +3 -1
  221. package/dist/stage-timeline/index.js +5 -3
  222. package/dist/status-dot/index.js +4 -2
  223. package/dist/stepper/index.js +7 -4
  224. package/dist/streaming-text/index.js +3 -2
  225. package/dist/survey/index.js +18 -15
  226. package/dist/switch/index.js +5 -3
  227. package/dist/system-state/index.js +7 -4
  228. package/dist/tab-bar/index.js +5 -2
  229. package/dist/tabs/index.js +4 -2
  230. package/dist/tags-input/index.js +10 -0
  231. package/dist/textarea/index.js +6 -4
  232. package/dist/thinking/index.js +3 -1
  233. package/dist/time-field/index.js +12 -0
  234. package/dist/time-range-control/index.js +22 -0
  235. package/dist/timeline/index.js +4 -2
  236. package/dist/toast/index.js +4 -2
  237. package/dist/toolbar/index.js +4 -2
  238. package/dist/tour/index.js +12 -9
  239. package/dist/truncation-notice/index.js +5 -2
  240. package/dist/update-notice/index.js +12 -9
  241. package/dist/video-player/index.js +5 -2
  242. package/dist/viewfinder/index.js +6 -4
  243. package/dist/widget/index.js +7 -4
  244. package/dist/wizard/index.js +7 -4
  245. package/package.json +13 -12
  246. package/dist/chunk-6N33LFQA.js +0 -35
  247. package/dist/chunk-GDKZTW34.js +0 -395
  248. package/dist/chunk-GL7B2DOW.js +0 -134
  249. package/dist/chunk-NKB7BZYK.js +0 -167
  250. package/dist/chunk-OETCUXQP.js +0 -134
  251. package/dist/chunk-OPXFZ4Y5.js +0 -204
  252. package/dist/chunk-Q72LJOVE.js +0 -169
  253. package/dist/chunk-RNGLIHFA.js +0 -191
  254. package/dist/chunk-RQ3HASCC.js +0 -6
  255. package/dist/chunk-RSOJT5YW.js +0 -124
  256. package/dist/chunk-TKVFVF5D.js +0 -95
  257. package/dist/chunk-XOSCY2CW.js +0 -242
  258. package/dist/header/index.js +0 -5
  259. package/dist/search-bar/index.js +0 -5
  260. /package/dist/{chunk-3ECPOSKO.js → chunk-3UG6JUCV.js} +0 -0
  261. /package/dist/{chunk-JRLTGLN4.js → chunk-5WWRTEPS.js} +0 -0
  262. /package/dist/{chunk-RTIKSY6A.js → chunk-5Z5ZYMOJ.js} +0 -0
@@ -1,19 +1,70 @@
1
- import { Timeline } from './chunk-4GBOGOTV.js';
2
- import { List, ListRow } from './chunk-IVNRBPGC.js';
3
- import { EmptyState } from './chunk-LZLHELAG.js';
4
- import { methodIcon } from './chunk-PUPM2YGF.js';
5
- import { Amount } from './chunk-VBOXAEPI.js';
6
- import { Sheet } from './chunk-ZVFE5QGU.js';
7
- import { Badge } from './chunk-SBMNWWBV.js';
8
- import { Alert } from './chunk-OETCUXQP.js';
9
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { Timeline } from './chunk-NBEF4EPJ.js';
2
+ import { List, ListRow } from './chunk-C4GTDLRC.js';
3
+ import { EmptyState } from './chunk-KFJGFLMW.js';
4
+ import { Amount } from './chunk-QHAITQIF.js';
5
+ import { Sheet } from './chunk-QYPE5JX3.js';
6
+ import { methodIcon } from './chunk-ROCUG24E.js';
7
+ import { usePayLabels } from './chunk-GEIGMWNF.js';
8
+ import { Badge } from './chunk-TN2ZNJUI.js';
9
+ import { Alert } from './chunk-QDZGFXQD.js';
10
+ import { Button } from './chunk-E2E3I5W2.js';
11
+ import { useLabels, useLoamLocale } from './chunk-APCWFOZW.js';
12
+ import { Icon } from './chunk-UXGIW7OK.js';
13
+ import { useResolvedMotion, springConfig } from './chunk-J64KGCGX.js';
10
14
  import * as React from 'react';
11
- import { View, Text, Pressable } from 'react-native';
15
+ import { Platform, findNodeHandle, AccessibilityInfo, View, Text, Pressable, Animated } from 'react-native';
12
16
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
13
- import { receivableStatus, methodFor, bucketFor } from '@btndprojects/loam-pay';
17
+ import { receivableStatus, methodFor, methodText, money, agingLabel, dunningText, bucketFor } from '@btndprojects/loam-pay';
14
18
  export { LEDGER_CARD_BREAKPOINT } from '@btndprojects/loam-pay';
15
19
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
16
20
 
21
+ // src/receivables/receivables-labels.ts
22
+ var plural = (n, one, other) => `${n} ${n === 1 ? one : other}`;
23
+ var DEFAULT_LABELS = {
24
+ actions: "Actions",
25
+ actionsFor: (label, no) => `${label} \u2014 ${no}`,
26
+ customer: "Customer",
27
+ invoice: "Invoice",
28
+ amount: "Amount",
29
+ due: "Due",
30
+ status: "Status",
31
+ method: "Method",
32
+ lateDays: (d) => `${d}d late`,
33
+ dueToday: "Due today",
34
+ dueIn: (d) => `in ${d}d`,
35
+ emptyMessage: "Nothing outstanding.",
36
+ caption: "Outstanding invoices",
37
+ emptyTitle: "Nothing outstanding",
38
+ open: "Open",
39
+ openRow: (open, no, who) => `${open} ${no} \u2014 ${who}`,
40
+ agingLabel: "Accounts receivable aging",
41
+ invoiceCount: (n) => plural(n, "invoice", "invoices"),
42
+ openRowDetail: (open, no, who, amount, status, due) => `${open} ${no} \u2014 ${who}, ${amount}, ${status}, ${due}`,
43
+ bucketSummary: (bucket, amount, count) => `${bucket} \u2014 ${amount}, ${count}`,
44
+ cannotBeUndone: "This cannot be undone.",
45
+ cancel: "Cancel",
46
+ asksConfirm: "Asks you to confirm",
47
+ confirmTitle: (action, no) => `${action} \u2014 ${no}?`,
48
+ day: "Day",
49
+ dayN: (d) => `Day ${d}`,
50
+ now: "Now",
51
+ retrySchedule: "Retry schedule",
52
+ reminderSchedule: "Reminder schedule",
53
+ sending: "Sending",
54
+ scheduled: "Scheduled",
55
+ reminderTitle: (day) => {
56
+ if (day < 0) return `Due in ${plural(-day, "day", "days")}`;
57
+ if (day === 0) return "Due today";
58
+ return `${plural(day, "day", "days")} past due`;
59
+ },
60
+ reminderBefore: "A heads-up before the due date, so a slow approval chain has time to move.",
61
+ reminderOn: "The due date, restated with the amount and the same pay link.",
62
+ reminderAfter: "The same template again, one sentence clearer about how late it now is.",
63
+ overdueTitle: (invoice, days) => `overdue on ${invoice} \u2014 ${plural(days, "day", "days")} past due`,
64
+ dueTitle: (invoice) => `due on ${invoice}`,
65
+ overdueDescription: (due) => `The due date was ${due}. Paying now clears it; if it has already been paid, tell us and we will match it up.`,
66
+ dueDescription: (due) => `Due ${due}. Nothing is late yet \u2014 this is a heads-up so an approval chain has time to move.`
67
+ };
17
68
  var RECEIVABLE_COLUMNS = [
18
69
  "who",
19
70
  "no",
@@ -22,33 +73,75 @@ var RECEIVABLE_COLUMNS = [
22
73
  "status",
23
74
  "method"
24
75
  ];
25
- function dueWords(dueIn) {
26
- if (dueIn < 0) return `${-dueIn}d late`;
27
- if (dueIn === 0) return "Due today";
28
- return `in ${dueIn}d`;
76
+ function dueWords(dueIn, labels = DEFAULT_LABELS) {
77
+ if (dueIn < 0) return labels.lateDays(-dueIn);
78
+ if (dueIn === 0) return labels.dueToday;
79
+ return labels.dueIn(dueIn);
29
80
  }
30
81
  function ReceivablesCardList({
31
82
  rows,
32
83
  actions = [],
33
- actionsLabel = "Actions",
34
- emptyTitle = "Nothing outstanding",
84
+ actionsLabel: actionsLabelProp,
85
+ emptyTitle: emptyTitleProp,
35
86
  emptyDescription,
36
- openLabel = "Open",
87
+ openLabel: openLabelProp,
37
88
  onOpenRow,
38
89
  onAction,
39
- locale,
90
+ confirmMessage: confirmMessageProp,
91
+ cancelLabel: cancelLabelProp,
92
+ locale: localeProp,
93
+ labels: labelsProp,
40
94
  style
41
95
  }) {
42
- const theme = useLoamTheme();
96
+ const labels = useLabels("receivables", DEFAULT_LABELS, labelsProp);
97
+ const pay = usePayLabels(labelsProp);
98
+ const providerLocale = useLoamLocale();
99
+ const locale = localeProp ?? providerLocale;
100
+ const actionsLabel = actionsLabelProp ?? labels.actions;
101
+ const emptyTitle = emptyTitleProp ?? labels.emptyTitle;
102
+ const openLabel = openLabelProp ?? labels.open;
103
+ const confirmMessage = confirmMessageProp ?? labels.cannotBeUndone;
104
+ const cancelLabel = cancelLabelProp ?? labels.cancel;
105
+ const theme = useLoamTheme("receivables");
43
106
  const { styles } = useStyles(sheet);
44
107
  const [menuFor, setMenuFor] = React.useState(null);
108
+ const [confirming, setConfirming] = React.useState(null);
109
+ const confirmTitle = React.useRef(null);
110
+ const closeMenu = () => {
111
+ setMenuFor(null);
112
+ setConfirming(null);
113
+ };
114
+ const run = (id) => {
115
+ const no = menuFor;
116
+ closeMenu();
117
+ if (no !== null) onAction?.(no, id);
118
+ };
119
+ React.useEffect(() => {
120
+ if (!confirming) return;
121
+ const node = confirmTitle.current;
122
+ if (!node) return;
123
+ if (Platform.OS === "web") node.focus?.();
124
+ else {
125
+ const handle = findNodeHandle(node);
126
+ if (handle) AccessibilityInfo.setAccessibilityFocus(handle);
127
+ }
128
+ }, [confirming]);
45
129
  if (rows.length === 0) {
46
- return /* @__PURE__ */ jsx(EmptyState, { variant: "empty", icon: "invoice", title: emptyTitle, description: emptyDescription });
130
+ return /* @__PURE__ */ jsx(
131
+ EmptyState,
132
+ {
133
+ variant: "empty",
134
+ icon: "invoice",
135
+ title: emptyTitle,
136
+ description: emptyDescription
137
+ }
138
+ );
47
139
  }
48
140
  return /* @__PURE__ */ jsxs(View, { style, children: [
49
141
  /* @__PURE__ */ jsx(List, { role: "list", children: rows.map((r) => {
50
- const s = receivableStatus(r);
142
+ const s = receivableStatus(r, pay);
51
143
  const def = methodFor(r.method);
144
+ const methodName = methodText(r.method, pay)?.label ?? r.method;
52
145
  return (
53
146
  // The trigger is a sibling of the row, not a child: a row rendered
54
147
  // interactive is a real pressable, and a second pressable inside it
@@ -58,7 +151,14 @@ function ReceivablesCardList({
58
151
  ListRow,
59
152
  {
60
153
  onPress: onOpenRow ? () => onOpenRow(r.no) : void 0,
61
- accessibilityLabel: onOpenRow ? `${openLabel} ${r.no} \u2014 ${r.who}` : void 0,
154
+ accessibilityLabel: onOpenRow ? labels.openRowDetail(
155
+ openLabel,
156
+ r.no,
157
+ r.who,
158
+ money(r.amount, r.cur, { locale }),
159
+ s.label,
160
+ dueWords(r.dueIn, labels)
161
+ ) : void 0,
62
162
  title: /* @__PURE__ */ jsxs(View, { style: styles.titleRow, children: [
63
163
  /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.who, children: r.who }),
64
164
  /* @__PURE__ */ jsx(View, { style: styles.pushEnd, children: /* @__PURE__ */ jsx(
@@ -75,7 +175,7 @@ function ReceivablesCardList({
75
175
  subtitle: /* @__PURE__ */ jsxs(View, { style: styles.subRow, children: [
76
176
  /* @__PURE__ */ jsx(Text, { style: styles.no, children: r.no }),
77
177
  /* @__PURE__ */ jsx(Badge, { variant: s.tone, size: "sm", children: s.label }),
78
- /* @__PURE__ */ jsx(Text, { style: styles.due, children: dueWords(r.dueIn) }),
178
+ /* @__PURE__ */ jsx(Text, { style: styles.due, children: dueWords(r.dueIn, labels) }),
79
179
  /* @__PURE__ */ jsxs(View, { style: styles.methodRow, children: [
80
180
  /* @__PURE__ */ jsx(
81
181
  Icon,
@@ -85,7 +185,7 @@ function ReceivablesCardList({
85
185
  color: theme.color.text3
86
186
  }
87
187
  ),
88
- /* @__PURE__ */ jsx(Text, { style: styles.method, children: def?.label ?? r.method })
188
+ /* @__PURE__ */ jsx(Text, { style: styles.method, children: methodName })
89
189
  ] })
90
190
  ] })
91
191
  }
@@ -94,7 +194,7 @@ function ReceivablesCardList({
94
194
  Pressable,
95
195
  {
96
196
  accessibilityRole: "button",
97
- accessibilityLabel: `${actionsLabel} \u2014 ${r.no}`,
197
+ accessibilityLabel: labels.actionsFor(actionsLabel, r.no),
98
198
  onPress: () => setMenuFor(r.no),
99
199
  style: styles.menuTrigger,
100
200
  children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: theme.icon.md, color: theme.color.text2 })
@@ -107,9 +207,29 @@ function ReceivablesCardList({
107
207
  Sheet,
108
208
  {
109
209
  open: menuFor !== null,
110
- title: menuFor === null ? actionsLabel : `${actionsLabel} \u2014 ${menuFor}`,
111
- onClose: () => setMenuFor(null),
112
- children: /* @__PURE__ */ jsx(View, { role: "list", accessibilityRole: "list", style: styles.actionList, children: actions.map((a) => (
210
+ title: menuFor === null ? actionsLabel : labels.actionsFor(actionsLabel, menuFor),
211
+ onClose: closeMenu,
212
+ children: confirming ? /* @__PURE__ */ jsxs(View, { style: styles.confirm, children: [
213
+ /* @__PURE__ */ jsxs(
214
+ View,
215
+ {
216
+ ref: confirmTitle,
217
+ accessible: true,
218
+ accessibilityRole: "header",
219
+ ...Platform.OS === "web" ? { tabIndex: -1 } : null,
220
+ style: styles.confirmTitleRow,
221
+ children: [
222
+ /* @__PURE__ */ jsx(Icon, { name: "alert-triangle", size: theme.icon.md, color: theme.color.danger }),
223
+ /* @__PURE__ */ jsx(Text, { style: styles.confirmTitle, children: labels.confirmTitle(confirming.label, menuFor ?? "") })
224
+ ]
225
+ }
226
+ ),
227
+ /* @__PURE__ */ jsx(Text, { style: styles.confirmMessage, children: confirmMessage }),
228
+ /* @__PURE__ */ jsxs(View, { style: styles.confirmActions, children: [
229
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onPress: () => setConfirming(null), children: cancelLabel }),
230
+ /* @__PURE__ */ jsx(Button, { variant: "danger", onPress: () => run(confirming.id), children: confirming.label })
231
+ ] })
232
+ ] }) : /* @__PURE__ */ jsx(View, { role: "list", accessibilityRole: "list", style: styles.actionList, children: actions.map((a) => (
113
233
  // The item and the control are separate nodes: `role="listitem"`
114
234
  // and `accessibilityRole="button"` on one element are two roles
115
235
  // fighting over the same node, and react-native-web resolves it
@@ -120,11 +240,8 @@ function ReceivablesCardList({
120
240
  {
121
241
  accessibilityRole: "button",
122
242
  accessibilityLabel: a.label,
123
- onPress: () => {
124
- const no = menuFor;
125
- setMenuFor(null);
126
- if (no !== null) onAction?.(no, a.id);
127
- },
243
+ accessibilityHint: a.danger ? labels.asksConfirm : void 0,
244
+ onPress: () => a.danger ? setConfirming(a) : run(a.id),
128
245
  style: ({ pressed }) => [
129
246
  styles.actionRow,
130
247
  pressed ? styles.actionRowPressed : null
@@ -138,7 +255,18 @@ function ReceivablesCardList({
138
255
  color: a.danger ? theme.color.danger : theme.color.text2
139
256
  }
140
257
  ) : null,
141
- /* @__PURE__ */ jsx(Text, { style: [styles.actionLabel, a.danger ? styles.actionLabelDanger : null], children: a.label })
258
+ /* @__PURE__ */ jsx(Text, { style: [styles.actionLabel, a.danger ? styles.actionLabelDanger : null], children: a.label }),
259
+ a.danger ? (
260
+ // Destructive is said in shape too, not in red alone.
261
+ /* @__PURE__ */ jsx(View, { style: styles.pushEnd, children: /* @__PURE__ */ jsx(
262
+ Icon,
263
+ {
264
+ name: "alert-triangle",
265
+ size: theme.icon.sm,
266
+ color: theme.color.danger
267
+ }
268
+ ) })
269
+ ) : null
142
270
  ]
143
271
  }
144
272
  ) }, a.id)
@@ -209,7 +337,24 @@ var sheet = createStyleSheet((theme) => ({
209
337
  lineHeight: theme.type.body.lineHeight,
210
338
  color: theme.color.text
211
339
  },
212
- actionLabelDanger: { color: theme.color.danger }
340
+ actionLabelDanger: { color: theme.color.danger },
341
+ confirm: { gap: theme.space.s3 },
342
+ confirmTitleRow: { flexDirection: "row", alignItems: "center", gap: theme.space.s2 },
343
+ confirmTitle: {
344
+ flexShrink: 1,
345
+ fontFamily: theme.font.sans,
346
+ fontSize: theme.type.body.fontSize,
347
+ lineHeight: theme.type.body.lineHeight,
348
+ fontWeight: theme.fontWeight.semibold,
349
+ color: theme.color.text
350
+ },
351
+ confirmMessage: {
352
+ fontFamily: theme.font.sans,
353
+ fontSize: theme.type.footnote.fontSize,
354
+ lineHeight: theme.type.footnote.lineHeight,
355
+ color: theme.color.text2
356
+ },
357
+ confirmActions: { flexDirection: "row", justifyContent: "flex-end", gap: theme.space.s2 }
213
358
  }));
214
359
  function tilePaint(theme, tone) {
215
360
  switch (tone) {
@@ -252,17 +397,38 @@ function AgingBucketCard({
252
397
  tone,
253
398
  fill = 0,
254
399
  onSelect,
255
- locale,
400
+ locale: localeProp,
256
401
  countLabel,
257
- style
402
+ labels: labelsProp,
403
+ style,
404
+ motion = "full",
405
+ delay = 0
258
406
  }) {
259
- const theme = useLoamTheme();
407
+ const labels = useLabels("receivables", DEFAULT_LABELS, labelsProp);
408
+ const pay = usePayLabels(labelsProp);
409
+ const providerLocale = useLoamLocale();
410
+ const locale = localeProp ?? providerLocale;
411
+ const theme = useLoamTheme("receivables");
260
412
  const { styles } = useStyles(sheet2);
261
413
  const paint = tilePaint(theme, tone);
262
414
  const pct = Math.round(Math.min(1, Math.max(0, fill)) * 100);
263
- const words = countLabel ?? (count === 1 ? "invoice" : "invoices");
415
+ const level = useResolvedMotion(motion, "receivables");
416
+ const grow = React.useRef(new Animated.Value(level === "full" ? 0 : pct)).current;
417
+ React.useEffect(() => {
418
+ if (level !== "full") {
419
+ grow.setValue(pct);
420
+ return;
421
+ }
422
+ const run = Animated.sequence([
423
+ Animated.delay(delay),
424
+ Animated.spring(grow, { ...springConfig(theme, "ds"), toValue: pct, useNativeDriver: false })
425
+ ]);
426
+ run.start();
427
+ return () => run.stop();
428
+ }, [pct, level]);
429
+ const countText = countLabel ? `${count} ${countLabel}` : labels.invoiceCount(count);
264
430
  const body = /* @__PURE__ */ jsxs(Fragment, { children: [
265
- /* @__PURE__ */ jsx(Text, { style: [styles.bucketName, { color: paint.ink }], children: bucket }),
431
+ /* @__PURE__ */ jsx(Text, { style: [styles.bucketName, { color: paint.ink }], children: agingLabel({ bucket }, pay) }),
266
432
  /* @__PURE__ */ jsx(
267
433
  Amount,
268
434
  {
@@ -281,10 +447,25 @@ function AgingBucketCard({
281
447
  accessibilityElementsHidden: true,
282
448
  importantForAccessibility: "no-hide-descendants",
283
449
  style: styles.rail,
284
- children: /* @__PURE__ */ jsx(View, { style: [styles.railFill, { width: `${pct}%`, backgroundColor: paint.bar }] })
450
+ children: /* @__PURE__ */ jsx(
451
+ Animated.View,
452
+ {
453
+ style: [
454
+ styles.railFill,
455
+ {
456
+ width: grow.interpolate({
457
+ inputRange: [0, 100],
458
+ outputRange: ["0%", "100%"],
459
+ extrapolate: "clamp"
460
+ }),
461
+ backgroundColor: paint.bar
462
+ }
463
+ ]
464
+ }
465
+ )
285
466
  }
286
467
  ),
287
- /* @__PURE__ */ jsx(Text, { style: [styles.count, { color: paint.ink }], children: `${count} ${words}` })
468
+ /* @__PURE__ */ jsx(Text, { style: [styles.count, { color: paint.ink }], children: countText })
288
469
  ] });
289
470
  const tile = [
290
471
  styles.tile,
@@ -296,7 +477,11 @@ function AgingBucketCard({
296
477
  Pressable,
297
478
  {
298
479
  accessibilityRole: "button",
299
- accessibilityLabel: `${bucket} \u2014 ${count} ${words}`,
480
+ accessibilityLabel: labels.bucketSummary(
481
+ agingLabel({ bucket }, pay),
482
+ money(minor, currency, { locale }),
483
+ countText
484
+ ),
300
485
  onPress: onSelect,
301
486
  style: tile,
302
487
  children: ({ pressed }) => /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -313,12 +498,15 @@ function AgingSummary({
313
498
  currency,
314
499
  onSelectBucket,
315
500
  locale,
316
- label = "Accounts receivable aging",
317
- style
501
+ label,
502
+ labels: labelsProp,
503
+ style,
504
+ motion = "full"
318
505
  }) {
506
+ const labels = useLabels("receivables", DEFAULT_LABELS, labelsProp);
319
507
  const { styles } = useStyles(sheet2);
320
508
  const peak = buckets.reduce((m, b) => Math.max(m, Math.abs(b.minor)), 0);
321
- return /* @__PURE__ */ jsx(View, { role: "group", accessibilityLabel: label, style: [styles.strip, style], children: buckets.map((b) => /* @__PURE__ */ jsx(
509
+ return /* @__PURE__ */ jsx(View, { role: "group", accessibilityLabel: label ?? labels.agingLabel, style: [styles.strip, style], children: buckets.map((b, i) => /* @__PURE__ */ jsx(
322
510
  AgingBucketCard,
323
511
  {
324
512
  bucket: b.bucket.bucket,
@@ -328,6 +516,9 @@ function AgingSummary({
328
516
  tone: b.bucket.tone,
329
517
  fill: peak === 0 ? 0 : Math.abs(b.minor) / peak,
330
518
  locale,
519
+ motion,
520
+ labels: labelsProp,
521
+ delay: Math.min(i, 8) * 30,
331
522
  onSelect: onSelectBucket ? () => onSelectBucket(b.bucket.bucket) : void 0
332
523
  },
333
524
  b.bucket.bucket
@@ -434,10 +625,12 @@ function DunningRung({
434
625
  surface,
435
626
  tone,
436
627
  current = false,
437
- dayLabel = "Day",
628
+ dayLabel,
629
+ labels: labelsProp,
438
630
  style
439
631
  }) {
440
- const theme = useLoamTheme();
632
+ const labels = useLabels("receivables", DEFAULT_LABELS, labelsProp);
633
+ const theme = useLoamTheme("receivables");
441
634
  const { styles } = useStyles(sheet3);
442
635
  const paint = rungPaint(theme, tone);
443
636
  const currentAttr = current ? { "aria-current": "step" } : {};
@@ -449,7 +642,7 @@ function DunningRung({
449
642
  testID: `dunning-rung-${day}${current ? "-current" : ""}`,
450
643
  style: [styles.rung, current ? styles.rungCurrent : null, style],
451
644
  children: [
452
- /* @__PURE__ */ jsx(View, { style: [styles.dayBadge, { borderColor: paint.edge, backgroundColor: paint.fill }], children: /* @__PURE__ */ jsx(Text, { style: [styles.dayLabel, { color: paint.ink }], children: `${dayLabel} ${day}` }) }),
645
+ /* @__PURE__ */ jsx(View, { style: [styles.dayBadge, { borderColor: paint.edge, backgroundColor: paint.fill }], children: /* @__PURE__ */ jsx(Text, { style: [styles.dayLabel, { color: paint.ink }], children: dayLabel ? `${dayLabel} ${day}` : labels.dayN(day) }) }),
453
646
  /* @__PURE__ */ jsx(
454
647
  View,
455
648
  {
@@ -465,7 +658,7 @@ function DunningRung({
465
658
  ] }),
466
659
  current ? (
467
660
  // The third marker. Never colour alone.
468
- /* @__PURE__ */ jsx(Text, { style: styles.now, children: "Now" })
661
+ /* @__PURE__ */ jsx(Text, { style: styles.now, children: labels.now })
469
662
  ) : null
470
663
  ]
471
664
  }
@@ -475,23 +668,27 @@ function DunningTimeline({
475
668
  steps,
476
669
  tones,
477
670
  currentDay,
478
- dayLabel = "Day",
671
+ dayLabel,
479
672
  density = "comfortable",
480
- label = "Retry schedule",
673
+ label,
674
+ labels: labelsProp,
481
675
  style
482
676
  }) {
677
+ const labels = useLabels("receivables", DEFAULT_LABELS, labelsProp);
678
+ const pay = usePayLabels(labelsProp);
483
679
  const { styles } = useStyles(sheet3);
484
680
  const items = steps.map((s, i) => {
485
681
  const tone = RUNG_TONE[tones?.[i] ?? "warn"];
486
682
  const current = currentDay === s.day;
683
+ const text = dunningText(s, pay);
487
684
  return {
488
685
  id: `dunning-${s.day}`,
489
- time: `${dayLabel} ${s.day}`,
490
- title: s.attempt,
686
+ time: dayLabel ? `${dayLabel} ${s.day}` : labels.dayN(s.day),
687
+ title: text.attempt,
491
688
  description: current ? /* @__PURE__ */ jsxs(Fragment, { children: [
492
- /* @__PURE__ */ jsx(Text, { children: `${s.surface} ` }),
493
- /* @__PURE__ */ jsx(Text, { style: styles.now, children: "Now" })
494
- ] }) : s.surface,
689
+ /* @__PURE__ */ jsx(Text, { children: `${text.surface} ` }),
690
+ /* @__PURE__ */ jsx(Text, { style: styles.now, children: labels.now })
691
+ ] }) : text.surface,
495
692
  tone,
496
693
  icon: RUNG_ICON[tone],
497
694
  current,
@@ -500,12 +697,10 @@ function DunningTimeline({
500
697
  testID: `dunning-rung-${s.day}${current ? "-current" : ""}`
501
698
  };
502
699
  });
503
- return /* @__PURE__ */ jsx(Timeline, { items, density, label, style });
700
+ return /* @__PURE__ */ jsx(Timeline, { items, density, label: label ?? labels.retrySchedule, style });
504
701
  }
505
- function reminderTitle(day) {
506
- if (day < 0) return `Due in ${-day} ${-day === 1 ? "day" : "days"}`;
507
- if (day === 0) return "Due today";
508
- return `${day} ${day === 1 ? "day" : "days"} past due`;
702
+ function reminderTitle(day, labels = DEFAULT_LABELS) {
703
+ return labels.reminderTitle(day);
509
704
  }
510
705
  function ReminderTimeline({
511
706
  days,
@@ -513,28 +708,33 @@ function ReminderTimeline({
513
708
  currentDay,
514
709
  titles = {},
515
710
  density = "comfortable",
516
- label = "Reminder schedule"
711
+ label,
712
+ labels: labelsProp
517
713
  }) {
714
+ const labels = useLabels("receivables", DEFAULT_LABELS, labelsProp);
518
715
  const items = days.map((d) => {
519
716
  const sent = sentAt[d];
520
717
  const isCurrent = currentDay === d;
521
718
  return {
522
719
  id: `reminder-${d}`,
523
- time: sent ?? (isCurrent ? "Sending" : "Scheduled"),
524
- title: titles[d] ?? reminderTitle(d),
720
+ time: sent ?? (isCurrent ? labels.sending : labels.scheduled),
721
+ title: titles[d] ?? reminderTitle(d, labels),
525
722
  // The one changed sentence sits here, under a headline that is the same
526
723
  // shape on every rung.
527
- description: d < 0 ? "A heads-up before the due date, so a slow approval chain has time to move." : d === 0 ? "The due date, restated with the amount and the same pay link." : "The same template again, one sentence clearer about how late it now is.",
724
+ description: d < 0 ? labels.reminderBefore : d === 0 ? labels.reminderOn : labels.reminderAfter,
528
725
  state: sent ? "done" : isCurrent ? "working" : "pending",
529
726
  icon: sent ? "check" : isCurrent ? "mail" : "clock"
530
727
  };
531
728
  });
532
- return /* @__PURE__ */ jsx(Timeline, { items, density, label });
729
+ return /* @__PURE__ */ jsx(Timeline, { items, density, label: label ?? labels.reminderSchedule });
533
730
  }
534
731
  function overdueTone(daysLate) {
535
732
  const tone = bucketFor(daysLate).tone;
536
733
  return tone === "good" ? "info" : tone;
537
734
  }
735
+ function sentenceCase(text, locale) {
736
+ return text.charAt(0).toLocaleUpperCase(locale) + text.slice(1);
737
+ }
538
738
  function OverdueNotice({
539
739
  invoiceNumber,
540
740
  minor,
@@ -546,9 +746,13 @@ function OverdueNotice({
546
746
  action,
547
747
  dismissible,
548
748
  onDismiss,
549
- locale,
749
+ locale: localeProp,
750
+ labels: labelsProp,
550
751
  style
551
752
  }) {
753
+ const labels = useLabels("receivables", DEFAULT_LABELS, labelsProp);
754
+ const providerLocale = useLoamLocale();
755
+ const locale = localeProp ?? providerLocale;
552
756
  const { styles } = useStyles(sheet3);
553
757
  const resolved = tone ?? overdueTone(daysLate);
554
758
  const late = daysLate > 0;
@@ -561,8 +765,8 @@ function OverdueNotice({
561
765
  dismissible,
562
766
  onDismiss,
563
767
  action,
564
- title: late ? `Overdue on ${invoiceNumber} \u2014 ${daysLate} ${daysLate === 1 ? "day" : "days"} past due` : `Due on ${invoiceNumber}`,
565
- description: message ?? (late ? `The due date was ${dueLabel}. Paying now clears it; if it has already been paid, tell us and we will match it up.` : `Due ${dueLabel}. Nothing is late yet \u2014 this is a heads-up so an approval chain has time to move.`)
768
+ title: late ? sentenceCase(labels.overdueTitle(invoiceNumber, daysLate), locale) : sentenceCase(labels.dueTitle(invoiceNumber), locale),
769
+ description: message ?? (late ? labels.overdueDescription(dueLabel) : labels.dueDescription(dueLabel))
566
770
  }
567
771
  )
568
772
  ] });