@btndprojects/loam-ui-native 0.1.0 → 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 (263) hide show
  1. package/README.md +56 -0
  2. package/dist/accordion/index.js +5 -3
  3. package/dist/adaptive/index.js +6 -2
  4. package/dist/alert/index.js +5 -2
  5. package/dist/analyzer/index.js +9 -6
  6. package/dist/announcement/index.js +8 -5
  7. package/dist/audio-player/index.js +5 -3
  8. package/dist/avatar/index.js +5 -2
  9. package/dist/avatar-group/index.js +7 -3
  10. package/dist/badge/index.js +7 -4
  11. package/dist/banner/index.js +5 -2
  12. package/dist/board/index.js +11 -6
  13. package/dist/button/index.js +6 -3
  14. package/dist/camera-permission/index.js +15 -12
  15. package/dist/capture-result/index.js +19 -16
  16. package/dist/card/index.js +6 -3
  17. package/dist/card-form/index.js +12 -8
  18. package/dist/carousel/index.js +4 -2
  19. package/dist/chart/index.js +8 -5
  20. package/dist/charts/index.js +8 -6
  21. package/dist/chat/index.js +16 -0
  22. package/dist/checkbox/index.js +6 -4
  23. package/dist/checklist/index.js +11 -8
  24. package/dist/checkout/index.js +16 -11
  25. package/dist/chip/index.js +7 -4
  26. package/dist/{chunk-XNUVB5OL.js → chunk-2OLKPG4E.js} +92 -28
  27. package/dist/{chunk-RUZHTGKB.js → chunk-2PKYGLQ6.js} +71 -40
  28. package/dist/{chunk-UC2WGUP3.js → chunk-2SWKL3AJ.js} +91 -252
  29. package/dist/{chunk-AI4DWZCD.js → chunk-2SY63FCH.js} +63 -16
  30. package/dist/{chunk-F5XNPWS7.js → chunk-2TXERVVA.js} +92 -35
  31. package/dist/chunk-36EC2T6P.js +581 -0
  32. package/dist/chunk-3DUWIYV5.js +437 -0
  33. package/dist/{chunk-RGQWWKLA.js → chunk-3QMEOFW5.js} +275 -71
  34. package/dist/chunk-3WEZCGHX.js +265 -0
  35. package/dist/chunk-46MMSDGL.js +194 -0
  36. package/dist/{chunk-7O2FMUPT.js → chunk-4IZXHVFJ.js} +297 -92
  37. package/dist/{chunk-LAECSR4H.js → chunk-5LAAAXFP.js} +14 -8
  38. package/dist/{chunk-2A5NIQAK.js → chunk-5RENVKBQ.js} +134 -46
  39. package/dist/{chunk-2ZZ7TDJ4.js → chunk-5UTRIXQ6.js} +37 -31
  40. package/dist/{chunk-LOE5YNN3.js → chunk-5VFZRGVD.js} +37 -10
  41. package/dist/{chunk-52X2VYTD.js → chunk-67IZZ2MJ.js} +115 -60
  42. package/dist/{chunk-UYG5L34B.js → chunk-6YAQBXB3.js} +10 -4
  43. package/dist/{chunk-BTTFCMKG.js → chunk-74FLKD24.js} +94 -23
  44. package/dist/{chunk-ITTYJZWX.js → chunk-7BUIKDD6.js} +73 -18
  45. package/dist/{chunk-FOKG57CR.js → chunk-7OVVSVEZ.js} +273 -109
  46. package/dist/chunk-AEB7KCHQ.js +287 -0
  47. package/dist/chunk-APCWFOZW.js +28 -0
  48. package/dist/chunk-AWKQIE5I.js +139 -0
  49. package/dist/{chunk-VCDBXW5H.js → chunk-B7N4ASYE.js} +86 -42
  50. package/dist/{chunk-IVNRBPGC.js → chunk-C4GTDLRC.js} +104 -20
  51. package/dist/{chunk-4ZAHCY44.js → chunk-C6APNDVA.js} +12 -5
  52. package/dist/{chunk-4SZYY6AN.js → chunk-CMTVNF3D.js} +18 -13
  53. package/dist/{chunk-WVKKJA6U.js → chunk-CPTOADB2.js} +151 -96
  54. package/dist/chunk-D5N5QWI7.js +1325 -0
  55. package/dist/{chunk-IIQTAY3J.js → chunk-DN7MNQIP.js} +113 -29
  56. package/dist/{chunk-47FWHGUN.js → chunk-DVGBZ3TX.js} +84 -23
  57. package/dist/chunk-DW3L54DQ.js +305 -0
  58. package/dist/{chunk-3ARE4TES.js → chunk-E2E3I5W2.js} +69 -18
  59. package/dist/{chunk-DHWADYZX.js → chunk-EDCBJV7J.js} +41 -28
  60. package/dist/{chunk-WSW6ZFAQ.js → chunk-ENP3BMZU.js} +4 -4
  61. package/dist/{chunk-OOPPQH27.js → chunk-EVOIGUBI.js} +43 -19
  62. package/dist/{chunk-VEAYTRPX.js → chunk-EY4DD67D.js} +165 -97
  63. package/dist/{chunk-223Q2T2Q.js → chunk-F3H33DQX.js} +132 -61
  64. package/dist/{chunk-CYRBHQQZ.js → chunk-F5B3UINI.js} +68 -35
  65. package/dist/{chunk-6X6PQ443.js → chunk-FAJI7BSC.js} +20 -9
  66. package/dist/{chunk-MOUJOP55.js → chunk-FUMHAAF3.js} +96 -29
  67. package/dist/{chunk-6HT2LP62.js → chunk-FV6HMP7W.js} +192 -73
  68. package/dist/{chunk-S7F6XLTK.js → chunk-FYWNRX4F.js} +76 -47
  69. package/dist/{chunk-YG3ZJHGU.js → chunk-FZGAAOKS.js} +30 -8
  70. package/dist/{chunk-YDGVJETP.js → chunk-G3AFC24V.js} +1 -1
  71. package/dist/{chunk-EJBDRVIH.js → chunk-G6UESEVN.js} +15 -8
  72. package/dist/chunk-GDKVKNR2.js +339 -0
  73. package/dist/chunk-GEIGMWNF.js +10 -0
  74. package/dist/{chunk-JUAMLEHX.js → chunk-H7DWSL4O.js} +24 -12
  75. package/dist/chunk-HJFFOOJ4.js +1 -0
  76. package/dist/{chunk-RW6ZL2FQ.js → chunk-HJLPZA4X.js} +106 -21
  77. package/dist/chunk-HYEOQWT7.js +647 -0
  78. package/dist/chunk-I2KLQ2HA.js +19 -0
  79. package/dist/{chunk-CJ5EOYZE.js → chunk-I4FHVKEC.js} +11 -5
  80. package/dist/{chunk-JNH2TYIN.js → chunk-IDM7JJMO.js} +19 -5
  81. package/dist/{chunk-O4AEHWII.js → chunk-IPUNJMAQ.js} +141 -49
  82. package/dist/{chunk-J7Q7VCVC.js → chunk-IT6FUXXG.js} +13 -6
  83. package/dist/{chunk-QJJ6MADV.js → chunk-IVKMZ7BB.js} +80 -28
  84. package/dist/{chunk-Z7H7VSFZ.js → chunk-IXKWIFWZ.js} +17 -6
  85. package/dist/chunk-J64KGCGX.js +55 -0
  86. package/dist/chunk-JBMLWFSJ.js +270 -0
  87. package/dist/{chunk-4BXMXBJO.js → chunk-JJLPBRVZ.js} +22 -11
  88. package/dist/chunk-JLC6PM5S.js +406 -0
  89. package/dist/chunk-JUYWSSKW.js +335 -0
  90. package/dist/{chunk-7CFF4HXS.js → chunk-JV5YOTOB.js} +49 -11
  91. package/dist/{chunk-LZLHELAG.js → chunk-KFJGFLMW.js} +29 -8
  92. package/dist/{chunk-O7AE6DAF.js → chunk-KQZ3GLHR.js} +18 -8
  93. package/dist/{chunk-N32RGOA5.js → chunk-LKFC4CS7.js} +80 -24
  94. package/dist/{chunk-YC6WORFL.js → chunk-LMPHCVJJ.js} +82 -50
  95. package/dist/{chunk-3WPW4KUN.js → chunk-LQP4KEXZ.js} +45 -13
  96. package/dist/{chunk-TKQYWZ5V.js → chunk-LUMVGO2K.js} +47 -31
  97. package/dist/{chunk-AWJOCGFZ.js → chunk-M656FYNH.js} +25 -13
  98. package/dist/{chunk-35OFI3JG.js → chunk-MKSNFG7H.js} +73 -20
  99. package/dist/{chunk-4GBOGOTV.js → chunk-NBEF4EPJ.js} +16 -6
  100. package/dist/chunk-NNCOFLNE.js +24 -0
  101. package/dist/{chunk-4YQOR7JM.js → chunk-NTQ2F3AU.js} +73 -20
  102. package/dist/{chunk-QCDXZBC5.js → chunk-O5V4TG3V.js} +126 -44
  103. package/dist/{chunk-U7TFM2JA.js → chunk-OJQUBQWA.js} +3 -3
  104. package/dist/{chunk-VQHPQEUH.js → chunk-OWAMM2DK.js} +13 -6
  105. package/dist/chunk-PID3NJB7.js +405 -0
  106. package/dist/{chunk-66SG2H23.js → chunk-PMMTGBBS.js} +27 -17
  107. package/dist/{chunk-RIBDXGUG.js → chunk-PNF3NKB5.js} +49 -16
  108. package/dist/{chunk-JXJB2X6M.js → chunk-Q6NKEPRE.js} +81 -32
  109. package/dist/chunk-QDZGFXQD.js +176 -0
  110. package/dist/{chunk-SYNOJOQO.js → chunk-QEYFDRHR.js} +60 -26
  111. package/dist/{chunk-VBOXAEPI.js → chunk-QHAITQIF.js} +97 -22
  112. package/dist/{chunk-VXDZFJGP.js → chunk-QHTVYA65.js} +230 -76
  113. package/dist/{chunk-TUTI5HOZ.js → chunk-QIKT7LIB.js} +14 -8
  114. package/dist/{chunk-3ENTMPQY.js → chunk-QP3KMOVF.js} +82 -42
  115. package/dist/{chunk-GNNJ4GCC.js → chunk-QPWDDJJ4.js} +62 -148
  116. package/dist/{chunk-QWCMU5B2.js → chunk-QRUMA22E.js} +205 -80
  117. package/dist/{chunk-ZVFE5QGU.js → chunk-QYPE5JX3.js} +50 -10
  118. package/dist/{chunk-PUPM2YGF.js → chunk-ROCUG24E.js} +76 -36
  119. package/dist/{chunk-NQYBUO3K.js → chunk-RU3ZPNL6.js} +333 -142
  120. package/dist/{chunk-TOXAGRDQ.js → chunk-RXSCIO6W.js} +14 -5
  121. package/dist/{chunk-FIF2M24N.js → chunk-SATMR6SG.js} +631 -203
  122. package/dist/{chunk-4YIP3CWS.js → chunk-SHHY5OMK.js} +7 -5
  123. package/dist/chunk-SKWO3SZF.js +2284 -0
  124. package/dist/{chunk-YF4NSSMT.js → chunk-SWS5JQIF.js} +41 -13
  125. package/dist/{chunk-CUMUNPXY.js → chunk-T5LTPKX6.js} +15 -7
  126. package/dist/{chunk-H6NIOQHK.js → chunk-TDMG26JI.js} +26 -6
  127. package/dist/{chunk-UWFLYMAR.js → chunk-TLCIR6RG.js} +267 -126
  128. package/dist/{chunk-SBMNWWBV.js → chunk-TN2ZNJUI.js} +47 -9
  129. package/dist/{chunk-5YNTNN5A.js → chunk-TQVAIKFD.js} +106 -41
  130. package/dist/chunk-TRGFFU6A.js +1456 -0
  131. package/dist/{chunk-2GK6PHGE.js → chunk-TY4MTKQJ.js} +100 -22
  132. package/dist/{chunk-AZRX6SAC.js → chunk-U23FYWME.js} +15 -7
  133. package/dist/{chunk-PZXZJBMP.js → chunk-U5NLHYV6.js} +26 -12
  134. package/dist/chunk-UQEN55EY.js +1 -0
  135. package/dist/chunk-UQGBTPXH.js +218 -0
  136. package/dist/chunk-UXGIW7OK.js +116 -0
  137. package/dist/{chunk-PJXUJYS6.js → chunk-UYGDJWMN.js} +55 -30
  138. package/dist/{chunk-QDYDBCFP.js → chunk-V2OEB75Z.js} +50 -51
  139. package/dist/{chunk-LSS54GLJ.js → chunk-VAOAKWUK.js} +34 -13
  140. package/dist/{chunk-DM5QUKKO.js → chunk-VDPK5CY4.js} +18 -6
  141. package/dist/chunk-W23G6JLF.js +37 -0
  142. package/dist/{chunk-CDRZHT42.js → chunk-W63AJTM7.js} +276 -12
  143. package/dist/{chunk-XXXEFXY5.js → chunk-W74TXYFB.js} +13 -5
  144. package/dist/{chunk-LRJNDEIA.js → chunk-WRDSPUE7.js} +144 -29
  145. package/dist/{chunk-C2NTXVWM.js → chunk-XBZGDDMR.js} +11 -4
  146. package/dist/{chunk-BV3B2HYZ.js → chunk-XIDTBCBA.js} +189 -131
  147. package/dist/{chunk-DSJBXLUG.js → chunk-XN4KG3P4.js} +348 -153
  148. package/dist/chunk-XQXMLMH3.js +211 -0
  149. package/dist/{chunk-HPPW424V.js → chunk-XTORZWRF.js} +19 -8
  150. package/dist/{chunk-P23EQNRQ.js → chunk-YAAHPATV.js} +181 -30
  151. package/dist/{chunk-KMI5ML5I.js → chunk-YXOAPXMU.js} +57 -18
  152. package/dist/{chunk-RJQOOHT2.js → chunk-ZECZOOSB.js} +59 -28
  153. package/dist/{chunk-QKXCPTFS.js → chunk-ZLTO5VQI.js} +121 -31
  154. package/dist/{chunk-BEDBFJND.js → chunk-ZVATDZOM.js} +16 -18
  155. package/dist/coachmark/index.js +6 -3
  156. package/dist/code-block/index.js +5 -3
  157. package/dist/color-field/index.js +6 -4
  158. package/dist/commerce/index.js +19 -16
  159. package/dist/connectivity/index.js +5 -2
  160. package/dist/context-menu/index.js +5 -3
  161. package/dist/copy-button/index.js +4 -2
  162. package/dist/data-grid/index.js +21 -16
  163. package/dist/date-range-picker/index.js +11 -8
  164. package/dist/description-list/index.js +3 -1
  165. package/dist/dialog/index.js +4 -2
  166. package/dist/empty-state/index.js +4 -2
  167. package/dist/error-summary/index.js +4 -2
  168. package/dist/fab/index.js +5 -2
  169. package/dist/file-manager/index.js +28 -0
  170. package/dist/file-upload/index.js +10 -7
  171. package/dist/filter-bar/index.js +9 -6
  172. package/dist/flow-run/index.js +15 -12
  173. package/dist/form/index.js +5 -3
  174. package/dist/gallery/index.js +5 -2
  175. package/dist/hold-to-confirm/index.js +4 -2
  176. package/dist/index.d.ts +9557 -2985
  177. package/dist/index.js +355 -122
  178. package/dist/infinite-list/index.js +4 -2
  179. package/dist/inline-edit/index.js +6 -4
  180. package/dist/input/index.js +5 -3
  181. package/dist/interactions/index.js +2 -1
  182. package/dist/invoice/index.js +13 -9
  183. package/dist/kbd/index.js +5 -1
  184. package/dist/keyboard/index.js +4 -2
  185. package/dist/list-row/index.js +6 -4
  186. package/dist/log-viewer/index.js +4 -2
  187. package/dist/map-view/index.js +5 -3
  188. package/dist/markdown/index.js +9 -6
  189. package/dist/metric/index.js +7 -4
  190. package/dist/money/index.js +9 -3
  191. package/dist/nav-drawer/index.js +4 -2
  192. package/dist/nav-header/index.js +9 -0
  193. package/dist/navigation/index.js +5 -2
  194. package/dist/notification-center/index.js +12 -10
  195. package/dist/number-roll/index.js +5 -2
  196. package/dist/one-handed/index.js +5 -3
  197. package/dist/os-surfaces/index.js +6 -3
  198. package/dist/otp/index.js +7 -4
  199. package/dist/page-header/index.js +1 -0
  200. package/dist/pagination/index.js +6 -0
  201. package/dist/payment-method/index.js +14 -10
  202. package/dist/payment-status/index.js +17 -14
  203. package/dist/permission/index.js +5 -2
  204. package/dist/picker/index.js +11 -6
  205. package/dist/progress/index.js +6 -3
  206. package/dist/pull-to-refresh/index.js +4 -2
  207. package/dist/radio-group/index.js +6 -4
  208. package/dist/rating/index.js +5 -2
  209. package/dist/receivables/index.js +21 -16
  210. package/dist/refund/index.js +18 -14
  211. package/dist/save-status/index.js +5 -3
  212. package/dist/scroll-area/index.js +3 -1
  213. package/dist/search-field/index.js +8 -0
  214. package/dist/segmented-control/index.js +4 -3
  215. package/dist/sheet/index.js +5 -3
  216. package/dist/skeleton/index.js +3 -1
  217. package/dist/slider/index.js +4 -2
  218. package/dist/sortable/index.js +7 -0
  219. package/dist/spinner/index.js +3 -1
  220. package/dist/split-button/index.js +9 -6
  221. package/dist/spotlight/index.js +3 -1
  222. package/dist/stage-timeline/index.js +5 -3
  223. package/dist/status-dot/index.js +4 -2
  224. package/dist/stepper/index.js +7 -4
  225. package/dist/streaming-text/index.js +3 -2
  226. package/dist/survey/index.js +18 -15
  227. package/dist/switch/index.js +5 -3
  228. package/dist/system-state/index.js +7 -4
  229. package/dist/tab-bar/index.js +5 -2
  230. package/dist/tabs/index.js +4 -2
  231. package/dist/tags-input/index.js +10 -0
  232. package/dist/textarea/index.js +6 -4
  233. package/dist/thinking/index.js +3 -1
  234. package/dist/time-field/index.js +12 -0
  235. package/dist/time-range-control/index.js +22 -0
  236. package/dist/timeline/index.js +4 -2
  237. package/dist/toast/index.js +4 -2
  238. package/dist/toolbar/index.js +4 -2
  239. package/dist/tour/index.js +12 -9
  240. package/dist/truncation-notice/index.js +5 -2
  241. package/dist/update-notice/index.js +12 -9
  242. package/dist/video-player/index.js +5 -2
  243. package/dist/viewfinder/index.js +6 -4
  244. package/dist/widget/index.js +7 -4
  245. package/dist/wizard/index.js +7 -4
  246. package/package.json +13 -12
  247. package/dist/chunk-6N33LFQA.js +0 -35
  248. package/dist/chunk-GDKZTW34.js +0 -395
  249. package/dist/chunk-GL7B2DOW.js +0 -134
  250. package/dist/chunk-NKB7BZYK.js +0 -167
  251. package/dist/chunk-OETCUXQP.js +0 -134
  252. package/dist/chunk-OPXFZ4Y5.js +0 -204
  253. package/dist/chunk-Q72LJOVE.js +0 -169
  254. package/dist/chunk-RNGLIHFA.js +0 -191
  255. package/dist/chunk-RQ3HASCC.js +0 -6
  256. package/dist/chunk-RSOJT5YW.js +0 -124
  257. package/dist/chunk-TKVFVF5D.js +0 -95
  258. package/dist/chunk-XOSCY2CW.js +0 -242
  259. package/dist/header/index.js +0 -5
  260. package/dist/search-bar/index.js +0 -5
  261. /package/dist/{chunk-3ECPOSKO.js → chunk-3UG6JUCV.js} +0 -0
  262. /package/dist/{chunk-JRLTGLN4.js → chunk-5WWRTEPS.js} +0 -0
  263. /package/dist/{chunk-RTIKSY6A.js → chunk-5Z5ZYMOJ.js} +0 -0
