@btndprojects/loam-ui-native 0.1.1 → 0.3.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 (412) hide show
  1. package/dist/accordion/index.js +7 -3
  2. package/dist/adaptive/index.js +16 -2
  3. package/dist/address-block/index.js +23 -0
  4. package/dist/alert/index.js +8 -2
  5. package/dist/analyzer/index.js +17 -6
  6. package/dist/announcement/index.js +18 -5
  7. package/dist/appearance-picker/index.js +15 -0
  8. package/dist/audio-player/index.js +29 -3
  9. package/dist/avatar/index.js +5 -2
  10. package/dist/avatar-group/index.js +9 -3
  11. package/dist/badge/index.js +10 -4
  12. package/dist/banner/index.js +6 -2
  13. package/dist/board/index.js +18 -6
  14. package/dist/button/index.js +9 -3
  15. package/dist/camera-permission/index.js +23 -12
  16. package/dist/capture-result/index.js +30 -17
  17. package/dist/card/index.js +10 -3
  18. package/dist/card-form/index.js +19 -9
  19. package/dist/carousel/index.js +6 -2
  20. package/dist/chart/index.js +18 -5
  21. package/dist/charts/index.js +21 -6
  22. package/dist/chat/index.js +41 -0
  23. package/dist/checkbox/index.js +9 -5
  24. package/dist/checklist/index.js +20 -8
  25. package/dist/checkout/index.js +30 -12
  26. package/dist/chip/index.js +11 -5
  27. package/dist/chunk-2BZD3NAP.js +1110 -0
  28. package/dist/chunk-2YKVID2V.js +35 -0
  29. package/dist/{chunk-JUAMLEHX.js → chunk-36DA3IPO.js} +137 -37
  30. package/dist/chunk-3A56MIAN.js +599 -0
  31. package/dist/chunk-3SCKCWF5.js +298 -0
  32. package/dist/chunk-3TZNDHKO.js +187 -0
  33. package/dist/chunk-43K3BLXV.js +9 -0
  34. package/dist/chunk-46ZJIQ2Z.js +208 -0
  35. package/dist/chunk-4CZMQDQL.js +192 -0
  36. package/dist/chunk-5DTKORLI.js +255 -0
  37. package/dist/{chunk-LOE5YNN3.js → chunk-5J4WFXFA.js} +68 -24
  38. package/dist/chunk-5KJ7TEQ6.js +305 -0
  39. package/dist/chunk-5NU33TXK.js +529 -0
  40. package/dist/chunk-5Z5ZYMOJ.js +1 -0
  41. package/dist/chunk-6KSUS7DF.js +690 -0
  42. package/dist/chunk-6RV6UW2J.js +349 -0
  43. package/dist/chunk-6RZM7RP2.js +520 -0
  44. package/dist/{chunk-4BXMXBJO.js → chunk-75BDCC7K.js} +24 -11
  45. package/dist/{chunk-PZXZJBMP.js → chunk-7CGJBQUA.js} +357 -32
  46. package/dist/{chunk-CJ5EOYZE.js → chunk-7IVF6JLJ.js} +24 -7
  47. package/dist/chunk-7IWCGXYA.js +143 -0
  48. package/dist/chunk-7LM4ASFH.js +172 -0
  49. package/dist/chunk-7MCEJFWV.js +341 -0
  50. package/dist/chunk-7NGMUVNU.js +245 -0
  51. package/dist/chunk-7PBSIXT7.js +355 -0
  52. package/dist/chunk-7QOYGENL.js +443 -0
  53. package/dist/{chunk-H6NIOQHK.js → chunk-A7SWYDE5.js} +66 -15
  54. package/dist/chunk-ADHPJALR.js +3051 -0
  55. package/dist/chunk-ALJYZLNQ.js +509 -0
  56. package/dist/chunk-APCWFOZW.js +28 -0
  57. package/dist/chunk-AQ5FIG74.js +419 -0
  58. package/dist/chunk-AWKQIE5I.js +139 -0
  59. package/dist/chunk-B2MMZZQB.js +426 -0
  60. package/dist/{chunk-ZVFE5QGU.js → chunk-B7JZ3N5G.js} +174 -97
  61. package/dist/chunk-BL37SW6G.js +1314 -0
  62. package/dist/chunk-BTRMA7GC.js +21 -0
  63. package/dist/chunk-C7IUWIUZ.js +643 -0
  64. package/dist/chunk-CA3DUVYD.js +10 -0
  65. package/dist/{chunk-S7F6XLTK.js → chunk-CBCJSO2B.js} +213 -54
  66. package/dist/chunk-CHPX4MFI.js +239 -0
  67. package/dist/chunk-CLGAMIOT.js +648 -0
  68. package/dist/chunk-CUE7VML6.js +1141 -0
  69. package/dist/chunk-CVU6S2E5.js +1587 -0
  70. package/dist/{chunk-AZRX6SAC.js → chunk-CXPQMA6Z.js} +112 -37
  71. package/dist/chunk-D2LN4I7I.js +581 -0
  72. package/dist/{chunk-UWFLYMAR.js → chunk-D34LNBO5.js} +635 -238
  73. package/dist/chunk-D4BCQICM.js +765 -0
  74. package/dist/chunk-EABKIIA4.js +1 -0
  75. package/dist/chunk-EICSYRAG.js +341 -0
  76. package/dist/chunk-EMWAJMAS.js +83 -0
  77. package/dist/chunk-EOLZWRV6.js +149 -0
  78. package/dist/chunk-EOQVTGB6.js +350 -0
  79. package/dist/{chunk-BEDBFJND.js → chunk-ESGUHNB2.js} +119 -43
  80. package/dist/{chunk-Q72LJOVE.js → chunk-F2KNBPKY.js} +74 -18
  81. package/dist/{chunk-O7AE6DAF.js → chunk-G7H3NX3G.js} +57 -24
  82. package/dist/chunk-GM7YIPB7.js +1052 -0
  83. package/dist/chunk-GVQQG435.js +581 -0
  84. package/dist/chunk-HE43OMEL.js +1056 -0
  85. package/dist/chunk-HHOMFQ7R.js +2535 -0
  86. package/dist/chunk-HJFFOOJ4.js +1 -0
  87. package/dist/chunk-HNAKS4Z3.js +207 -0
  88. package/dist/chunk-HP6ST2OW.js +352 -0
  89. package/dist/chunk-HW3OWDTU.js +1 -0
  90. package/dist/{chunk-3ENTMPQY.js → chunk-HZDB44K4.js} +102 -52
  91. package/dist/chunk-I2KLQ2HA.js +19 -0
  92. package/dist/chunk-I6CUP2LW.js +1155 -0
  93. package/dist/chunk-ICV4Y2WY.js +27 -0
  94. package/dist/chunk-IHSIENOE.js +3950 -0
  95. package/dist/{chunk-CUMUNPXY.js → chunk-IMMALLRU.js} +68 -32
  96. package/dist/chunk-J64KGCGX.js +55 -0
  97. package/dist/{chunk-IVNRBPGC.js → chunk-JA6TK7H2.js} +255 -84
  98. package/dist/{chunk-OOPPQH27.js → chunk-JAVZ5JPV.js} +83 -29
  99. package/dist/chunk-JCMTP3E4.js +1251 -0
  100. package/dist/{chunk-U7TFM2JA.js → chunk-JCXFFK64.js} +75 -18
  101. package/dist/chunk-JWCVBFDU.js +236 -0
  102. package/dist/chunk-JXRTD5RI.js +414 -0
  103. package/dist/chunk-JYIUZUIQ.js +1567 -0
  104. package/dist/chunk-K3TK3GIV.js +219 -0
  105. package/dist/chunk-KEVZIHM2.js +1511 -0
  106. package/dist/chunk-KHZDNQQD.js +171 -0
  107. package/dist/chunk-KL4GDV4V.js +131 -0
  108. package/dist/chunk-KNILMM4H.js +225 -0
  109. package/dist/chunk-KRBUZV45.js +25 -0
  110. package/dist/{chunk-ITTYJZWX.js → chunk-KXLDK6HB.js} +161 -45
  111. package/dist/chunk-KZ3X7TSL.js +196 -0
  112. package/dist/chunk-L2WMOA2V.js +474 -0
  113. package/dist/chunk-L4D5LHCH.js +109 -0
  114. package/dist/chunk-LAUJPLDB.js +853 -0
  115. package/dist/{chunk-SBMNWWBV.js → chunk-LGNTP5XA.js} +89 -17
  116. package/dist/chunk-LUZFCCSD.js +271 -0
  117. package/dist/{chunk-HPPW424V.js → chunk-LXJCP4PL.js} +129 -37
  118. package/dist/chunk-MCOZJWPU.js +731 -0
  119. package/dist/chunk-MG4SKWLL.js +2587 -0
  120. package/dist/chunk-MPEPTSER.js +414 -0
  121. package/dist/chunk-MWPJ4YGP.js +1 -0
  122. package/dist/{chunk-TKQYWZ5V.js → chunk-N7AX4OA4.js} +108 -41
  123. package/dist/chunk-NHSLM6SE.js +523 -0
  124. package/dist/chunk-NNCOFLNE.js +24 -0
  125. package/dist/{chunk-J7Q7VCVC.js → chunk-NNJLVA7M.js} +54 -15
  126. package/dist/chunk-NZG75DGA.js +282 -0
  127. package/dist/chunk-O76QXRBV.js +431 -0
  128. package/dist/chunk-OANH27AK.js +223 -0
  129. package/dist/chunk-OCHPK5YV.js +609 -0
  130. package/dist/chunk-OMHVEVX4.js +436 -0
  131. package/dist/{chunk-YF4NSSMT.js → chunk-ONKQUJWD.js} +220 -65
  132. package/dist/chunk-OVTK7A6T.js +615 -0
  133. package/dist/chunk-PCEFCOLN.js +120 -0
  134. package/dist/chunk-PFLNFIVB.js +186 -0
  135. package/dist/chunk-PHSZY37H.js +300 -0
  136. package/dist/chunk-PJLTKDVY.js +18 -0
  137. package/dist/{chunk-4YIP3CWS.js → chunk-PK7BN3MI.js} +89 -19
  138. package/dist/{chunk-KMI5ML5I.js → chunk-PWFRDRGS.js} +155 -29
  139. package/dist/chunk-PYPMD46W.js +707 -0
  140. package/dist/chunk-Q6CCHDI7.js +331 -0
  141. package/dist/chunk-QFA5WS2A.js +750 -0
  142. package/dist/chunk-QJMMM4RC.js +124 -0
  143. package/dist/chunk-QNZII37O.js +10 -0
  144. package/dist/chunk-QYWEVAM6.js +407 -0
  145. package/dist/chunk-R5T4VZ7Z.js +126 -0
  146. package/dist/chunk-R77HFLZD.js +1 -0
  147. package/dist/{chunk-YC6WORFL.js → chunk-RAESDNU5.js} +228 -102
  148. package/dist/chunk-RBYQUXNL.js +1 -0
  149. package/dist/chunk-RCM3DT5E.js +1 -0
  150. package/dist/chunk-RGNY56L7.js +282 -0
  151. package/dist/chunk-RIK6UX2K.js +344 -0
  152. package/dist/{chunk-LAECSR4H.js → chunk-RJA3RXO3.js} +75 -60
  153. package/dist/chunk-RJYRJ3LD.js +1 -0
  154. package/dist/chunk-RMA3NOY4.js +599 -0
  155. package/dist/{chunk-DM5QUKKO.js → chunk-RSWKKAHK.js} +160 -66
  156. package/dist/chunk-RVOIIX3V.js +204 -0
  157. package/dist/chunk-SA2RRBGT.js +1077 -0
  158. package/dist/chunk-SG3J4R45.js +1428 -0
  159. package/dist/chunk-SPUK7JD4.js +238 -0
  160. package/dist/chunk-SWXV2K5N.js +434 -0
  161. package/dist/chunk-SYJEPXP6.js +1303 -0
  162. package/dist/{chunk-N32RGOA5.js → chunk-SZLI34TA.js} +93 -28
  163. package/dist/{chunk-4GBOGOTV.js → chunk-T77WJA74.js} +143 -18
  164. package/dist/chunk-TDWWVJA4.js +630 -0
  165. package/dist/chunk-TFHI5XDR.js +610 -0
  166. package/dist/chunk-TH4PW2WU.js +17 -0
  167. package/dist/chunk-TTQ24HQX.js +12 -0
  168. package/dist/chunk-TUACVJNG.js +12 -0
  169. package/dist/{chunk-CYRBHQQZ.js → chunk-TUL5RUIA.js} +201 -59
  170. package/dist/{chunk-4ZAHCY44.js → chunk-TYOSA7JG.js} +74 -38
  171. package/dist/chunk-TYQTMMEV.js +1 -0
  172. package/dist/chunk-TZO6YDS7.js +346 -0
  173. package/dist/chunk-U3ETF22F.js +328 -0
  174. package/dist/chunk-U6BYHD2N.js +213 -0
  175. package/dist/{chunk-WSW6ZFAQ.js → chunk-UF6EJXPQ.js} +20 -5
  176. package/dist/chunk-UNNQIPGK.js +792 -0
  177. package/dist/chunk-UQEN55EY.js +1 -0
  178. package/dist/chunk-UQVO6AJV.js +171 -0
  179. package/dist/chunk-VFDQAAIW.js +351 -0
  180. package/dist/chunk-VIUE3VQT.js +1 -0
  181. package/dist/chunk-VJLSSSGC.js +438 -0
  182. package/dist/chunk-VLMT6KYT.js +350 -0
  183. package/dist/chunk-VMHGBUGS.js +35 -0
  184. package/dist/{chunk-7O2FMUPT.js → chunk-VQKPBYW6.js} +400 -139
  185. package/dist/{chunk-EJBDRVIH.js → chunk-VSSTWLC5.js} +61 -16
  186. package/dist/chunk-VZYYZRPN.js +1992 -0
  187. package/dist/chunk-W23G6JLF.js +37 -0
  188. package/dist/chunk-WAIJCD2V.js +480 -0
  189. package/dist/chunk-WFMQ3WKM.js +378 -0
  190. package/dist/chunk-WJ2KDRMY.js +66 -0
  191. package/dist/chunk-WKFZJO54.js +437 -0
  192. package/dist/{chunk-SYNOJOQO.js → chunk-WVVD3XOV.js} +189 -93
  193. package/dist/chunk-XAIWMSLB.js +1 -0
  194. package/dist/chunk-XBXUBBJZ.js +98 -0
  195. package/dist/chunk-XCU7MYBJ.js +1 -0
  196. package/dist/chunk-XHE4PGCI.js +717 -0
  197. package/dist/chunk-XRSJ32M3.js +331 -0
  198. package/dist/chunk-XTCVOEAW.js +1 -0
  199. package/dist/chunk-XWGXVQF6.js +58 -0
  200. package/dist/{chunk-35OFI3JG.js → chunk-Y3XKKO5K.js} +258 -123
  201. package/dist/chunk-Y4QNMBLO.js +533 -0
  202. package/dist/chunk-Y5H4CTKO.js +1 -0
  203. package/dist/chunk-YBQIN75A.js +403 -0
  204. package/dist/chunk-YJ5PXOX3.js +158 -0
  205. package/dist/{chunk-AWJOCGFZ.js → chunk-YLRSRUPS.js} +81 -55
  206. package/dist/chunk-YM6MPJ4A.js +1 -0
  207. package/dist/chunk-YV7KZENV.js +200 -0
  208. package/dist/chunk-Z7I4ZSO6.js +316 -0
  209. package/dist/chunk-ZIRMWD2B.js +555 -0
  210. package/dist/chunk-ZPMG3FWU.js +75 -0
  211. package/dist/{chunk-QWCMU5B2.js → chunk-ZTXMK2G7.js} +289 -115
  212. package/dist/chunk-ZVJCWXAL.js +541 -0
  213. package/dist/{chunk-P23EQNRQ.js → chunk-ZYQ23DPT.js} +215 -49
  214. package/dist/coachmark/index.js +10 -3
  215. package/dist/code-block/index.js +6 -3
  216. package/dist/color-field/index.js +15 -5
  217. package/dist/color-picker/index.js +23 -0
  218. package/dist/commerce/index.js +31 -17
  219. package/dist/confirm/index.js +31 -0
  220. package/dist/connection-card/index.js +34 -0
  221. package/dist/connectivity/index.js +6 -2
  222. package/dist/context-menu/index.js +13 -3
  223. package/dist/copy-button/index.js +5 -2
  224. package/dist/data-grid/index.js +35 -17
  225. package/dist/date-range-picker/index.js +22 -9
  226. package/dist/description-list/index.js +6 -1
  227. package/dist/device-frame/index.js +30 -0
  228. package/dist/dialog/index.js +10 -2
  229. package/dist/divider/index.js +2 -0
  230. package/dist/empty-state/index.js +15 -2
  231. package/dist/error-summary/index.js +9 -2
  232. package/dist/fab/index.js +7 -2
  233. package/dist/file-manager/index.js +44 -0
  234. package/dist/file-upload/index.js +16 -7
  235. package/dist/filter-bar/index.js +14 -7
  236. package/dist/flow-run/index.js +23 -13
  237. package/dist/form/index.js +32 -3
  238. package/dist/gallery/index.js +8 -2
  239. package/dist/hold-to-confirm/index.js +6 -2
  240. package/dist/hover-card/index.js +18 -0
  241. package/dist/icon-tile/index.js +10 -0
  242. package/dist/image/index.js +9 -0
  243. package/dist/index.d.ts +30789 -12332
  244. package/dist/index.js +424 -135
  245. package/dist/infinite-list/index.js +6 -2
  246. package/dist/inline-edit/index.js +8 -5
  247. package/dist/input/index.js +7 -4
  248. package/dist/interactions/index.js +5 -1
  249. package/dist/invoice/index.js +22 -9
  250. package/dist/job-row/index.js +22 -0
  251. package/dist/json-inspector/index.js +20 -0
  252. package/dist/kbd/index.js +5 -1
  253. package/dist/keyboard/index.js +9 -2
  254. package/dist/level-meter/index.js +9 -0
  255. package/dist/list-row/index.js +14 -4
  256. package/dist/log-viewer/index.js +11 -2
  257. package/dist/map-view/index.js +16 -3
  258. package/dist/markdown/index.js +12 -6
  259. package/dist/metric/index.js +10 -4
  260. package/dist/metric-strip/index.js +12 -0
  261. package/dist/money/index.js +16 -3
  262. package/dist/nav-drawer/index.js +8 -2
  263. package/dist/nav-header/index.js +15 -0
  264. package/dist/navigation/index.js +32 -2
  265. package/dist/notification-center/index.js +28 -12
  266. package/dist/number-roll/index.js +7 -2
  267. package/dist/onboarding-pager/index.js +22 -0
  268. package/dist/one-handed/index.js +5 -3
  269. package/dist/os-surfaces/index.js +9 -3
  270. package/dist/otp/index.js +9 -5
  271. package/dist/page-header/index.js +3 -1
  272. package/dist/pagination/index.js +8 -0
  273. package/dist/payment-method/index.js +21 -11
  274. package/dist/payment-status/index.js +26 -15
  275. package/dist/permission/index.js +21 -2
  276. package/dist/picker/index.js +22 -6
  277. package/dist/progress/index.js +11 -3
  278. package/dist/provenance/index.js +16 -0
  279. package/dist/pull-to-refresh/index.js +4 -2
  280. package/dist/qr-code/index.js +16 -0
  281. package/dist/query-builder/index.js +30 -0
  282. package/dist/radio-group/index.js +9 -5
  283. package/dist/rating/index.js +10 -2
  284. package/dist/receivables/index.js +35 -17
  285. package/dist/recording-indicator/index.js +21 -0
  286. package/dist/refund/index.js +28 -15
  287. package/dist/repeatable-rows/index.js +19 -0
  288. package/dist/save-status/index.js +7 -3
  289. package/dist/screen/index.js +3 -0
  290. package/dist/scroll-area/index.js +3 -1
  291. package/dist/search-field/index.js +13 -0
  292. package/dist/secret-field/index.js +19 -0
  293. package/dist/section-header/index.js +4 -0
  294. package/dist/segmented-control/index.js +4 -3
  295. package/dist/sheet/index.js +11 -3
  296. package/dist/shortcuts-sheet/index.js +2 -0
  297. package/dist/sign-in-screen/index.js +25 -0
  298. package/dist/skeleton/index.js +5 -1
  299. package/dist/slider/index.js +5 -2
  300. package/dist/sortable/index.js +8 -0
  301. package/dist/spinner/index.js +4 -1
  302. package/dist/split-button/index.js +21 -6
  303. package/dist/spotlight/index.js +9 -1
  304. package/dist/stack/index.js +2 -0
  305. package/dist/stage-timeline/index.js +8 -3
  306. package/dist/status-dot/index.js +8 -2
  307. package/dist/stepper/index.js +11 -4
  308. package/dist/streaming-text/index.js +4 -2
  309. package/dist/survey/index.js +29 -16
  310. package/dist/switch/index.js +9 -3
  311. package/dist/system-state/index.js +15 -4
  312. package/dist/tab-bar/index.js +13 -2
  313. package/dist/tabs/index.js +12 -2
  314. package/dist/tags-input/index.js +13 -0
  315. package/dist/text/index.js +4 -0
  316. package/dist/textarea/index.js +8 -5
  317. package/dist/thinking/index.js +6 -1
  318. package/dist/tile-rail/index.js +10 -0
  319. package/dist/time-field/index.js +20 -0
  320. package/dist/time-range-control/index.js +36 -0
  321. package/dist/timeline/index.js +4 -2
  322. package/dist/toast/index.js +6 -2
  323. package/dist/toolbar/index.js +5 -2
  324. package/dist/tour/index.js +15 -10
  325. package/dist/transcript/index.js +28 -0
  326. package/dist/truncation-notice/index.js +5 -2
  327. package/dist/update-notice/index.js +19 -9
  328. package/dist/video-player/index.js +29 -2
  329. package/dist/viewfinder/index.js +15 -5
  330. package/dist/widget/index.js +14 -4
  331. package/dist/wizard/index.js +10 -4
  332. package/package.json +13 -12
  333. package/dist/chunk-223Q2T2Q.js +0 -229
  334. package/dist/chunk-2A5NIQAK.js +0 -254
  335. package/dist/chunk-2GK6PHGE.js +0 -363
  336. package/dist/chunk-2ZZ7TDJ4.js +0 -324
  337. package/dist/chunk-3ARE4TES.js +0 -195
  338. package/dist/chunk-3NMD74ZU.js +0 -4
  339. package/dist/chunk-3WPW4KUN.js +0 -182
  340. package/dist/chunk-423B7SPN.js +0 -993
  341. package/dist/chunk-47FWHGUN.js +0 -394
  342. package/dist/chunk-4DS5ZWVC.js +0 -83
  343. package/dist/chunk-4SZYY6AN.js +0 -99
  344. package/dist/chunk-4YQOR7JM.js +0 -204
  345. package/dist/chunk-52X2VYTD.js +0 -228
  346. package/dist/chunk-5YNTNN5A.js +0 -177
  347. package/dist/chunk-6HT2LP62.js +0 -504
  348. package/dist/chunk-6N33LFQA.js +0 -35
  349. package/dist/chunk-6X6PQ443.js +0 -432
  350. package/dist/chunk-7CFF4HXS.js +0 -126
  351. package/dist/chunk-AI4DWZCD.js +0 -162
  352. package/dist/chunk-BTTFCMKG.js +0 -166
  353. package/dist/chunk-BV3B2HYZ.js +0 -1635
  354. package/dist/chunk-C2NTXVWM.js +0 -98
  355. package/dist/chunk-CDRZHT42.js +0 -424
  356. package/dist/chunk-DHWADYZX.js +0 -144
  357. package/dist/chunk-F5XNPWS7.js +0 -1024
  358. package/dist/chunk-FMYDDECK.js +0 -1521
  359. package/dist/chunk-GDKZTW34.js +0 -395
  360. package/dist/chunk-GL7B2DOW.js +0 -134
  361. package/dist/chunk-GNNJ4GCC.js +0 -471
  362. package/dist/chunk-HET4LLMX.js +0 -129
  363. package/dist/chunk-HZ6CNMAF.js +0 -870
  364. package/dist/chunk-IIQTAY3J.js +0 -715
  365. package/dist/chunk-JNH2TYIN.js +0 -96
  366. package/dist/chunk-JNY4ZHAR.js +0 -634
  367. package/dist/chunk-JXJB2X6M.js +0 -131
  368. package/dist/chunk-LRJNDEIA.js +0 -302
  369. package/dist/chunk-LSS54GLJ.js +0 -116
  370. package/dist/chunk-LZLHELAG.js +0 -137
  371. package/dist/chunk-MOUJOP55.js +0 -425
  372. package/dist/chunk-NKB7BZYK.js +0 -167
  373. package/dist/chunk-NQYBUO3K.js +0 -1795
  374. package/dist/chunk-O4AEHWII.js +0 -464
  375. package/dist/chunk-OETCUXQP.js +0 -134
  376. package/dist/chunk-OPXFZ4Y5.js +0 -204
  377. package/dist/chunk-PJXUJYS6.js +0 -248
  378. package/dist/chunk-PUPM2YGF.js +0 -376
  379. package/dist/chunk-QCDXZBC5.js +0 -247
  380. package/dist/chunk-QDYDBCFP.js +0 -197
  381. package/dist/chunk-QJJ6MADV.js +0 -274
  382. package/dist/chunk-QKXCPTFS.js +0 -349
  383. package/dist/chunk-RIBDXGUG.js +0 -108
  384. package/dist/chunk-RJQOOHT2.js +0 -214
  385. package/dist/chunk-RNGLIHFA.js +0 -191
  386. package/dist/chunk-RQ3HASCC.js +0 -6
  387. package/dist/chunk-RSOJT5YW.js +0 -124
  388. package/dist/chunk-RUZHTGKB.js +0 -237
  389. package/dist/chunk-RW6ZL2FQ.js +0 -284
  390. package/dist/chunk-TKVFVF5D.js +0 -95
  391. package/dist/chunk-TOXAGRDQ.js +0 -144
  392. package/dist/chunk-TUTI5HOZ.js +0 -112
  393. package/dist/chunk-UC2WGUP3.js +0 -627
  394. package/dist/chunk-UYG5L34B.js +0 -87
  395. package/dist/chunk-VBOXAEPI.js +0 -336
  396. package/dist/chunk-VCDBXW5H.js +0 -188
  397. package/dist/chunk-VEAYTRPX.js +0 -414
  398. package/dist/chunk-VQHPQEUH.js +0 -273
  399. package/dist/chunk-VXDZFJGP.js +0 -874
  400. package/dist/chunk-XNUVB5OL.js +0 -375
  401. package/dist/chunk-XOSCY2CW.js +0 -242
  402. package/dist/chunk-XXXEFXY5.js +0 -99
  403. package/dist/chunk-YDGVJETP.js +0 -60
  404. package/dist/chunk-YG3ZJHGU.js +0 -223
  405. package/dist/chunk-YTFKPRUK.js +0 -845
  406. package/dist/chunk-Z7H7VSFZ.js +0 -323
  407. package/dist/header/index.js +0 -5
  408. package/dist/search-bar/index.js +0 -5
  409. /package/dist/{chunk-3ECPOSKO.js → chunk-3BKLBYPK.js} +0 -0
  410. /package/dist/{chunk-JRLTGLN4.js → chunk-3UG6JUCV.js} +0 -0
  411. /package/dist/{chunk-RTIKSY6A.js → chunk-4QCR3K2J.js} +0 -0
  412. /package/dist/{chunk-VFCUIDRT.js → chunk-5WWRTEPS.js} +0 -0