@@ -1,35 +1,57 @@
1
- import { Skeleton } from './chunk-RIBDXGUG.js';
2
- import { Button } from './chunk-3ARE4TES.js';
3
- import { useResolvedMotion } from './chunk-6N33LFQA.js';
4
- import { Icon } from './chunk-TKVFVF5D.js';
1
+ import { Skeleton } from './chunk-PNF3NKB5.js';
2
+ import { Button } from './chunk-E2E3I5W2.js';
3
+ import { useLabels } from './chunk-APCWFOZW.js';
4
+ import { Icon } from './chunk-UXGIW7OK.js';
5
+ import { useResolvedMotion } from './chunk-J64KGCGX.js';
5
6
  import * as React from 'react';
6
7
  import { View, Text, Animated, Easing } from 'react-native';
7
8
  import { Svg, Path, Polyline, Circle, Line, Rect } from 'react-native-svg';
8
9
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
9
10
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
11
 
11
- var STATE_DEFAULTS = {
12
+ // src/charts/charts-labels.ts
13
+ var DEFAULT_CHARTS_LABELS = {
12
14
  emptyTitle: "No data",
13
15
  emptyMessage: "There is nothing to show for this range.",
14
16
  errorTitle: "Could not load this chart",
15
17
  errorMessage: "The data could not be loaded.",
16
- retryLabel: "Retry",
17
- loadingLabel: "Loading chart"
18
+ retry: "Retry",
19
+ loading: "Loading chart",
20
+ other: "Other",
21
+ lineChart: "Line chart",
22
+ barChart: "Bar chart",
23
+ donutChart: "DonutChart chart",
24
+ stackedBarChart: "Stacked bar chart",
25
+ noData: (kind) => kind + ", no data",
26
+ pointCount: (n) => n + " " + (n === 1 ? "point" : "points"),
27
+ span: (first, end) => first + " to " + end,
28
+ seriesSummary: (kind, span, points, min, max, last) => kind + (span ? ", " + span : "") + ", " + points + ", " + min + " to " + max + ", last " + last,
29
+ donutSummary: (kind, slices) => kind + ": " + slices,
30
+ donutSlice: (label, pct) => label + " " + pct + "%",
31
+ stackedSummary: (kind, names, columns) => kind + " of " + names + " across " + columns + " columns"
18
32
  };
19
33
  function ChartFrame({
20
34
  state = "data",
21
35
  width,
22
36
  height,
23
37
  compact = false,
24
- emptyTitle = STATE_DEFAULTS.emptyTitle,
25
- emptyMessage = STATE_DEFAULTS.emptyMessage,
26
- errorTitle = STATE_DEFAULTS.errorTitle,
27
- errorMessage = STATE_DEFAULTS.errorMessage,
28
- retryLabel = STATE_DEFAULTS.retryLabel,
29
- loadingLabel = STATE_DEFAULTS.loadingLabel,
38
+ emptyTitle: emptyTitleProp,
39
+ emptyMessage: emptyMessageProp,
40
+ errorTitle: errorTitleProp,
41
+ errorMessage: errorMessageProp,
42
+ retryLabel: retryLabelProp,
43
+ loadingLabel: loadingLabelProp,
44
+ labels: labelsProp,
30
45
  onRetry
31
46
  }) {
32
- const theme = useLoamTheme();
47
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
48
+ const emptyTitle = emptyTitleProp ?? labels.emptyTitle;
49
+ const emptyMessage = emptyMessageProp ?? labels.emptyMessage;
50
+ const errorTitle = errorTitleProp ?? labels.errorTitle;
51
+ const errorMessage = errorMessageProp ?? labels.errorMessage;
52
+ const retryLabel = retryLabelProp ?? labels.retry;
53
+ const loadingLabel = loadingLabelProp ?? labels.loading;
54
+ const theme = useLoamTheme("charts");
33
55
  const { styles } = useStyles(frameSheet);
34
56
  if (state === "data") return null;
35
57
  const box = { minWidth: width, minHeight: height };
@@ -112,15 +134,15 @@ function toneColors(theme, tone) {
112
134
  }
113
135
  }
114
136
  function useToneColors(tone) {
115
- return toneColors(useLoamTheme(), tone);
137
+ return toneColors(useLoamTheme("charts"), tone);
116
138
  }
117
139
  function clamp(n, lo, hi) {
118
140
  return Math.max(lo, Math.min(hi, n));
119
141
  }
120
142
  function useDrawIn(motion, animate) {
121
- const resolved = useResolvedMotion(motion ?? (animate ? "full" : "none"));
143
+ const resolved = useResolvedMotion(motion ?? (animate ? "full" : "none"), "charts");
122
144
  const on = resolved !== "none";
123
- const theme = useLoamTheme();
145
+ const theme = useLoamTheme("charts");
124
146
  const opacity = React.useRef(new Animated.Value(on ? 0 : 1)).current;
125
147
  React.useEffect(() => {
126
148
  if (!on) return;
@@ -136,6 +158,7 @@ function useDrawIn(motion, animate) {
136
158
  return opacity;
137
159
  }
138
160
  function Sparkline({
161
+ labels: labelsProp,
139
162
  data,
140
163
  width = 120,
141
164
  height = 32,
@@ -153,11 +176,13 @@ function Sparkline({
153
176
  retryLabel,
154
177
  loadingLabel,
155
178
  onRetry,
156
- accessibilityLabel = "Sparkline chart"
179
+ accessibilityLabel: labelProp
157
180
  }) {
181
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
158
182
  const { main, soft } = useToneColors(tone);
159
183
  const opacity = useDrawIn(motion, animate);
160
184
  const dotR = strokeWidth + 1.5;
185
+ const accessibilityLabel = labelProp ?? summarizeSeries(labels.lineChart, data, void 0, labels);
161
186
  const pad = Math.max(strokeWidth, showDot ? dotR : 0);
162
187
  const innerW = Math.max(0, width - pad * 2);
163
188
  const innerH = Math.max(0, height - pad * 2);
@@ -176,6 +201,7 @@ function Sparkline({
176
201
  return /* @__PURE__ */ jsx(
177
202
  ChartFrame,
178
203
  {
204
+ labels,
179
205
  compact: true,
180
206
  state,
181
207
  width,
@@ -214,6 +240,26 @@ function Sparkline({
214
240
  }
215
241
  );
216
242
  }
243
+ function spoken(n) {
244
+ return new Intl.NumberFormat("en", { notation: "compact", maximumFractionDigits: 1 }).format(n);
245
+ }
246
+ function summarizeSeries(kind, values, labels, copy = DEFAULT_CHARTS_LABELS) {
247
+ if (values.length === 0) return copy.noData(kind);
248
+ const min = Math.min(...values);
249
+ const max = Math.max(...values);
250
+ const last = values[values.length - 1];
251
+ const first = labels?.[0];
252
+ const end = labels?.[values.length - 1];
253
+ const span = first && end ? copy.span(first, end) : "";
254
+ return copy.seriesSummary(
255
+ kind,
256
+ span,
257
+ copy.pointCount(values.length),
258
+ spoken(min),
259
+ spoken(max),
260
+ spoken(last)
261
+ );
262
+ }
217
263
  function normalizeBars(data) {
218
264
  return data.map((d) => typeof d === "number" ? { value: d } : d);
219
265
  }
@@ -223,6 +269,7 @@ function topRoundedBar(x, y, w, h, r) {
223
269
  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`;
224
270
  }
225
271
  function BarChart({
272
+ labels: labelsProp,
226
273
  data,
227
274
  width = 140,
228
275
  height = 150,
@@ -232,11 +279,18 @@ function BarChart({
232
279
  highlightLast = true,
233
280
  highlightIndex,
234
281
  colors,
235
- accessibilityLabel = "Bar chart"
282
+ accessibilityLabel: labelProp
236
283
  }) {
237
- const theme = useLoamTheme();
284
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
285
+ const theme = useLoamTheme("charts");
238
286
  const { main, soft } = useToneColors(tone);
239
287
  const bars = normalizeBars(data);
288
+ const accessibilityLabel = labelProp ?? summarizeSeries(
289
+ labels.barChart,
290
+ bars.map((b) => b.value),
291
+ bars.map((b) => b.label),
292
+ labels
293
+ );
240
294
  const n = bars.length;
241
295
  const values = bars.map((b) => b.value);
242
296
  const max = n > 0 ? Math.max(...values, 0) : 0;
@@ -264,6 +318,7 @@ function BarChart({
264
318
  );
265
319
  }
266
320
  function RingChart({
321
+ labels: labelsProp,
267
322
  value,
268
323
  max = 100,
269
324
  size = 92,
@@ -272,7 +327,8 @@ function RingChart({
272
327
  label = false,
273
328
  accessibilityLabel
274
329
  }) {
275
- const theme = useLoamTheme();
330
+ useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
331
+ const theme = useLoamTheme("charts");
276
332
  const { main } = useToneColors(tone);
277
333
  const fraction = max > 0 ? clamp(value / max, 0, 1) : 0;
278
334
  const now = Math.round(fraction * 100);
@@ -349,8 +405,19 @@ function RingChart({
349
405
  );
350
406
  }
351
407
  var ringSvgStyle = { position: "absolute" };
352
- function Donut({
353
- data,
408
+ function foldDonutSlices(data, max, other) {
409
+ if (max <= 0 || data.length <= max) return data;
410
+ const keep = new Set(
411
+ data.map((d, i) => ({ v: d.value, i })).sort((a, b) => b.v - a.v).slice(0, max - 1).map((x) => x.i)
412
+ );
413
+ const rest = data.filter((_, i) => !keep.has(i)).reduce((a, d) => a + d.value, 0);
414
+ return [...data.filter((_, i) => keep.has(i)), { label: other, value: rest }];
415
+ }
416
+ function DonutChart({
417
+ labels: labelsProp,
418
+ data: rawData,
419
+ maxSlices = 5,
420
+ otherLabel: otherLabelProp,
354
421
  size = 140,
355
422
  thickness = 18,
356
423
  showLegend = true,
@@ -365,15 +432,23 @@ function Donut({
365
432
  retryLabel,
366
433
  loadingLabel,
367
434
  onRetry,
368
- accessibilityLabel = "Donut chart"
435
+ accessibilityLabel: labelProp
369
436
  }) {
370
- const theme = useLoamTheme();
437
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
438
+ const data = foldDonutSlices(rawData, maxSlices, otherLabelProp ?? labels.other);
439
+ const donutTotal = data.reduce((a, d) => a + d.value, 0);
440
+ const accessibilityLabel = labelProp ?? (data.length && donutTotal > 0 ? labels.donutSummary(
441
+ labels.donutChart,
442
+ data.map((d) => labels.donutSlice(d.label, Math.round(d.value / donutTotal * 100))).join(", ")
443
+ ) : labels.noData(labels.donutChart));
444
+ const theme = useLoamTheme("charts");
371
445
  const { styles } = useStyles(donutSheet);
372
446
  const opacity = useDrawIn(motion, animate);
373
447
  if (state !== "data") {
374
448
  return /* @__PURE__ */ jsx(
375
449
  ChartFrame,
376
450
  {
451
+ labels,
377
452
  state,
378
453
  width: size,
379
454
  height: size,
@@ -518,7 +593,8 @@ var donutSheet = createStyleSheet((theme) => ({
518
593
  color: theme.color.text2
519
594
  }
520
595
  }));
521
- function StackedBar({
596
+ function StackedBarChart({
597
+ labels: labelsProp,
522
598
  data,
523
599
  series,
524
600
  width = 280,
@@ -541,7 +617,8 @@ function StackedBar({
541
617
  onRetry,
542
618
  accessibilityLabel
543
619
  }) {
544
- const theme = useLoamTheme();
620
+ const labels = useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
621
+ const theme = useLoamTheme("charts");
545
622
  const { styles } = useStyles(stackedSheet);
546
623
  const opacity = useDrawIn(motion, animate);
547
624
  const palette = [
@@ -553,11 +630,16 @@ function StackedBar({
553
630
  theme.chart.c6
554
631
  ];
555
632
  const segColor = (i) => colors && colors.length > 0 ? colors[i % colors.length] : palette[i % palette.length];
556
- const label = accessibilityLabel ?? (series && series.length ? `Stacked bar chart of ${series.map((s) => s.label).join(", ")} across ${data.length} columns` : "Stacked bar chart");
633
+ const label = accessibilityLabel ?? (series && series.length ? labels.stackedSummary(
634
+ labels.stackedBarChart,
635
+ series.map((s) => s.label).join(", "),
636
+ data.length
637
+ ) : labels.stackedBarChart);
557
638
  if (state !== "data") {
558
639
  return /* @__PURE__ */ jsx(
559
640
  ChartFrame,
560
641
  {
642
+ labels,
561
643
  state,
562
644
  width,
563
645
  height,
@@ -649,6 +731,7 @@ var stackedSheet = createStyleSheet((theme) => ({
649
731
  }
650
732
  }));
651
733
  function StatCard({
734
+ labels: labelsProp,
652
735
  label,
653
736
  value,
654
737
  delta,
@@ -657,6 +740,7 @@ function StatCard({
657
740
  tone = "accent",
658
741
  accessibilityLabel
659
742
  }) {
743
+ useLabels("charts", DEFAULT_CHARTS_LABELS, labelsProp);
660
744
  const { styles } = useStyles(statSheet, { deltaTone });
661
745
  const [sparkW, setSparkW] = React.useState(0);
662
746
  const onSparkLayout = React.useCallback((e) => {
@@ -712,4 +796,4 @@ var statSheet = createStyleSheet((theme) => ({
712
796
  spark: { marginTop: "auto" }
713
797
  }));
714
798
 
715
- export { BarChart, ChartFrame, Donut, RingChart, Sparkline, StackedBar, StatCard };
799
+ export { BarChart, ChartFrame, DonutChart, RingChart, Sparkline, StackedBarChart, StatCard, foldDonutSlices };
@@ -1,25 +1,40 @@
1
1
  import { NO_UA_FOCUS_RING } from './chunk-3NMD74ZU.js';
2
- import { useResolvedMotion } from './chunk-6N33LFQA.js';
3
- import { Icon } from './chunk-TKVFVF5D.js';
2
+ import { announce } from './chunk-W23G6JLF.js';
3
+ import { useLabels } from './chunk-APCWFOZW.js';
4
+ import { Icon } from './chunk-UXGIW7OK.js';
5
+ import { useResolvedMotion } from './chunk-J64KGCGX.js';
4
6
  import * as React from 'react';
5
- import { View, TextInput, ScrollView, Text, Animated, Pressable, Easing } from 'react-native';
7
+ import { Platform, View, TextInput, Pressable, Text, ScrollView, Animated, Easing } from 'react-native';
6
8
  import { createStyleSheet, useStyles, useLoamTheme } from '@btndprojects/loam-theme-native';
7
9
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
10
 
9
11
  var LEADING_ICON = 18;
10
12
  var CANCEL_WIDTH = 52;
11
13
  var RECENTS_MAX_H = 120;
12
- function SearchBar({
14
+ var DEFAULT_LABELS = {
15
+ placeholder: "Search",
16
+ clear: "Clear search",
17
+ recent: "Recent",
18
+ noMatches: "No matches",
19
+ noMatchesFor: (query) => `No matches for "${query}"`,
20
+ tryRecent: "Try a recent search",
21
+ results: (count) => `${count} ${count === 1 ? "result" : "results"}`,
22
+ cancel: "Cancel"
23
+ };
24
+ function SearchField({
13
25
  data,
14
26
  recents = [],
15
27
  onSelect,
16
- placeholder = "Search",
28
+ placeholder: placeholderProp,
17
29
  value,
18
30
  defaultValue = "",
19
- onChangeText
31
+ onChangeText,
32
+ labels: labelsProp
20
33
  }) {
21
34
  const { styles } = useStyles(sheet);
22
- const theme = useLoamTheme();
35
+ const labels = useLabels("searchField", DEFAULT_LABELS, labelsProp);
36
+ const placeholder = placeholderProp ?? labels.placeholder;
37
+ const theme = useLoamTheme("search-field");
23
38
  const iconColor = theme.color.text3;
24
39
  const [focused, setFocused] = React.useState(false);
25
40
  const isControlled = value !== void 0;
@@ -29,6 +44,7 @@ function SearchBar({
29
44
  if (!isControlled) setInternal(text);
30
45
  onChangeText?.(text);
31
46
  };
47
+ const clear = () => handleChangeText("");
32
48
  const isEmpty = query.length === 0;
33
49
  const needle = query.toLowerCase();
34
50
  const matches = isEmpty ? [] : data.filter((item) => item.toLowerCase().includes(needle));
@@ -47,6 +63,12 @@ function SearchBar({
47
63
  },
48
64
  item
49
65
  );
66
+ const countText = isEmpty ? "" : matches.length === 0 ? labels.noMatches : labels.results(matches.length);
67
+ React.useEffect(() => {
68
+ if (Platform.OS === "web" || !countText) return;
69
+ const t = setTimeout(() => announce(countText), 600);
70
+ return () => clearTimeout(t);
71
+ }, [countText]);
50
72
  return /* @__PURE__ */ jsxs(View, { style: styles.container, children: [
51
73
  /* @__PURE__ */ jsxs(View, { style: [styles.field, focused ? styles.fieldFocused : null], children: [
52
74
  /* @__PURE__ */ jsx(Icon, { name: "search", size: LEADING_ICON, color: iconColor }),
@@ -59,33 +81,59 @@ function SearchBar({
59
81
  onFocus: () => setFocused(true),
60
82
  onBlur: () => setFocused(false),
61
83
  placeholder,
62
- placeholderTextColor: theme.color.text3
84
+ placeholderTextColor: theme.color.text3,
85
+ returnKeyType: "search",
86
+ ...Platform.OS === "web" ? { role: "searchbox" } : { accessibilityRole: "search" },
87
+ accessibilityLabel: placeholder,
88
+ onSubmitEditing: () => {
89
+ const top = matches[0];
90
+ if (top !== void 0) onSelect?.(top);
91
+ },
92
+ onKeyPress: (e) => {
93
+ if (e.nativeEvent.key === "Escape" && !isEmpty) clear();
94
+ }
95
+ }
96
+ ),
97
+ isEmpty ? null : /* @__PURE__ */ jsx(
98
+ Pressable,
99
+ {
100
+ accessibilityRole: "button",
101
+ accessibilityLabel: labels.clear,
102
+ onPress: clear,
103
+ hitSlop: Math.max(0, (theme.tapMin - theme.icon.sm) / 2),
104
+ children: /* @__PURE__ */ jsx(Icon, { name: "x", size: theme.icon.sm, color: iconColor })
63
105
  }
64
106
  )
65
107
  ] }),
108
+ Platform.OS === "web" ? /* @__PURE__ */ jsx(Text, { accessibilityLiveRegion: "polite", style: styles.liveCount, children: countText }) : null,
66
109
  /* @__PURE__ */ jsx(ScrollView, { style: styles.results, contentContainerStyle: styles.resultsContent, children: isEmpty ? /* @__PURE__ */ jsxs(Fragment, { children: [
67
- /* @__PURE__ */ jsx(Text, { style: styles.recentHeader, children: "Recent" }),
110
+ recents.length > 0 ? /* @__PURE__ */ jsx(Text, { style: styles.recentHeader, children: labels.recent }) : null,
68
111
  recents.map((item) => renderRow(item, "more-horizontal"))
69
- ] }) : matches.length > 0 ? matches.map((item) => renderRow(item, "search")) : /* @__PURE__ */ jsxs(Text, { style: styles.empty, children: [
70
- 'No matches for "',
71
- query,
72
- '"'
112
+ ] }) : matches.length > 0 ? matches.map((item) => renderRow(item, "search")) : /* @__PURE__ */ jsxs(Fragment, { children: [
113
+ /* @__PURE__ */ jsx(Text, { style: styles.empty, children: labels.noMatchesFor(query) }),
114
+ recents.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
115
+ /* @__PURE__ */ jsx(Text, { style: styles.recentHeader, children: labels.tryRecent }),
116
+ recents.map((item) => renderRow(item, "more-horizontal"))
117
+ ] }) : null
73
118
  ] }) })
74
119
  ] });
75
120
  }
76
- function SearchExpand({
121
+ function ExpandingSearchField({
77
122
  recents = [],
78
- placeholder = "Search",
123
+ placeholder: placeholderProp,
79
124
  value,
80
125
  defaultValue = "",
81
126
  onChangeText,
82
127
  onCancel,
83
128
  onSelectRecent,
84
- motion = "full"
129
+ motion = "full",
130
+ labels: labelsProp
85
131
  }) {
86
132
  const { styles: sx } = useStyles(expandSheet);
87
- const theme = useLoamTheme();
88
- const resolved = useResolvedMotion(motion);
133
+ const labels = useLabels("searchField", DEFAULT_LABELS, labelsProp);
134
+ const placeholder = placeholderProp ?? labels.placeholder;
135
+ const theme = useLoamTheme("search-field");
136
+ const resolved = useResolvedMotion(motion, "search-field");
89
137
  const animateTravel = resolved === "full";
90
138
  const animateFade = resolved !== "none";
91
139
  const isControlled = value !== void 0;
@@ -169,7 +217,8 @@ function SearchExpand({
169
217
  onBlur: handleBlur,
170
218
  placeholder,
171
219
  placeholderTextColor: theme.color.text3,
172
- returnKeyType: "search"
220
+ returnKeyType: "search",
221
+ accessibilityLabel: placeholder
173
222
  }
174
223
  ),
175
224
  /* @__PURE__ */ jsx(
@@ -180,14 +229,19 @@ function SearchExpand({
180
229
  overflow: "hidden",
181
230
  pointerEvents: focused ? "auto" : "none"
182
231
  },
232
+ accessibilityElementsHidden: !focused,
233
+ importantForAccessibility: focused ? "auto" : "no-hide-descendants",
234
+ ...focused ? null : { "aria-hidden": true },
183
235
  children: /* @__PURE__ */ jsx(Animated.View, { style: { opacity: cancelOpacity }, children: /* @__PURE__ */ jsx(
184
236
  Pressable,
185
237
  {
186
238
  accessibilityRole: "button",
187
- accessibilityLabel: "Cancel",
239
+ accessibilityLabel: labels.cancel,
240
+ focusable: focused,
241
+ tabIndex: focused ? 0 : -1,
188
242
  onPress: handleCancel,
189
243
  style: sx.cancelBtn,
190
- children: /* @__PURE__ */ jsx(Text, { style: sx.cancelText, children: "Cancel" })
244
+ children: /* @__PURE__ */ jsx(Text, { style: sx.cancelText, children: labels.cancel })
191
245
  }
192
246
  ) })
193
247
  }
@@ -206,11 +260,17 @@ function SearchExpand({
206
260
  pointerEvents: focused ? "auto" : "none"
207
261
  }
208
262
  ],
263
+ accessibilityElementsHidden: !focused,
264
+ importantForAccessibility: focused ? "auto" : "no-hide-descendants",
265
+ ...focused ? null : { "aria-hidden": true },
209
266
  children: /* @__PURE__ */ jsx(View, { style: sx.chipsRow, children: recents.map((label) => /* @__PURE__ */ jsxs(
210
267
  Pressable,
211
268
  {
212
269
  accessibilityRole: "button",
213
270
  accessibilityLabel: label,
271
+ focusable: focused,
272
+ tabIndex: focused ? 0 : -1,
273
+ hitSlop: { top: theme.space[6], bottom: theme.space[6] },
214
274
  onPress: () => handleChipPress(label),
215
275
  style: sx.chip,
216
276
  children: [
@@ -241,7 +301,7 @@ var sheet = createStyleSheet((theme) => ({
241
301
  borderWidth: theme.borderWidth.thick,
242
302
  borderColor: "transparent"
243
303
  },
244
- // Same focused treatment as `SearchExpand`: the two sit in the same product.
304
+ // Same focused treatment as `ExpandingSearchField`: the two sit in the same product.
245
305
  // The edge is the *measured* ring colour, not the raw
246
306
  // accent. `NO_UA_FOCUS_RING` removes the browser's own outline, so this edge
247
307
  // is the **only** focus affordance the field has — which makes it a focus
@@ -261,6 +321,7 @@ var sheet = createStyleSheet((theme) => ({
261
321
  backgroundColor: "transparent"
262
322
  },
263
323
  results: { alignSelf: "stretch" },
324
+ liveCount: { position: "absolute", width: 1, height: 1, opacity: 0, overflow: "hidden" },
264
325
  resultsContent: { gap: theme.space.s1 },
265
326
  recentHeader: {
266
327
  fontFamily: theme.font.mono,
@@ -391,4 +452,4 @@ var expandSheet = createStyleSheet((theme) => ({
391
452
  }
392
453
  }));
393
454
 
394
- export { SearchBar, SearchExpand };
455
+ export { ExpandingSearchField, SearchField };