@@ -0,0 +1,1303 @@
1
+ import { MetricDelta } from './chunk-N7AX4OA4.js';
2
+ import { EmptyState } from './chunk-QJMMM4RC.js';
3
+ import { Button } from './chunk-5DTKORLI.js';
4
+ import { resolveTextRole } from './chunk-L4D5LHCH.js';
5
+ import { NumberRoll } from './chunk-IMMALLRU.js';
6
+ import { Skeleton } from './chunk-YJ5PXOX3.js';
7
+ import { haptics } from './chunk-NY2U3PBI.js';
8
+ import { isAndroidIdiom } from './chunk-TH4PW2WU.js';
9
+ import { useLabels, useLoamLocale } from './chunk-APCWFOZW.js';
10
+ import { Icon } from './chunk-PCEFCOLN.js';
11
+ import { useResolvedMotion } from './chunk-J64KGCGX.js';
12
+ import * as React from 'react';
13
+ import { View, Animated, Text, Pressable, Easing } from 'react-native';
14
+ import { Svg, Path, Polyline, Circle, Line, Rect } from 'react-native-svg';
15
+ import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
16
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
17
+
18
+ // src/charts/charts-labels.ts
19
+ var DEFAULT_CHARTS_LABELS = {
20
+ emptyTitle: "No data",
21
+ emptyMessage: "There is nothing to show for this range.",
22
+ errorTitle: "Could not load this chart",
23
+ errorMessage: "The data could not be loaded.",
24
+ retry: "Retry",
25
+ loading: "Loading chart",
26
+ other: "Other",
27
+ lineChart: "Line chart",
28
+ barChart: "Bar chart",
29
+ donutChart: "DonutChart chart",
30
+ stackedBarChart: "Stacked bar chart",
31
+ noData: (kind) => kind + ", no data",
32
+ pointCount: (n) => n + " " + (n === 1 ? "point" : "points"),
33
+ span: (first, end) => first + " to " + end,
34
+ seriesSummary: (kind, span, points, min, max, last) => kind + (span ? ", " + span : "") + ", " + points + ", " + min + " to " + max + ", last " + last,
35
+ donutSummary: (kind, slices) => kind + ": " + slices,
36
+ donutSlice: (label, pct) => label + " " + pct + "%",
37
+ stackedSummary: (kind, names, columns) => kind + " of " + names + " across " + columns + " columns",
38
+ splitBar: "Split bar",
39
+ rankedBars: "Ranked bars",
40
+ free: "Free",
41
+ splitEmpty: "No data yet",
42
+ percent: (pct) => pct + " percent"
43
+ };
44
+ function ChartFrame({
45
+ state = "data",
46
+ width,
47
+ height,
48
+ compact = false,
49
+ icon,
50
+ tone,
51
+ variant = "plain",
52
+ motion,
53
+ emptyTitle: emptyTitleProp,
54
+ emptyMessage: emptyMessageProp,
55
+ errorTitle: errorTitleProp,
56
+ errorMessage: errorMessageProp,
57
+ retryLabel: retryLabelProp,
58
+ loadingLabel: loadingLabelProp,
59
+ labels: labelsProp,
60
+ onRetry
61
+ }) {
62
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
63
+ const emptyTitle = emptyTitleProp ?? labels.emptyTitle;
64
+ const emptyMessage = emptyMessageProp ?? labels.emptyMessage;
65
+ const errorTitle = errorTitleProp ?? labels.errorTitle;
66
+ const errorMessage = errorMessageProp ?? labels.errorMessage;
67
+ const retryLabel = retryLabelProp ?? labels.retry;
68
+ const loadingLabel = loadingLabelProp ?? labels.loading;
69
+ const theme = useLoamTheme("charts");
70
+ const { styles } = useStyles(frameSheet);
71
+ if (state === "data") return null;
72
+ const box = {
73
+ minWidth: width,
74
+ minHeight: height,
75
+ ...variant !== "plain" ? {
76
+ borderWidth: theme.borderWidth.thin,
77
+ borderColor: theme.color.border,
78
+ borderRadius: theme.radius.md,
79
+ ...variant === "filled" ? { backgroundColor: theme.color.surface } : null
80
+ } : null
81
+ };
82
+ if (state === "loading") {
83
+ return /* @__PURE__ */ jsx(
84
+ Skeleton,
85
+ {
86
+ variant: "rect",
87
+ width,
88
+ height: height ?? 120,
89
+ accessibilityLabel: loadingLabel,
90
+ motion,
91
+ style: box
92
+ }
93
+ );
94
+ }
95
+ if (!compact) {
96
+ const error = state === "error";
97
+ return /* @__PURE__ */ jsx(View, { style: box, children: /* @__PURE__ */ jsx(
98
+ EmptyState,
99
+ {
100
+ variant: error || tone === "danger" ? "error" : "empty",
101
+ icon: icon ?? (error ? "alert-triangle" : "chart-bar"),
102
+ title: error ? errorTitle : emptyTitle,
103
+ description: error ? errorMessage : emptyMessage,
104
+ actionLabel: error && onRetry ? retryLabel : void 0,
105
+ onAction: error ? onRetry : void 0
106
+ }
107
+ ) });
108
+ }
109
+ if (state === "empty") {
110
+ return /* @__PURE__ */ jsx(
111
+ View,
112
+ {
113
+ accessibilityRole: "image",
114
+ accessibilityLabel: `${emptyTitle}. ${emptyMessage}`,
115
+ style: [styles.center, box],
116
+ children: /* @__PURE__ */ jsx(
117
+ Icon,
118
+ {
119
+ name: icon ?? "chart-bar",
120
+ size: 18,
121
+ color: tone ? toneColors(theme, tone).main : theme.color.text3
122
+ }
123
+ )
124
+ }
125
+ );
126
+ }
127
+ return /* @__PURE__ */ jsxs(View, { style: [styles.centerRow, box], children: [
128
+ /* @__PURE__ */ jsx(Icon, { name: icon ?? "alert-triangle", size: 18, color: theme.color.danger }),
129
+ /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onPress: onRetry, accessibilityLabel: retryLabel, children: retryLabel })
130
+ ] });
131
+ }
132
+ var frameSheet = createStyleSheet((theme) => ({
133
+ center: {
134
+ alignItems: "center",
135
+ justifyContent: "center",
136
+ gap: theme.space.s2,
137
+ padding: theme.space.s4
138
+ },
139
+ centerRow: {
140
+ flexDirection: "row",
141
+ alignItems: "center",
142
+ justifyContent: "center",
143
+ gap: theme.space.s2,
144
+ padding: theme.space.s2
145
+ }
146
+ }));
147
+ function chartHue(theme, index) {
148
+ const palette = [
149
+ theme.chart.c1,
150
+ theme.chart.c2,
151
+ theme.chart.c3,
152
+ theme.chart.c4,
153
+ theme.chart.c5,
154
+ theme.chart.c6
155
+ ];
156
+ return palette[((Math.round(index) - 1) % 6 + 6) % 6];
157
+ }
158
+ function chartEdgeHue(theme, index) {
159
+ return theme.chart.edge[((Math.round(index) - 1) % 6 + 6) % 6];
160
+ }
161
+ function toneColors(theme, tone) {
162
+ switch (tone) {
163
+ case "good":
164
+ return { main: theme.color.good, soft: theme.color.goodSoft };
165
+ case "warn":
166
+ return { main: theme.color.warn, soft: theme.color.warnSoft };
167
+ case "danger":
168
+ return { main: theme.color.danger, soft: theme.color.dangerSoft };
169
+ default:
170
+ return { main: theme.color.accentStrong, soft: theme.color.accentSoft };
171
+ }
172
+ }
173
+ function toneStep(theme, i) {
174
+ const steps = [
175
+ theme.opacity[100],
176
+ theme.opacity[72],
177
+ theme.opacity[56],
178
+ theme.opacity[48],
179
+ theme.opacity[38],
180
+ theme.opacity[32]
181
+ ];
182
+ return steps[Math.min(Math.max(0, Math.round(i)), steps.length - 1)];
183
+ }
184
+ function useToneColors(tone) {
185
+ return toneColors(useLoamTheme("charts"), tone);
186
+ }
187
+ function clamp(n, lo, hi) {
188
+ return Math.max(lo, Math.min(hi, n));
189
+ }
190
+ function useDrawIn(motion, animate) {
191
+ const resolved = useResolvedMotion(motion ?? (animate ? "full" : "none"), "charts");
192
+ const on = resolved !== "none";
193
+ const theme = useLoamTheme("charts");
194
+ const opacity = React.useRef(new Animated.Value(on ? 0 : 1)).current;
195
+ React.useEffect(() => {
196
+ if (!on) return;
197
+ const anim = Animated.timing(opacity, {
198
+ toValue: 1,
199
+ duration: theme.motion.enter.duration,
200
+ easing: Easing.bezier(...theme.motion.enter.easing),
201
+ useNativeDriver: true
202
+ });
203
+ anim.start();
204
+ return () => anim.stop();
205
+ }, [on, opacity, theme.motion.enter]);
206
+ return opacity;
207
+ }
208
+ function Sparkline({
209
+ labels: labelsProp,
210
+ data,
211
+ width = 120,
212
+ height = 32,
213
+ tone = "accent",
214
+ strokeWidth = 2,
215
+ showArea = false,
216
+ showDot = false,
217
+ motion,
218
+ animate = false,
219
+ state = "data",
220
+ emptyTitle,
221
+ emptyMessage,
222
+ errorTitle,
223
+ errorMessage,
224
+ retryLabel,
225
+ loadingLabel,
226
+ onRetry,
227
+ accessibilityLabel: labelProp
228
+ }) {
229
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
230
+ const { main, soft } = useToneColors(tone);
231
+ const opacity = useDrawIn(motion, animate);
232
+ const dotR = strokeWidth + 1.5;
233
+ const accessibilityLabel = labelProp ?? summarizeSeries(labels.lineChart, data, void 0, labels);
234
+ const pad = Math.max(strokeWidth, showDot ? dotR : 0);
235
+ const innerW = Math.max(0, width - pad * 2);
236
+ const innerH = Math.max(0, height - pad * 2);
237
+ const n = data.length;
238
+ const min = n > 0 ? Math.min(...data) : 0;
239
+ const max = n > 0 ? Math.max(...data) : 0;
240
+ const range = max - min || 1;
241
+ const stepX = n > 1 ? innerW / (n - 1) : 0;
242
+ const px = (i) => pad + i * stepX;
243
+ const py = (v) => pad + (1 - (v - min) / range) * innerH;
244
+ const points = data.map((v, i) => `${px(i)},${py(v)}`).join(" ");
245
+ const lastX = px(n - 1);
246
+ const lastY = n > 0 ? py(data[n - 1]) : 0;
247
+ const areaPath = n > 1 ? `M ${points.replace(/ /g, " L ")} L ${lastX},${height} L ${px(0)},${height} Z` : "";
248
+ if (state !== "data") {
249
+ return /* @__PURE__ */ jsx(
250
+ ChartFrame,
251
+ {
252
+ labels,
253
+ compact: true,
254
+ state,
255
+ width,
256
+ height,
257
+ emptyTitle,
258
+ emptyMessage,
259
+ errorTitle,
260
+ errorMessage,
261
+ retryLabel,
262
+ loadingLabel,
263
+ onRetry
264
+ }
265
+ );
266
+ }
267
+ return /* @__PURE__ */ jsx(
268
+ Animated.View,
269
+ {
270
+ accessibilityRole: "image",
271
+ accessibilityLabel,
272
+ style: { width, height, opacity },
273
+ children: /* @__PURE__ */ jsxs(Svg, { width, height, viewBox: `0 0 ${width} ${height}`, fill: "none", children: [
274
+ showArea && areaPath ? /* @__PURE__ */ jsx(Path, { d: areaPath, fill: soft }) : null,
275
+ n > 1 ? /* @__PURE__ */ jsx(
276
+ Polyline,
277
+ {
278
+ points,
279
+ fill: "none",
280
+ stroke: main,
281
+ strokeWidth,
282
+ strokeLinecap: "round",
283
+ strokeLinejoin: "round"
284
+ }
285
+ ) : null,
286
+ showDot && n > 0 ? /* @__PURE__ */ jsx(Circle, { cx: lastX, cy: lastY, r: dotR, fill: main }) : null
287
+ ] })
288
+ }
289
+ );
290
+ }
291
+ function spoken(n) {
292
+ return new Intl.NumberFormat("en", { notation: "compact", maximumFractionDigits: 1 }).format(n);
293
+ }
294
+ function summarizeSeries(kind, values, labels, copy = DEFAULT_CHARTS_LABELS) {
295
+ if (values.length === 0) return copy.noData(kind);
296
+ const min = Math.min(...values);
297
+ const max = Math.max(...values);
298
+ const last = values[values.length - 1];
299
+ const first = labels?.[0];
300
+ const end = labels?.[values.length - 1];
301
+ const span = first && end ? copy.span(first, end) : "";
302
+ return copy.seriesSummary(
303
+ kind,
304
+ span,
305
+ copy.pointCount(values.length),
306
+ spoken(min),
307
+ spoken(max),
308
+ spoken(last)
309
+ );
310
+ }
311
+ function normalizeBars(data) {
312
+ return data.map((d) => typeof d === "number" ? { value: d } : d);
313
+ }
314
+ function topRoundedBar(x, y, w, h, r) {
315
+ const rr = Math.max(0, Math.min(r, w / 2, h));
316
+ if (rr <= 0) return `M ${x},${y} h ${w} v ${h} h ${-w} Z`;
317
+ return `M ${x},${y + h} L ${x},${y + rr} Q ${x},${y} ${x + rr},${y} L ${x + w - rr},${y} Q ${x + w},${y} ${x + w},${y + rr} L ${x + w},${y + h} Z`;
318
+ }
319
+ function BarChart({
320
+ labels: labelsProp,
321
+ data,
322
+ width = 140,
323
+ height = 150,
324
+ tone = "accent",
325
+ gap = 8,
326
+ barRadius = 4,
327
+ highlightLast = true,
328
+ highlightIndex,
329
+ colors,
330
+ motion,
331
+ animate = false,
332
+ state = "data",
333
+ emptyTitle,
334
+ emptyMessage,
335
+ errorTitle,
336
+ errorMessage,
337
+ retryLabel,
338
+ loadingLabel,
339
+ onRetry,
340
+ accessibilityLabel: labelProp
341
+ }) {
342
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
343
+ const theme = useLoamTheme("charts");
344
+ const { main, soft } = useToneColors(tone);
345
+ const opacity = useDrawIn(motion, animate);
346
+ const bars = normalizeBars(data);
347
+ const accessibilityLabel = labelProp ?? summarizeSeries(
348
+ labels.barChart,
349
+ bars.map((b) => b.value),
350
+ bars.map((b) => b.label),
351
+ labels
352
+ );
353
+ const n = bars.length;
354
+ const values = bars.map((b) => b.value);
355
+ const max = n > 0 ? Math.max(...values, 0) : 0;
356
+ const barW = n > 0 ? Math.max(0, (width - gap * (n - 1)) / n) : 0;
357
+ const fillFor = (i) => {
358
+ if (colors && colors.length > 0) {
359
+ const c = colors[i % colors.length];
360
+ return typeof c === "number" ? chartHue(theme, c) : toneColors(theme, c).main;
361
+ }
362
+ if (highlightIndex !== void 0) {
363
+ return i === highlightIndex ? theme.chart.c1 : theme.chart.c2;
364
+ }
365
+ return highlightLast ? i === n - 1 ? main : soft : main;
366
+ };
367
+ if (state !== "data") {
368
+ return /* @__PURE__ */ jsx(
369
+ ChartFrame,
370
+ {
371
+ labels,
372
+ state,
373
+ width,
374
+ height,
375
+ emptyTitle,
376
+ emptyMessage,
377
+ errorTitle,
378
+ errorMessage,
379
+ retryLabel,
380
+ loadingLabel,
381
+ onRetry
382
+ }
383
+ );
384
+ }
385
+ return /* @__PURE__ */ jsx(
386
+ Animated.View,
387
+ {
388
+ accessibilityRole: "image",
389
+ accessibilityLabel,
390
+ style: { width, height, opacity },
391
+ children: /* @__PURE__ */ jsx(Svg, { width, height, viewBox: `0 0 ${width} ${height}`, fill: "none", children: bars.map((b, i) => {
392
+ const h = max > 0 ? clamp(b.value / max, 0, 1) * height : 0;
393
+ const x = i * (barW + gap);
394
+ const y = height - h;
395
+ return /* @__PURE__ */ jsx(
396
+ Path,
397
+ {
398
+ d: topRoundedBar(x, y, barW, h, Math.min(barRadius, barW / 4)),
399
+ fill: fillFor(i)
400
+ },
401
+ i
402
+ );
403
+ }) })
404
+ }
405
+ );
406
+ }
407
+ function RingChart({
408
+ labels: labelsProp,
409
+ value,
410
+ max = 100,
411
+ diameter: size = 92,
412
+ thickness = 8,
413
+ tone = "accent",
414
+ label = false,
415
+ motion,
416
+ animate = false,
417
+ state = "data",
418
+ accessibilityLabel
419
+ }) {
420
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
421
+ const theme = useLoamTheme("charts");
422
+ const { main } = useToneColors(tone);
423
+ const opacity = useDrawIn(motion, animate);
424
+ if (state !== "data") {
425
+ return /* @__PURE__ */ jsx(ChartFrame, { labels, state, width: size, height: size, compact: true });
426
+ }
427
+ const fraction = max > 0 ? clamp(value / max, 0, 1) : 0;
428
+ const now = Math.round(fraction * 100);
429
+ const center = size / 2;
430
+ const radius = (size - thickness) / 2;
431
+ const circumference = 2 * Math.PI * radius;
432
+ const dashOffset = circumference * (1 - fraction);
433
+ const labelText = label === true ? `${now}%` : typeof label === "string" ? label : null;
434
+ const labelSize = Math.max(theme.fontSize[14], Math.round(size * 0.2));
435
+ return /* @__PURE__ */ jsxs(
436
+ Animated.View,
437
+ {
438
+ accessibilityRole: "progressbar",
439
+ accessibilityLabel,
440
+ accessibilityValue: { min: 0, max, now: Math.round(fraction * max) },
441
+ "aria-valuemin": 0,
442
+ "aria-valuemax": max,
443
+ "aria-valuenow": Math.round(fraction * max),
444
+ style: { width: size, height: size, alignItems: "center", justifyContent: "center", opacity },
445
+ children: [
446
+ /* @__PURE__ */ jsxs(
447
+ Svg,
448
+ {
449
+ width: size,
450
+ height: size,
451
+ viewBox: `0 0 ${size} ${size}`,
452
+ fill: "none",
453
+ style: ringSvgStyle,
454
+ children: [
455
+ /* @__PURE__ */ jsx(
456
+ Circle,
457
+ {
458
+ cx: center,
459
+ cy: center,
460
+ r: radius,
461
+ stroke: theme.color.surface3,
462
+ strokeWidth: thickness,
463
+ fill: "none"
464
+ }
465
+ ),
466
+ /* @__PURE__ */ jsx(
467
+ Circle,
468
+ {
469
+ cx: center,
470
+ cy: center,
471
+ r: radius,
472
+ stroke: main,
473
+ strokeWidth: thickness,
474
+ strokeLinecap: "round",
475
+ fill: "none",
476
+ strokeDasharray: `${circumference} ${circumference}`,
477
+ strokeDashoffset: dashOffset,
478
+ transform: `rotate(-90 ${center} ${center})`
479
+ }
480
+ )
481
+ ]
482
+ }
483
+ ),
484
+ labelText !== null ? /* @__PURE__ */ jsx(
485
+ Text,
486
+ {
487
+ style: {
488
+ position: "absolute",
489
+ fontFamily: theme.font.sans,
490
+ fontWeight: theme.fontWeight.bold,
491
+ fontSize: labelSize,
492
+ color: theme.color.text
493
+ },
494
+ children: labelText
495
+ }
496
+ ) : null
497
+ ]
498
+ }
499
+ );
500
+ }
501
+ var ringSvgStyle = { position: "absolute" };
502
+ function foldDonutSlices(data, max, other) {
503
+ if (max <= 0 || data.length <= max) return data;
504
+ const keep = new Set(
505
+ data.map((d, i) => ({ v: d.value, i })).sort((a, b) => b.v - a.v).slice(0, max - 1).map((x) => x.i)
506
+ );
507
+ const rest = data.filter((_, i) => !keep.has(i)).reduce((a, d) => a + d.value, 0);
508
+ return [...data.filter((_, i) => keep.has(i)), { label: other, value: rest }];
509
+ }
510
+ function DonutChart({
511
+ labels: labelsProp,
512
+ data: rawData,
513
+ maxSlices = 5,
514
+ otherLabel: otherLabelProp,
515
+ diameter: size = 140,
516
+ thickness = 18,
517
+ showLegend = true,
518
+ centerLabel,
519
+ motion,
520
+ animate = false,
521
+ state = "data",
522
+ emptyTitle,
523
+ emptyMessage,
524
+ errorTitle,
525
+ errorMessage,
526
+ retryLabel,
527
+ loadingLabel,
528
+ onRetry,
529
+ accessibilityLabel: labelProp,
530
+ tone
531
+ }) {
532
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
533
+ const data = foldDonutSlices(rawData, maxSlices, otherLabelProp ?? labels.other);
534
+ const donutTotal = data.reduce((a, d) => a + d.value, 0);
535
+ const accessibilityLabel = labelProp ?? (data.length && donutTotal > 0 ? labels.donutSummary(
536
+ labels.donutChart,
537
+ data.map((d) => labels.donutSlice(d.label, Math.round(d.value / donutTotal * 100))).join(", ")
538
+ ) : labels.noData(labels.donutChart));
539
+ const theme = useLoamTheme("charts");
540
+ const { styles } = useStyles(donutSheet);
541
+ const opacity = useDrawIn(motion, animate);
542
+ if (state !== "data") {
543
+ return /* @__PURE__ */ jsx(
544
+ ChartFrame,
545
+ {
546
+ labels,
547
+ state,
548
+ width: size,
549
+ height: size,
550
+ emptyTitle,
551
+ emptyMessage,
552
+ errorTitle,
553
+ errorMessage,
554
+ retryLabel,
555
+ loadingLabel,
556
+ onRetry
557
+ }
558
+ );
559
+ }
560
+ const palette = [
561
+ theme.chart.c1,
562
+ theme.chart.c2,
563
+ theme.chart.c3,
564
+ theme.chart.c4,
565
+ theme.chart.c5,
566
+ theme.chart.c6
567
+ ];
568
+ const colorAt = (i) => tone ? toneColors(theme, tone).main : palette[i % palette.length];
569
+ const center = size / 2;
570
+ const radius = (size - thickness) / 2;
571
+ const circumference = 2 * Math.PI * radius;
572
+ const total = data.reduce((sum, d) => sum + Math.max(0, d.value), 0);
573
+ const fractionOf = (v) => total > 0 ? Math.max(0, v) / total : 0;
574
+ let acc = 0;
575
+ const segments = data.map((d, i) => {
576
+ const fraction = fractionOf(d.value);
577
+ const start = acc;
578
+ acc += fraction;
579
+ return { i, fraction, start, color: colorAt(i), pct: Math.round(fraction * 100) };
580
+ });
581
+ const centerContent = centerLabel ?? String(Math.round(total));
582
+ const seam = segments.length > 1 ? 2 : 0;
583
+ return /* @__PURE__ */ jsxs(
584
+ View,
585
+ {
586
+ accessibilityRole: "image",
587
+ accessibilityLabel,
588
+ style: showLegend ? styles.container : void 0,
589
+ children: [
590
+ /* @__PURE__ */ jsxs(
591
+ Animated.View,
592
+ {
593
+ style: {
594
+ width: size,
595
+ height: size,
596
+ alignItems: "center",
597
+ justifyContent: "center",
598
+ opacity
599
+ },
600
+ children: [
601
+ /* @__PURE__ */ jsxs(
602
+ Svg,
603
+ {
604
+ width: size,
605
+ height: size,
606
+ viewBox: `0 0 ${size} ${size}`,
607
+ fill: "none",
608
+ style: ringSvgStyle,
609
+ children: [
610
+ /* @__PURE__ */ jsx(
611
+ Circle,
612
+ {
613
+ cx: center,
614
+ cy: center,
615
+ r: radius,
616
+ stroke: theme.chart.grid,
617
+ strokeWidth: thickness,
618
+ fill: "none"
619
+ }
620
+ ),
621
+ segments.map((s) => /* @__PURE__ */ jsx(
622
+ Circle,
623
+ {
624
+ cx: center,
625
+ cy: center,
626
+ r: radius,
627
+ stroke: s.color,
628
+ ...tone ? { strokeOpacity: toneStep(theme, s.i) } : null,
629
+ strokeWidth: thickness,
630
+ fill: "none",
631
+ strokeDasharray: `${Math.max(0, s.fraction * circumference - seam)} ${circumference - Math.max(0, s.fraction * circumference - seam)}`,
632
+ strokeDashoffset: -s.start * circumference,
633
+ transform: `rotate(-90 ${center} ${center})`
634
+ },
635
+ s.i
636
+ ))
637
+ ]
638
+ }
639
+ ),
640
+ typeof centerContent === "string" || typeof centerContent === "number" ? (
641
+ // The Metric value: sans 700 tabular, 20 on the donut (R18).
642
+ /* @__PURE__ */ jsx(Text, { style: styles.centre, children: centerContent })
643
+ ) : centerContent
644
+ ]
645
+ }
646
+ ),
647
+ showLegend ? /* @__PURE__ */ jsx(View, { style: styles.legend, children: segments.map((s) => /* @__PURE__ */ jsxs(View, { style: styles.legendRow, children: [
648
+ /* @__PURE__ */ jsx(
649
+ View,
650
+ {
651
+ style: [
652
+ styles.chip,
653
+ { backgroundColor: s.color, borderColor: chartEdgeHue(theme, s.i + 1) },
654
+ tone ? { borderColor: s.color, opacity: toneStep(theme, s.i) } : null
655
+ ]
656
+ }
657
+ ),
658
+ /* @__PURE__ */ jsx(Text, { style: styles.legendLabel, children: data[s.i].label }),
659
+ /* @__PURE__ */ jsxs(Text, { style: styles.legendPct, children: [
660
+ s.pct,
661
+ "%"
662
+ ] })
663
+ ] }, s.i)) }) : null
664
+ ]
665
+ }
666
+ );
667
+ }
668
+ var donutSheet = createStyleSheet((theme) => ({
669
+ container: { flexDirection: "row", alignItems: "center", gap: theme.space.s5 },
670
+ legend: { flexShrink: 1, gap: theme.space.s2 },
671
+ legendRow: {
672
+ flexDirection: "row",
673
+ alignItems: "center",
674
+ gap: theme.space.s2,
675
+ minWidth: theme.space[140]
676
+ },
677
+ centre: {
678
+ position: "absolute",
679
+ fontFamily: theme.font.sans,
680
+ fontWeight: theme.fontWeight.bold,
681
+ fontSize: theme.fontSize[20],
682
+ fontVariant: ["tabular-nums"],
683
+ color: theme.color.text
684
+ },
685
+ // The static key (R18): 10 swatch r 3 with its series edge, gap 8, the label
686
+ // at the platform's label weight (F51), the value in the count style.
687
+ chip: {
688
+ width: theme.space[10],
689
+ height: theme.space[10],
690
+ borderRadius: theme.radius[3],
691
+ borderWidth: theme.borderWidth.thin
692
+ },
693
+ legendLabel: {
694
+ fontFamily: theme.font.sans,
695
+ fontWeight: isAndroidIdiom(theme) ? theme.fontWeight.medium : theme.fontWeight.semibold,
696
+ fontSize: theme.fontSize[13],
697
+ color: theme.color.text
698
+ },
699
+ legendPct: {
700
+ marginLeft: "auto",
701
+ textAlign: "right",
702
+ fontFamily: theme.font.mono,
703
+ fontWeight: theme.fontWeight.medium,
704
+ fontSize: theme.fontSize[12],
705
+ fontVariant: ["tabular-nums"],
706
+ color: theme.color.text2
707
+ }
708
+ }));
709
+ function StackedBarChart({
710
+ labels: labelsProp,
711
+ data,
712
+ series,
713
+ width = 280,
714
+ height = 160,
715
+ gap = 10,
716
+ barRadius = 4,
717
+ colors,
718
+ stackMax,
719
+ showLabels = false,
720
+ showLegend = true,
721
+ motion,
722
+ animate = false,
723
+ state = "data",
724
+ emptyTitle,
725
+ emptyMessage,
726
+ errorTitle,
727
+ errorMessage,
728
+ retryLabel,
729
+ loadingLabel,
730
+ onRetry,
731
+ accessibilityLabel,
732
+ tone
733
+ }) {
734
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
735
+ const theme = useLoamTheme("charts");
736
+ const { styles } = useStyles(stackedSheet);
737
+ const opacity = useDrawIn(motion, animate);
738
+ const palette = [
739
+ theme.chart.c1,
740
+ theme.chart.c2,
741
+ theme.chart.c3,
742
+ theme.chart.c4,
743
+ theme.chart.c5,
744
+ theme.chart.c6
745
+ ];
746
+ const segColor = (i) => tone ? toneColors(theme, tone).main : colors && colors.length > 0 ? chartHue(theme, colors[i % colors.length]) : palette[i % palette.length];
747
+ const label = accessibilityLabel ?? (series && series.length ? labels.stackedSummary(
748
+ labels.stackedBarChart,
749
+ series.map((s) => s.label).join(", "),
750
+ data.length
751
+ ) : labels.stackedBarChart);
752
+ if (state !== "data") {
753
+ return /* @__PURE__ */ jsx(
754
+ ChartFrame,
755
+ {
756
+ labels,
757
+ state,
758
+ width,
759
+ height,
760
+ emptyTitle,
761
+ emptyMessage,
762
+ errorTitle,
763
+ errorMessage,
764
+ retryLabel,
765
+ loadingLabel,
766
+ onRetry
767
+ }
768
+ );
769
+ }
770
+ const n = data.length;
771
+ const colW = n > 0 ? Math.max(0, (width - gap * (n - 1)) / n) : 0;
772
+ const totals = data.map((d) => d.values.reduce((a, v) => a + Math.max(0, v), 0));
773
+ const domain = stackMax ?? Math.max(...totals, 0);
774
+ const gridFractions = [0.25, 0.5, 0.75];
775
+ return /* @__PURE__ */ jsxs(View, { accessibilityRole: "image", accessibilityLabel: label, style: styles.wrap, children: [
776
+ /* @__PURE__ */ jsx(Animated.View, { style: { opacity }, children: /* @__PURE__ */ jsxs(Svg, { width, height, viewBox: `0 0 ${width} ${height}`, fill: "none", children: [
777
+ gridFractions.map((f) => /* @__PURE__ */ jsx(
778
+ Line,
779
+ {
780
+ x1: 0,
781
+ y1: f * height,
782
+ x2: width,
783
+ y2: f * height,
784
+ stroke: theme.chart.grid,
785
+ strokeWidth: 1
786
+ },
787
+ f
788
+ )),
789
+ data.map((d, ci) => {
790
+ const x = ci * (colW + gap);
791
+ let topIdx = -1;
792
+ d.values.forEach((v, si) => {
793
+ if (v > 0) topIdx = si;
794
+ });
795
+ let yCursor = height;
796
+ return d.values.map((v, si) => {
797
+ const h = domain > 0 ? Math.max(0, v) / domain * height : 0;
798
+ if (h <= 0) return null;
799
+ yCursor -= h;
800
+ const y = yCursor;
801
+ if (si === topIdx) {
802
+ return /* @__PURE__ */ jsx(
803
+ Path,
804
+ {
805
+ d: topRoundedBar(x, y, colW, h, Math.min(barRadius, colW / 4)),
806
+ fill: segColor(si),
807
+ ...tone ? { fillOpacity: toneStep(theme, si) } : null,
808
+ stroke: theme.color.surface,
809
+ strokeWidth: 1
810
+ },
811
+ `${ci}-${si}`
812
+ );
813
+ }
814
+ return (
815
+ // Touching segments part on a 1 px surface seam, no outline (R19 V1).
816
+ /* @__PURE__ */ jsx(
817
+ Rect,
818
+ {
819
+ x,
820
+ y,
821
+ width: colW,
822
+ height: h,
823
+ fill: segColor(si),
824
+ ...tone ? { fillOpacity: toneStep(theme, si) } : null,
825
+ stroke: theme.color.surface,
826
+ strokeWidth: 1
827
+ },
828
+ `${ci}-${si}`
829
+ )
830
+ );
831
+ });
832
+ })
833
+ ] }) }),
834
+ showLabels ? /* @__PURE__ */ jsx(View, { style: styles.axis, children: data.map((d, i) => /* @__PURE__ */ jsx(Text, { style: styles.axisLabel, children: d.label }, i)) }) : null,
835
+ showLegend && series && series.length ? /* @__PURE__ */ jsx(View, { style: styles.legend, children: series.map((s, i) => /* @__PURE__ */ jsxs(View, { style: styles.legendItem, children: [
836
+ /* @__PURE__ */ jsx(
837
+ View,
838
+ {
839
+ style: [
840
+ styles.legendChip,
841
+ {
842
+ backgroundColor: segColor(i),
843
+ borderColor: chartEdgeHue(
844
+ theme,
845
+ colors && colors.length > 0 ? colors[i % colors.length] : i + 1
846
+ )
847
+ },
848
+ tone ? { borderColor: segColor(i), opacity: toneStep(theme, i) } : null
849
+ ]
850
+ }
851
+ ),
852
+ /* @__PURE__ */ jsx(Text, { style: styles.legendLabel, children: s.label })
853
+ ] }, i)) }) : null
854
+ ] });
855
+ }
856
+ var stackedSheet = createStyleSheet((theme) => ({
857
+ wrap: { gap: theme.space.s2 },
858
+ axis: { flexDirection: "row", justifyContent: "space-between" },
859
+ axisLabel: {
860
+ flex: 1,
861
+ textAlign: "center",
862
+ fontFamily: theme.font.mono,
863
+ fontSize: theme.fontSize[11],
864
+ color: theme.color.text3
865
+ },
866
+ legend: {
867
+ flexDirection: "row",
868
+ flexWrap: "wrap",
869
+ columnGap: theme.space.s4,
870
+ rowGap: theme.space.s2
871
+ },
872
+ legendItem: { flexDirection: "row", alignItems: "center", gap: theme.space.s2 },
873
+ legendChip: {
874
+ width: theme.space[10],
875
+ height: theme.space[10],
876
+ borderRadius: theme.radius[3],
877
+ borderWidth: theme.borderWidth.thin
878
+ },
879
+ legendLabel: {
880
+ fontFamily: theme.font.sans,
881
+ fontWeight: isAndroidIdiom(theme) ? theme.fontWeight.medium : theme.fontWeight.semibold,
882
+ fontSize: theme.fontSize[13],
883
+ color: theme.color.text
884
+ }
885
+ }));
886
+ function StatCard({
887
+ labels: labelsProp,
888
+ label,
889
+ value,
890
+ delta,
891
+ deltaTone = "good",
892
+ data,
893
+ tone = "accent",
894
+ loading = false,
895
+ roll = false,
896
+ motion,
897
+ onPress,
898
+ accessibilityLabel,
899
+ elevation = "default",
900
+ size = "sm",
901
+ variant = "default",
902
+ padding = "md",
903
+ format,
904
+ unit,
905
+ align = "start"
906
+ }) {
907
+ useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
908
+ const locale = useLoamLocale();
909
+ const theme = useLoamTheme("charts");
910
+ const android = isAndroidIdiom(theme);
911
+ const { styles } = useStyles(statSheet, {
912
+ idiom: android ? "android" : "ios",
913
+ size,
914
+ elevation: elevation === "default" ? void 0 : elevation
915
+ });
916
+ const valueFont = size === "lg" ? theme.type.largeTitle.fontSize : size === "md" ? theme.type.title1.fontSize : android ? theme.fontSize[24] : theme.fontSize[22];
917
+ const alignText = {
918
+ textAlign: align === "start" ? "left" : align === "end" ? "right" : "center"
919
+ };
920
+ const alignRow = {
921
+ justifyContent: align === "start" ? "flex-start" : align === "end" ? "flex-end" : "center"
922
+ };
923
+ const trimmed = delta?.trim() ?? "";
924
+ const direction = /^[-−]/.test(trimmed) ? "down" : /^\+/.test(trimmed) ? "up" : "flat";
925
+ const invert = direction === "down" ? deltaTone === "good" : deltaTone === "danger";
926
+ const [sparkW, setSparkW] = React.useState(0);
927
+ const onSparkLayout = React.useCallback((e) => {
928
+ setSparkW(e.nativeEvent.layout.width);
929
+ }, []);
930
+ const cardStyle = [
931
+ styles.card,
932
+ variant === "outline" ? styles.cardOutline : variant === "ghost" ? styles.cardGhost : null,
933
+ padding === "sm" ? styles.cardPadSm : padding === "lg" ? styles.cardPadLg : null
934
+ ];
935
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
936
+ /* @__PURE__ */ jsx(Text, { style: [styles.label, resolveTextRole(theme, "overline", android), alignText], children: label }),
937
+ loading ? /* @__PURE__ */ jsxs(View, { style: styles.valueRow, children: [
938
+ /* @__PURE__ */ jsx(Skeleton, { variant: "rect", width: 96, height: Math.round(valueFont * 1.1), decorative: true }),
939
+ /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: 48, height: theme.space[20], decorative: true })
940
+ ] }) : /* @__PURE__ */ jsxs(View, { style: [styles.valueRow, alignRow], children: [
941
+ roll && typeof value === "number" ? /* @__PURE__ */ jsx(NumberRoll, { value, format, textStyle: styles.value, motion }) : typeof value === "string" || typeof value === "number" ? /* @__PURE__ */ jsx(Text, { style: styles.value, children: typeof value === "number" && format ? value.toLocaleString(locale, format) : value }) : value,
942
+ unit ? /* @__PURE__ */ jsx(Text, { style: styles.unit, children: unit }) : null,
943
+ delta ? /* @__PURE__ */ jsx(MetricDelta, { delta, deltaDirection: direction, invert, size: "sm" }) : null
944
+ ] }),
945
+ /* @__PURE__ */ jsx(View, { style: styles.spark, onLayout: onSparkLayout, children: loading ? /* @__PURE__ */ jsx(Skeleton, { variant: "rect", height: 34, decorative: true }) : (
946
+ /* 120 is the pre-measurement fallback (first paint, jsdom). */
947
+ /* @__PURE__ */ jsx(
948
+ Sparkline,
949
+ {
950
+ data,
951
+ tone,
952
+ width: sparkW > 0 ? sparkW : 120,
953
+ height: 34,
954
+ showArea: true
955
+ }
956
+ )
957
+ ) })
958
+ ] });
959
+ if (onPress) {
960
+ return /* @__PURE__ */ jsx(
961
+ Pressable,
962
+ {
963
+ accessibilityRole: "button",
964
+ accessibilityLabel: accessibilityLabel ?? label,
965
+ accessibilityState: loading ? { busy: true } : void 0,
966
+ "aria-busy": loading || void 0,
967
+ onPress,
968
+ style: ({ pressed }) => [cardStyle, pressed ? styles.cardPressed : null],
969
+ children: body
970
+ }
971
+ );
972
+ }
973
+ return /* @__PURE__ */ jsx(
974
+ View,
975
+ {
976
+ accessibilityRole: "image",
977
+ accessibilityLabel: accessibilityLabel ?? label,
978
+ accessibilityState: loading ? { busy: true } : void 0,
979
+ "aria-busy": loading || void 0,
980
+ style: cardStyle,
981
+ children: body
982
+ }
983
+ );
984
+ }
985
+ var statSheet = createStyleSheet((theme) => ({
986
+ card: {
987
+ backgroundColor: theme.color.surface,
988
+ borderWidth: theme.borderWidth.thin,
989
+ borderColor: theme.color.border,
990
+ borderRadius: theme.radius.lg,
991
+ minHeight: theme.space[112],
992
+ padding: theme.space[16],
993
+ gap: theme.space.s2,
994
+ variants: {
995
+ elevation: {
996
+ flat: {},
997
+ raised: { ...theme.shadow.lg }
998
+ }
999
+ }
1000
+ },
1001
+ cardOutline: { backgroundColor: "transparent" },
1002
+ cardGhost: { backgroundColor: "transparent", borderColor: "transparent" },
1003
+ cardPadSm: { padding: theme.space[10] },
1004
+ cardPadLg: { padding: theme.space[24] },
1005
+ unit: { fontFamily: theme.font.sans, color: theme.color.text2 },
1006
+ cardPressed: { backgroundColor: theme.state.pressed },
1007
+ label: { fontFamily: theme.font.sans, color: theme.color.text2 },
1008
+ valueRow: {
1009
+ flexDirection: "row",
1010
+ flexWrap: "wrap",
1011
+ alignItems: "center",
1012
+ columnGap: theme.space.s2,
1013
+ rowGap: theme.space.s1
1014
+ },
1015
+ // The money figure (F51): iOS 22 / 700, Android 24 / 400, tabular.
1016
+ value: {
1017
+ fontFamily: theme.font.sans,
1018
+ fontVariant: ["tabular-nums"],
1019
+ color: theme.color.text,
1020
+ variants: {
1021
+ idiom: {
1022
+ ios: { fontWeight: theme.fontWeight.bold, fontSize: theme.fontSize[22] },
1023
+ android: { fontWeight: theme.fontWeight.regular, fontSize: theme.fontSize[24] }
1024
+ },
1025
+ size: {
1026
+ sm: {},
1027
+ md: {
1028
+ fontSize: theme.type.title1.fontSize,
1029
+ lineHeight: theme.type.title1.lineHeight,
1030
+ letterSpacing: theme.type.title1.letterSpacing
1031
+ },
1032
+ lg: {
1033
+ fontSize: theme.type.largeTitle.fontSize,
1034
+ lineHeight: theme.type.largeTitle.lineHeight,
1035
+ letterSpacing: theme.type.largeTitle.letterSpacing
1036
+ }
1037
+ }
1038
+ }
1039
+ },
1040
+ spark: { marginTop: "auto" }
1041
+ }));
1042
+ var plain = (v) => String(Math.round(v * 100) / 100);
1043
+ function chartSlot(theme, i) {
1044
+ const six = [
1045
+ theme.chart.c1,
1046
+ theme.chart.c2,
1047
+ theme.chart.c3,
1048
+ theme.chart.c4,
1049
+ theme.chart.c5,
1050
+ theme.chart.c6
1051
+ ];
1052
+ return i < 6 ? six[i] : theme.chart.tier[(i - 6) % 6] ?? six[i % 6];
1053
+ }
1054
+ function segFill(theme, kind) {
1055
+ if (kind === "free") return theme.color.surface2;
1056
+ if (kind === "other") return theme.color.borderStrong;
1057
+ return chartSlot(theme, kind % 12);
1058
+ }
1059
+ function splitSegments(parts, maxParts, total, labels) {
1060
+ const clean = parts.filter((p) => p.value > 0);
1061
+ const own = clean.length > maxParts ? clean.slice(0, Math.max(0, maxParts - 1)) : clean;
1062
+ const rest = clean.slice(own.length);
1063
+ const segs = own.map((p, i) => ({ ...p, kind: i }));
1064
+ if (rest.length) {
1065
+ segs.push({
1066
+ id: "__other",
1067
+ label: labels.other,
1068
+ value: rest.reduce((a, p) => a + p.value, 0),
1069
+ kind: "other"
1070
+ });
1071
+ }
1072
+ const sum = segs.reduce((a, s) => a + s.value, 0);
1073
+ if (total !== void 0 && total > sum) {
1074
+ segs.push({ id: "__free", label: labels.free, value: total - sum, kind: "free" });
1075
+ }
1076
+ return segs;
1077
+ }
1078
+ function SplitBar({
1079
+ parts,
1080
+ total,
1081
+ maxParts = 5,
1082
+ format = plain,
1083
+ legend = "below",
1084
+ size = "md",
1085
+ title,
1086
+ summary,
1087
+ state = "data",
1088
+ emptyText,
1089
+ motion,
1090
+ labels: labelsProp,
1091
+ tone
1092
+ }) {
1093
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
1094
+ const theme = useLoamTheme("charts");
1095
+ const android = isAndroidIdiom(theme);
1096
+ const { styles } = useStyles(splitSheet, { size });
1097
+ const segs = splitSegments(parts, maxParts, total, labels);
1098
+ const paint = (kind) => tone && typeof kind === "number" ? toneColors(theme, tone).main : segFill(theme, kind);
1099
+ const whole = segs.reduce((a, s) => a + s.value, 0);
1100
+ const [lit, setLit] = React.useState(null);
1101
+ const pct = (v) => whole > 0 ? Math.round(v / whole * 100) : 0;
1102
+ const readout = lit !== null && segs[lit] ? `${segs[lit].label} \xB7 ${format(segs[lit].value)} \xB7 ${pct(segs[lit].value)}%` : void 0;
1103
+ const detail = readout ?? summary;
1104
+ const header = title !== void 0 || detail !== void 0 ? /* @__PURE__ */ jsxs(View, { style: styles.header, children: [
1105
+ title !== void 0 ? /* @__PURE__ */ jsx(Text, { style: [styles.title, resolveTextRole(theme, "body", android)], children: title }) : /* @__PURE__ */ jsx(View, {}),
1106
+ state === "data" && detail !== void 0 ? /* @__PURE__ */ jsx(
1107
+ Text,
1108
+ {
1109
+ accessibilityLiveRegion: "polite",
1110
+ style: [styles.detail, resolveTextRole(theme, "subheadline", android)],
1111
+ children: detail
1112
+ }
1113
+ ) : null
1114
+ ] }) : null;
1115
+ if (state !== "data" || segs.length === 0) {
1116
+ return /* @__PURE__ */ jsxs(View, { style: styles.wrap, children: [
1117
+ header,
1118
+ state === "loading" ? /* @__PURE__ */ jsx(Skeleton, { variant: "rect", height: size === "sm" ? 8 : 12, motion }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1119
+ /* @__PURE__ */ jsx(View, { style: [styles.bar, styles.emptyTrack] }),
1120
+ /* @__PURE__ */ jsx(Text, { style: [styles.emptyText, resolveTextRole(theme, "footnote", android)], children: emptyText ?? labels.splitEmpty })
1121
+ ] })
1122
+ ] });
1123
+ }
1124
+ return /* @__PURE__ */ jsxs(View, { style: styles.wrap, children: [
1125
+ header,
1126
+ /* @__PURE__ */ jsx(View, { role: "group", accessibilityLabel: labels.splitBar, style: [styles.bar, styles.row], children: segs.map((s, i) => /* @__PURE__ */ jsx(
1127
+ Pressable,
1128
+ {
1129
+ accessibilityRole: "button",
1130
+ accessibilityLabel: `${s.label}, ${format(s.value)}, ${labels.percent(pct(s.value))}`,
1131
+ onPress: () => {
1132
+ haptics.selection();
1133
+ setLit(lit === i ? null : i);
1134
+ },
1135
+ hitSlop: { top: theme.space[16], bottom: theme.space[16] },
1136
+ style: [
1137
+ styles.segment,
1138
+ s.kind === "free" && styles.freeEdge,
1139
+ {
1140
+ flexGrow: s.value,
1141
+ backgroundColor: paint(s.kind),
1142
+ opacity: lit !== null && lit !== i ? theme.opacity[32] : tone && typeof s.kind === "number" ? toneStep(theme, s.kind) : 1
1143
+ }
1144
+ ]
1145
+ },
1146
+ s.id
1147
+ )) }),
1148
+ legend === "below" ? /* @__PURE__ */ jsx(View, { style: styles.legend, children: segs.map((s) => /* @__PURE__ */ jsxs(View, { style: styles.legendItem, children: [
1149
+ /* @__PURE__ */ jsx(
1150
+ View,
1151
+ {
1152
+ style: [
1153
+ styles.dot,
1154
+ s.kind === "free" && styles.freeEdge,
1155
+ { backgroundColor: paint(s.kind) },
1156
+ tone && typeof s.kind === "number" ? { opacity: toneStep(theme, s.kind) } : null
1157
+ ]
1158
+ }
1159
+ ),
1160
+ /* @__PURE__ */ jsx(Text, { style: [styles.legendText, resolveTextRole(theme, "footnote", android)], children: s.label })
1161
+ ] }, s.id)) }) : null
1162
+ ] });
1163
+ }
1164
+ var splitSheet = createStyleSheet((theme) => ({
1165
+ wrap: { gap: theme.space[10] },
1166
+ header: {
1167
+ flexDirection: "row",
1168
+ justifyContent: "space-between",
1169
+ alignItems: "baseline",
1170
+ gap: theme.space.s3
1171
+ },
1172
+ title: { fontFamily: theme.font.sans, color: theme.color.text, flexShrink: 1 },
1173
+ detail: { fontFamily: theme.font.sans, color: theme.color.text2, fontVariant: ["tabular-nums"] },
1174
+ bar: { variants: { size: { sm: { height: theme.space[8] }, md: { height: theme.space[12] } } } },
1175
+ row: { flexDirection: "row", gap: theme.space[2] },
1176
+ // r 4 on every segment; min 2 so a tiny share stays visible.
1177
+ segment: { flexBasis: 0, minWidth: theme.space[2], borderRadius: theme.radius.xs },
1178
+ freeEdge: { borderWidth: theme.borderWidth.thin, borderColor: theme.color.border },
1179
+ emptyTrack: {
1180
+ borderRadius: theme.radius.xs,
1181
+ backgroundColor: theme.color.surface2,
1182
+ borderWidth: theme.borderWidth.thin,
1183
+ borderColor: theme.color.border
1184
+ },
1185
+ emptyText: { fontFamily: theme.font.sans, color: theme.color.text3 },
1186
+ legend: {
1187
+ flexDirection: "row",
1188
+ flexWrap: "wrap",
1189
+ columnGap: theme.space[14],
1190
+ rowGap: theme.space[6]
1191
+ },
1192
+ legendItem: { flexDirection: "row", alignItems: "center", gap: theme.space[6] },
1193
+ dot: { width: theme.space[8], height: theme.space[8], borderRadius: theme.radius.full },
1194
+ legendText: { fontFamily: theme.font.sans, color: theme.color.text2 }
1195
+ }));
1196
+ function RankedBars({
1197
+ items,
1198
+ limit = 5,
1199
+ tone = 1,
1200
+ format = plain,
1201
+ state = "data",
1202
+ emptyText,
1203
+ motion,
1204
+ accessibilityLabel,
1205
+ labels: labelsProp
1206
+ }) {
1207
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
1208
+ const theme = useLoamTheme("charts");
1209
+ const android = isAndroidIdiom(theme);
1210
+ const { styles } = useStyles(rankedSheet);
1211
+ const shown = [...items].sort((a, b) => b.value - a.value).slice(0, limit);
1212
+ const max = Math.max(0, ...shown.map((r) => r.value));
1213
+ const fill = chartSlot(theme, ((Math.round(tone) - 1) % 12 + 12) % 12);
1214
+ const labelRole = resolveTextRole(theme, android ? "bodyMedium" : "subheadline", android);
1215
+ if (state === "loading") {
1216
+ return /* @__PURE__ */ jsx(View, { style: styles.list, children: Array.from({ length: Math.min(limit, 5) }, (_, i) => /* @__PURE__ */ jsxs(View, { style: [styles.row, styles.rowStatic], children: [
1217
+ /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: 96, motion }),
1218
+ /* @__PURE__ */ jsx(View, { style: styles.trackCell, children: /* @__PURE__ */ jsx(Skeleton, { variant: "rect", height: 8, motion }) })
1219
+ ] }, i)) });
1220
+ }
1221
+ if (state === "empty" || shown.length === 0) {
1222
+ return /* @__PURE__ */ jsx(Text, { style: [styles.empty, resolveTextRole(theme, "footnote", android)], children: emptyText ?? labels.splitEmpty });
1223
+ }
1224
+ return /* @__PURE__ */ jsx(
1225
+ View,
1226
+ {
1227
+ accessibilityRole: "list",
1228
+ accessibilityLabel: accessibilityLabel ?? labels.rankedBars,
1229
+ style: styles.list,
1230
+ children: shown.map((r) => {
1231
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
1232
+ /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: [styles.label, labelRole], children: r.label }),
1233
+ /* @__PURE__ */ jsx(View, { style: [styles.trackCell, styles.track], children: /* @__PURE__ */ jsx(
1234
+ View,
1235
+ {
1236
+ style: [
1237
+ styles.fill,
1238
+ { width: `${max > 0 ? r.value / max * 100 : 0}%`, backgroundColor: fill }
1239
+ ]
1240
+ }
1241
+ ) }),
1242
+ /* @__PURE__ */ jsx(Text, { style: [styles.value, labelRole, android && styles.valueAndroid], children: format(r.value) })
1243
+ ] });
1244
+ return r.onPress ? /* @__PURE__ */ jsx(View, { role: "listitem", children: /* @__PURE__ */ jsx(
1245
+ Pressable,
1246
+ {
1247
+ accessibilityRole: "button",
1248
+ accessibilityLabel: `${r.label}, ${format(r.value)}`,
1249
+ onPress: r.onPress,
1250
+ android_ripple: android ? { color: theme.state.pressed } : void 0,
1251
+ style: ({ pressed }) => [
1252
+ styles.row,
1253
+ styles.rowTouch,
1254
+ pressed && !android && { backgroundColor: theme.state.pressed }
1255
+ ],
1256
+ children: body
1257
+ }
1258
+ ) }, r.id) : /* @__PURE__ */ jsx(
1259
+ View,
1260
+ {
1261
+ role: "listitem",
1262
+ accessible: true,
1263
+ accessibilityLabel: `${r.label}, ${format(r.value)}`,
1264
+ style: [styles.row, styles.rowStatic],
1265
+ children: body
1266
+ },
1267
+ r.id
1268
+ );
1269
+ })
1270
+ }
1271
+ );
1272
+ }
1273
+ var rankedSheet = createStyleSheet((theme) => ({
1274
+ list: { paddingVertical: theme.space[4] },
1275
+ row: {
1276
+ flexDirection: "row",
1277
+ alignItems: "center",
1278
+ gap: theme.space.s3,
1279
+ paddingHorizontal: theme.space.s4
1280
+ },
1281
+ rowStatic: { height: theme.space[32] },
1282
+ rowTouch: { height: theme.space[48] },
1283
+ label: { width: theme.space[96], fontFamily: theme.font.sans, color: theme.color.text },
1284
+ trackCell: { flex: 1 },
1285
+ track: {
1286
+ height: theme.space[8],
1287
+ borderRadius: theme.radius.xs,
1288
+ backgroundColor: theme.color.surface2
1289
+ },
1290
+ fill: { height: theme.space[8], borderRadius: theme.radius.xs },
1291
+ value: {
1292
+ width: theme.space[44],
1293
+ textAlign: "right",
1294
+ fontFamily: theme.font.sans,
1295
+ fontWeight: theme.fontWeight.semibold,
1296
+ fontVariant: ["tabular-nums"],
1297
+ color: theme.color.text
1298
+ },
1299
+ valueAndroid: { fontWeight: theme.fontWeight.medium },
1300
+ empty: { fontFamily: theme.font.sans, color: theme.color.text3, padding: theme.space.s2 }
1301
+ }));
1302
+
1303
+ export { BarChart, ChartFrame, DonutChart, RankedBars, RingChart, Sparkline, SplitBar, StackedBarChart, StatCard, foldDonutSlices };