@btndprojects/loam-ui-native 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/dist/accordion/index.js +5 -3
  2. package/dist/adaptive/index.js +6 -2
  3. package/dist/alert/index.js +5 -2
  4. package/dist/analyzer/index.js +9 -6
  5. package/dist/announcement/index.js +8 -5
  6. package/dist/audio-player/index.js +5 -3
  7. package/dist/avatar/index.js +5 -2
  8. package/dist/avatar-group/index.js +7 -3
  9. package/dist/badge/index.js +7 -4
  10. package/dist/banner/index.js +5 -2
  11. package/dist/board/index.js +11 -6
  12. package/dist/button/index.js +6 -3
  13. package/dist/camera-permission/index.js +15 -12
  14. package/dist/capture-result/index.js +19 -16
  15. package/dist/card/index.js +6 -3
  16. package/dist/card-form/index.js +12 -8
  17. package/dist/carousel/index.js +4 -2
  18. package/dist/chart/index.js +8 -5
  19. package/dist/charts/index.js +8 -6
  20. package/dist/chat/index.js +16 -0
  21. package/dist/checkbox/index.js +6 -4
  22. package/dist/checklist/index.js +11 -8
  23. package/dist/checkout/index.js +16 -11
  24. package/dist/chip/index.js +7 -4
  25. package/dist/{chunk-XNUVB5OL.js → chunk-2OLKPG4E.js} +92 -28
  26. package/dist/{chunk-RUZHTGKB.js → chunk-2PKYGLQ6.js} +71 -40
  27. package/dist/{chunk-UC2WGUP3.js → chunk-2SWKL3AJ.js} +91 -252
  28. package/dist/{chunk-AI4DWZCD.js → chunk-2SY63FCH.js} +63 -16
  29. package/dist/{chunk-F5XNPWS7.js → chunk-2TXERVVA.js} +92 -35
  30. package/dist/chunk-36EC2T6P.js +581 -0
  31. package/dist/chunk-3DUWIYV5.js +437 -0
  32. package/dist/{chunk-JNY4ZHAR.js → chunk-3QMEOFW5.js} +275 -71
  33. package/dist/chunk-3WEZCGHX.js +265 -0
  34. package/dist/chunk-46MMSDGL.js +194 -0
  35. package/dist/{chunk-7O2FMUPT.js → chunk-4IZXHVFJ.js} +297 -92
  36. package/dist/{chunk-LAECSR4H.js → chunk-5LAAAXFP.js} +14 -8
  37. package/dist/{chunk-2A5NIQAK.js → chunk-5RENVKBQ.js} +134 -46
  38. package/dist/{chunk-2ZZ7TDJ4.js → chunk-5UTRIXQ6.js} +37 -31
  39. package/dist/{chunk-LOE5YNN3.js → chunk-5VFZRGVD.js} +37 -10
  40. package/dist/{chunk-52X2VYTD.js → chunk-67IZZ2MJ.js} +115 -60
  41. package/dist/{chunk-UYG5L34B.js → chunk-6YAQBXB3.js} +10 -4
  42. package/dist/{chunk-BTTFCMKG.js → chunk-74FLKD24.js} +94 -23
  43. package/dist/{chunk-ITTYJZWX.js → chunk-7BUIKDD6.js} +73 -18
  44. package/dist/{chunk-423B7SPN.js → chunk-7OVVSVEZ.js} +273 -109
  45. package/dist/chunk-AEB7KCHQ.js +287 -0
  46. package/dist/chunk-APCWFOZW.js +28 -0
  47. package/dist/chunk-AWKQIE5I.js +139 -0
  48. package/dist/{chunk-VCDBXW5H.js → chunk-B7N4ASYE.js} +86 -42
  49. package/dist/{chunk-IVNRBPGC.js → chunk-C4GTDLRC.js} +104 -20
  50. package/dist/{chunk-4ZAHCY44.js → chunk-C6APNDVA.js} +12 -5
  51. package/dist/{chunk-4SZYY6AN.js → chunk-CMTVNF3D.js} +18 -13
  52. package/dist/{chunk-HZ6CNMAF.js → chunk-CPTOADB2.js} +151 -96
  53. package/dist/chunk-D5N5QWI7.js +1325 -0
  54. package/dist/{chunk-IIQTAY3J.js → chunk-DN7MNQIP.js} +113 -29
  55. package/dist/{chunk-47FWHGUN.js → chunk-DVGBZ3TX.js} +84 -23
  56. package/dist/chunk-DW3L54DQ.js +305 -0
  57. package/dist/{chunk-3ARE4TES.js → chunk-E2E3I5W2.js} +69 -18
  58. package/dist/{chunk-DHWADYZX.js → chunk-EDCBJV7J.js} +41 -28
  59. package/dist/{chunk-WSW6ZFAQ.js → chunk-ENP3BMZU.js} +4 -4
  60. package/dist/{chunk-OOPPQH27.js → chunk-EVOIGUBI.js} +43 -19
  61. package/dist/{chunk-VEAYTRPX.js → chunk-EY4DD67D.js} +165 -97
  62. package/dist/{chunk-223Q2T2Q.js → chunk-F3H33DQX.js} +132 -61
  63. package/dist/{chunk-CYRBHQQZ.js → chunk-F5B3UINI.js} +68 -35
  64. package/dist/{chunk-6X6PQ443.js → chunk-FAJI7BSC.js} +20 -9
  65. package/dist/{chunk-MOUJOP55.js → chunk-FUMHAAF3.js} +96 -29
  66. package/dist/{chunk-6HT2LP62.js → chunk-FV6HMP7W.js} +192 -73
  67. package/dist/{chunk-S7F6XLTK.js → chunk-FYWNRX4F.js} +76 -47
  68. package/dist/{chunk-YG3ZJHGU.js → chunk-FZGAAOKS.js} +30 -8
  69. package/dist/{chunk-YDGVJETP.js → chunk-G3AFC24V.js} +1 -1
  70. package/dist/{chunk-EJBDRVIH.js → chunk-G6UESEVN.js} +15 -8
  71. package/dist/chunk-GDKVKNR2.js +339 -0
  72. package/dist/chunk-GEIGMWNF.js +10 -0
  73. package/dist/{chunk-JUAMLEHX.js → chunk-H7DWSL4O.js} +24 -12
  74. package/dist/chunk-HJFFOOJ4.js +1 -0
  75. package/dist/{chunk-RW6ZL2FQ.js → chunk-HJLPZA4X.js} +106 -21
  76. package/dist/chunk-HYEOQWT7.js +647 -0
  77. package/dist/chunk-I2KLQ2HA.js +19 -0
  78. package/dist/{chunk-CJ5EOYZE.js → chunk-I4FHVKEC.js} +11 -5
  79. package/dist/{chunk-JNH2TYIN.js → chunk-IDM7JJMO.js} +19 -5
  80. package/dist/{chunk-O4AEHWII.js → chunk-IPUNJMAQ.js} +141 -49
  81. package/dist/{chunk-J7Q7VCVC.js → chunk-IT6FUXXG.js} +13 -6
  82. package/dist/{chunk-QJJ6MADV.js → chunk-IVKMZ7BB.js} +80 -28
  83. package/dist/{chunk-Z7H7VSFZ.js → chunk-IXKWIFWZ.js} +17 -6
  84. package/dist/chunk-J64KGCGX.js +55 -0
  85. package/dist/chunk-JBMLWFSJ.js +270 -0
  86. package/dist/{chunk-4BXMXBJO.js → chunk-JJLPBRVZ.js} +22 -11
  87. package/dist/chunk-JLC6PM5S.js +406 -0
  88. package/dist/chunk-JUYWSSKW.js +335 -0
  89. package/dist/{chunk-7CFF4HXS.js → chunk-JV5YOTOB.js} +49 -11
  90. package/dist/{chunk-LZLHELAG.js → chunk-KFJGFLMW.js} +29 -8
  91. package/dist/{chunk-O7AE6DAF.js → chunk-KQZ3GLHR.js} +18 -8
  92. package/dist/{chunk-N32RGOA5.js → chunk-LKFC4CS7.js} +80 -24
  93. package/dist/{chunk-YC6WORFL.js → chunk-LMPHCVJJ.js} +82 -50
  94. package/dist/{chunk-3WPW4KUN.js → chunk-LQP4KEXZ.js} +45 -13
  95. package/dist/{chunk-TKQYWZ5V.js → chunk-LUMVGO2K.js} +47 -31
  96. package/dist/{chunk-AWJOCGFZ.js → chunk-M656FYNH.js} +25 -13
  97. package/dist/{chunk-35OFI3JG.js → chunk-MKSNFG7H.js} +73 -20
  98. package/dist/{chunk-4GBOGOTV.js → chunk-NBEF4EPJ.js} +16 -6
  99. package/dist/chunk-NNCOFLNE.js +24 -0
  100. package/dist/{chunk-4YQOR7JM.js → chunk-NTQ2F3AU.js} +73 -20
  101. package/dist/{chunk-QCDXZBC5.js → chunk-O5V4TG3V.js} +126 -44
  102. package/dist/{chunk-U7TFM2JA.js → chunk-OJQUBQWA.js} +3 -3
  103. package/dist/{chunk-VQHPQEUH.js → chunk-OWAMM2DK.js} +13 -6
  104. package/dist/chunk-PID3NJB7.js +405 -0
  105. package/dist/{chunk-HET4LLMX.js → chunk-PMMTGBBS.js} +27 -17
  106. package/dist/{chunk-RIBDXGUG.js → chunk-PNF3NKB5.js} +49 -16
  107. package/dist/{chunk-JXJB2X6M.js → chunk-Q6NKEPRE.js} +81 -32
  108. package/dist/chunk-QDZGFXQD.js +176 -0
  109. package/dist/{chunk-SYNOJOQO.js → chunk-QEYFDRHR.js} +60 -26
  110. package/dist/{chunk-VBOXAEPI.js → chunk-QHAITQIF.js} +97 -22
  111. package/dist/{chunk-VXDZFJGP.js → chunk-QHTVYA65.js} +230 -76
  112. package/dist/{chunk-TUTI5HOZ.js → chunk-QIKT7LIB.js} +14 -8
  113. package/dist/{chunk-3ENTMPQY.js → chunk-QP3KMOVF.js} +82 -42
  114. package/dist/{chunk-GNNJ4GCC.js → chunk-QPWDDJJ4.js} +62 -148
  115. package/dist/{chunk-QWCMU5B2.js → chunk-QRUMA22E.js} +205 -80
  116. package/dist/{chunk-ZVFE5QGU.js → chunk-QYPE5JX3.js} +50 -10
  117. package/dist/{chunk-PUPM2YGF.js → chunk-ROCUG24E.js} +76 -36
  118. package/dist/{chunk-NQYBUO3K.js → chunk-RU3ZPNL6.js} +333 -142
  119. package/dist/{chunk-TOXAGRDQ.js → chunk-RXSCIO6W.js} +14 -5
  120. package/dist/{chunk-FMYDDECK.js → chunk-SATMR6SG.js} +631 -203
  121. package/dist/{chunk-4YIP3CWS.js → chunk-SHHY5OMK.js} +7 -5
  122. package/dist/chunk-SKWO3SZF.js +2284 -0
  123. package/dist/{chunk-YF4NSSMT.js → chunk-SWS5JQIF.js} +41 -13
  124. package/dist/{chunk-CUMUNPXY.js → chunk-T5LTPKX6.js} +15 -7
  125. package/dist/{chunk-H6NIOQHK.js → chunk-TDMG26JI.js} +26 -6
  126. package/dist/{chunk-UWFLYMAR.js → chunk-TLCIR6RG.js} +267 -126
  127. package/dist/{chunk-SBMNWWBV.js → chunk-TN2ZNJUI.js} +47 -9
  128. package/dist/{chunk-5YNTNN5A.js → chunk-TQVAIKFD.js} +106 -41
  129. package/dist/chunk-TRGFFU6A.js +1456 -0
  130. package/dist/{chunk-2GK6PHGE.js → chunk-TY4MTKQJ.js} +100 -22
  131. package/dist/{chunk-AZRX6SAC.js → chunk-U23FYWME.js} +15 -7
  132. package/dist/{chunk-PZXZJBMP.js → chunk-U5NLHYV6.js} +26 -12
  133. package/dist/chunk-UQEN55EY.js +1 -0
  134. package/dist/chunk-UQGBTPXH.js +218 -0
  135. package/dist/chunk-UXGIW7OK.js +116 -0
  136. package/dist/{chunk-PJXUJYS6.js → chunk-UYGDJWMN.js} +55 -30
  137. package/dist/{chunk-QDYDBCFP.js → chunk-V2OEB75Z.js} +50 -51
  138. package/dist/{chunk-LSS54GLJ.js → chunk-VAOAKWUK.js} +34 -13
  139. package/dist/{chunk-DM5QUKKO.js → chunk-VDPK5CY4.js} +18 -6
  140. package/dist/chunk-W23G6JLF.js +37 -0
  141. package/dist/{chunk-CDRZHT42.js → chunk-W63AJTM7.js} +276 -12
  142. package/dist/{chunk-XXXEFXY5.js → chunk-W74TXYFB.js} +13 -5
  143. package/dist/{chunk-LRJNDEIA.js → chunk-WRDSPUE7.js} +144 -29
  144. package/dist/{chunk-C2NTXVWM.js → chunk-XBZGDDMR.js} +11 -4
  145. package/dist/{chunk-BV3B2HYZ.js → chunk-XIDTBCBA.js} +189 -131
  146. package/dist/{chunk-YTFKPRUK.js → chunk-XN4KG3P4.js} +348 -153
  147. package/dist/chunk-XQXMLMH3.js +211 -0
  148. package/dist/{chunk-HPPW424V.js → chunk-XTORZWRF.js} +19 -8
  149. package/dist/{chunk-P23EQNRQ.js → chunk-YAAHPATV.js} +181 -30
  150. package/dist/{chunk-KMI5ML5I.js → chunk-YXOAPXMU.js} +57 -18
  151. package/dist/{chunk-RJQOOHT2.js → chunk-ZECZOOSB.js} +59 -28
  152. package/dist/{chunk-QKXCPTFS.js → chunk-ZLTO5VQI.js} +121 -31
  153. package/dist/{chunk-BEDBFJND.js → chunk-ZVATDZOM.js} +16 -18
  154. package/dist/coachmark/index.js +6 -3
  155. package/dist/code-block/index.js +5 -3
  156. package/dist/color-field/index.js +6 -4
  157. package/dist/commerce/index.js +19 -16
  158. package/dist/connectivity/index.js +5 -2
  159. package/dist/context-menu/index.js +5 -3
  160. package/dist/copy-button/index.js +4 -2
  161. package/dist/data-grid/index.js +21 -16
  162. package/dist/date-range-picker/index.js +11 -8
  163. package/dist/description-list/index.js +3 -1
  164. package/dist/dialog/index.js +4 -2
  165. package/dist/empty-state/index.js +4 -2
  166. package/dist/error-summary/index.js +4 -2
  167. package/dist/fab/index.js +5 -2
  168. package/dist/file-manager/index.js +28 -0
  169. package/dist/file-upload/index.js +10 -7
  170. package/dist/filter-bar/index.js +9 -6
  171. package/dist/flow-run/index.js +15 -12
  172. package/dist/form/index.js +5 -3
  173. package/dist/gallery/index.js +5 -2
  174. package/dist/hold-to-confirm/index.js +4 -2
  175. package/dist/index.d.ts +9557 -2985
  176. package/dist/index.js +355 -122
  177. package/dist/infinite-list/index.js +4 -2
  178. package/dist/inline-edit/index.js +6 -4
  179. package/dist/input/index.js +5 -3
  180. package/dist/interactions/index.js +2 -1
  181. package/dist/invoice/index.js +13 -9
  182. package/dist/kbd/index.js +5 -1
  183. package/dist/keyboard/index.js +4 -2
  184. package/dist/list-row/index.js +6 -4
  185. package/dist/log-viewer/index.js +4 -2
  186. package/dist/map-view/index.js +5 -3
  187. package/dist/markdown/index.js +9 -6
  188. package/dist/metric/index.js +7 -4
  189. package/dist/money/index.js +9 -3
  190. package/dist/nav-drawer/index.js +4 -2
  191. package/dist/nav-header/index.js +9 -0
  192. package/dist/navigation/index.js +5 -2
  193. package/dist/notification-center/index.js +12 -10
  194. package/dist/number-roll/index.js +5 -2
  195. package/dist/one-handed/index.js +5 -3
  196. package/dist/os-surfaces/index.js +6 -3
  197. package/dist/otp/index.js +7 -4
  198. package/dist/page-header/index.js +1 -0
  199. package/dist/pagination/index.js +6 -0
  200. package/dist/payment-method/index.js +14 -10
  201. package/dist/payment-status/index.js +17 -14
  202. package/dist/permission/index.js +5 -2
  203. package/dist/picker/index.js +11 -6
  204. package/dist/progress/index.js +6 -3
  205. package/dist/pull-to-refresh/index.js +4 -2
  206. package/dist/radio-group/index.js +6 -4
  207. package/dist/rating/index.js +5 -2
  208. package/dist/receivables/index.js +21 -16
  209. package/dist/refund/index.js +18 -14
  210. package/dist/save-status/index.js +5 -3
  211. package/dist/scroll-area/index.js +3 -1
  212. package/dist/search-field/index.js +8 -0
  213. package/dist/segmented-control/index.js +4 -3
  214. package/dist/sheet/index.js +5 -3
  215. package/dist/skeleton/index.js +3 -1
  216. package/dist/slider/index.js +4 -2
  217. package/dist/sortable/index.js +7 -0
  218. package/dist/spinner/index.js +3 -1
  219. package/dist/split-button/index.js +9 -6
  220. package/dist/spotlight/index.js +3 -1
  221. package/dist/stage-timeline/index.js +5 -3
  222. package/dist/status-dot/index.js +4 -2
  223. package/dist/stepper/index.js +7 -4
  224. package/dist/streaming-text/index.js +3 -2
  225. package/dist/survey/index.js +18 -15
  226. package/dist/switch/index.js +5 -3
  227. package/dist/system-state/index.js +7 -4
  228. package/dist/tab-bar/index.js +5 -2
  229. package/dist/tabs/index.js +4 -2
  230. package/dist/tags-input/index.js +10 -0
  231. package/dist/textarea/index.js +6 -4
  232. package/dist/thinking/index.js +3 -1
  233. package/dist/time-field/index.js +12 -0
  234. package/dist/time-range-control/index.js +22 -0
  235. package/dist/timeline/index.js +4 -2
  236. package/dist/toast/index.js +4 -2
  237. package/dist/toolbar/index.js +4 -2
  238. package/dist/tour/index.js +12 -9
  239. package/dist/truncation-notice/index.js +5 -2
  240. package/dist/update-notice/index.js +12 -9
  241. package/dist/video-player/index.js +5 -2
  242. package/dist/viewfinder/index.js +6 -4
  243. package/dist/widget/index.js +7 -4
  244. package/dist/wizard/index.js +7 -4
  245. package/package.json +13 -12
  246. package/dist/chunk-6N33LFQA.js +0 -35
  247. package/dist/chunk-GDKZTW34.js +0 -395
  248. package/dist/chunk-GL7B2DOW.js +0 -134
  249. package/dist/chunk-NKB7BZYK.js +0 -167
  250. package/dist/chunk-OETCUXQP.js +0 -134
  251. package/dist/chunk-OPXFZ4Y5.js +0 -204
  252. package/dist/chunk-Q72LJOVE.js +0 -169
  253. package/dist/chunk-RNGLIHFA.js +0 -191
  254. package/dist/chunk-RQ3HASCC.js +0 -6
  255. package/dist/chunk-RSOJT5YW.js +0 -124
  256. package/dist/chunk-TKVFVF5D.js +0 -95
  257. package/dist/chunk-XOSCY2CW.js +0 -242
  258. package/dist/header/index.js +0 -5
  259. package/dist/search-bar/index.js +0 -5
  260. /package/dist/{chunk-3ECPOSKO.js → chunk-3UG6JUCV.js} +0 -0
  261. /package/dist/{chunk-JRLTGLN4.js → chunk-5WWRTEPS.js} +0 -0
  262. /package/dist/{chunk-RTIKSY6A.js → chunk-5Z5ZYMOJ.js} +0 -0
@@ -1,9 +1,11 @@
1
1
  import { DRAG_CURSOR } from './chunk-KTAC4MGE.js';
2
- import { Input } from './chunk-ITTYJZWX.js';
2
+ import { Input } from './chunk-7BUIKDD6.js';
3
3
  import { haptics } from './chunk-NY2U3PBI.js';
4
+ import { useLabels } from './chunk-APCWFOZW.js';
5
+ import { Icon } from './chunk-UXGIW7OK.js';
4
6
  import * as React from 'react';
5
- import { PanResponder, View, StyleSheet } from 'react-native';
6
- import { Svg, Defs, LinearGradient, Stop, Rect } from 'react-native-svg';
7
+ import { PanResponder, View, StyleSheet, Pressable, Animated, Easing } from 'react-native';
8
+ import { Svg, Defs, LinearGradient, Stop, Rect, Pattern } from 'react-native-svg';
7
9
  import { createStyleSheet, useStyles, useLoamTheme } from '@btndprojects/loam-theme-native';
8
10
  import { jsxs, jsx } from 'react/jsx-runtime';
9
11
 
@@ -84,6 +86,30 @@ function hexToHsv(hex, prevHue) {
84
86
  if (hsv.s === 0) hsv.h = prevHue;
85
87
  return hsv;
86
88
  }
89
+ var DEFAULT_LABELS = {
90
+ saturationBrightness: "Saturation and brightness",
91
+ hue: "Hue",
92
+ opacity: "Opacity",
93
+ planeNamed: (name) => `${name}, saturation and brightness`,
94
+ hueNamed: (name) => `${name}, hue`,
95
+ opacityNamed: (name) => `${name}, opacity`,
96
+ planeValue: (s, v) => `Saturation ${s} percent, brightness ${v} percent`,
97
+ opacityValue: (pct) => `${pct}% opacity`,
98
+ hexColour: "Hex colour",
99
+ hexError: "Enter a 6-digit hex, like #4A7C59",
100
+ savedColours: "Saved colours",
101
+ useSaved: (hex) => `Use saved colour ${hex}`,
102
+ saveColour: "Save this colour"
103
+ };
104
+ var CHECK = 4;
105
+ function Checker({ id, dark }) {
106
+ const [a, b] = dark ? ["#000000", "#333333"] : ["#ffffff", "#e0e0e0"];
107
+ return /* @__PURE__ */ jsxs(Pattern, { id, width: CHECK * 2, height: CHECK * 2, patternUnits: "userSpaceOnUse", children: [
108
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: CHECK * 2, height: CHECK * 2, fill: a }),
109
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: CHECK, height: CHECK, fill: b }),
110
+ /* @__PURE__ */ jsx(Rect, { x: CHECK, y: CHECK, width: CHECK, height: CHECK, fill: b })
111
+ ] });
112
+ }
87
113
  function ColorField({
88
114
  value,
89
115
  defaultValue = "#4A7C59",
@@ -92,8 +118,16 @@ function ColorField({
92
118
  disabled = false,
93
119
  size = "md",
94
120
  accessibilityLabel,
95
- style
121
+ style,
122
+ savedColors,
123
+ onSavedColorsChange,
124
+ showAlpha = false,
125
+ alpha: alphaProp,
126
+ defaultAlpha = 1,
127
+ onAlphaChange,
128
+ labels: labelsProp
96
129
  }) {
130
+ const labels = useLabels("colorField", DEFAULT_LABELS, labelsProp);
97
131
  const isControlled = value !== void 0;
98
132
  const initialHsv = React.useMemo(
99
133
  () => hexToHsv(value ?? defaultValue, 0) ?? { h: 0, s: 0, v: 0 },
@@ -104,7 +138,7 @@ function ColorField({
104
138
  const [hsv, setHsv] = React.useState(initialHsv);
105
139
  const [hexText, setHexText] = React.useState(() => hsvToHex(initialHsv));
106
140
  const { styles } = useStyles(sheet, { size, disabled });
107
- const theme = useLoamTheme();
141
+ const theme = useLoamTheme("color-field");
108
142
  const hex = hsvToHex(hsv);
109
143
  const hueColor = hsvToHex({ h: hsv.h, s: 100, v: 100 });
110
144
  const planeRef = React.useRef(null);
@@ -116,6 +150,7 @@ function ColorField({
116
150
  const disabledRef = React.useRef(disabled);
117
151
  disabledRef.current = disabled;
118
152
  const editingHex = React.useRef(false);
153
+ const [hexTouched, setHexTouched] = React.useState(false);
119
154
  const [planeW, setPlaneW] = React.useState(0);
120
155
  const [hueW, setHueW] = React.useState(0);
121
156
  const commit = React.useCallback(
@@ -173,6 +208,32 @@ function ColorField({
173
208
  onPanResponderMove: (e) => hueFromX.current(e.nativeEvent.pageX)
174
209
  })
175
210
  ).current;
211
+ const nudge = (axis, key, big) => {
212
+ if (disabledRef.current) return false;
213
+ const step = big ? 10 : 1;
214
+ const cur = hsvRef.current;
215
+ if (axis === "plane") {
216
+ if (key === "ArrowRight") commit({ ...cur, s: clamp(cur.s + step, 0, 100) });
217
+ else if (key === "ArrowLeft") commit({ ...cur, s: clamp(cur.s - step, 0, 100) });
218
+ else if (key === "ArrowUp") commit({ ...cur, v: clamp(cur.v + step, 0, 100) });
219
+ else if (key === "ArrowDown") commit({ ...cur, v: clamp(cur.v - step, 0, 100) });
220
+ else return false;
221
+ return true;
222
+ }
223
+ if (key === "ArrowRight" || key === "ArrowUp") commit({ ...cur, h: clamp(cur.h + step, 0, 360) });
224
+ else if (key === "ArrowLeft" || key === "ArrowDown") commit({ ...cur, h: clamp(cur.h - step, 0, 360) });
225
+ else if (key === "Home") commit({ ...cur, h: 0 });
226
+ else if (key === "End") commit({ ...cur, h: 360 });
227
+ else return false;
228
+ return true;
229
+ };
230
+ const keyHandler = (axis) => (e) => {
231
+ if (nudge(axis, e.key, Boolean(e.shiftKey))) e.preventDefault?.();
232
+ };
233
+ const hueActions = [{ name: "increment" }, { name: "decrement" }];
234
+ const onHueAction = (e) => {
235
+ nudge("hue", e.nativeEvent.actionName === "increment" ? "ArrowRight" : "ArrowLeft", true);
236
+ };
176
237
  const onPlaneLayout = (e) => {
177
238
  const { width, height } = e.nativeEvent.layout;
178
239
  planeBox.current.w = width;
@@ -191,6 +252,74 @@ function ColorField({
191
252
  hueBox.current.x = x;
192
253
  });
193
254
  };
255
+ const alphaControlled = alphaProp !== void 0;
256
+ const [alphaInternal, setAlphaInternal] = React.useState(defaultAlpha);
257
+ const alpha = clamp(alphaControlled ? alphaProp : alphaInternal, 0, 1);
258
+ const alphaRefVal = React.useRef(alpha);
259
+ alphaRefVal.current = alpha;
260
+ const commitAlpha = React.useRef(() => {
261
+ });
262
+ commitAlpha.current = (next) => {
263
+ const a = clamp(Math.round(next * 100) / 100, 0, 1);
264
+ alphaRefVal.current = a;
265
+ if (!alphaControlled) setAlphaInternal(a);
266
+ onAlphaChange?.(a);
267
+ };
268
+ const alphaRef = React.useRef(null);
269
+ const alphaBox = React.useRef({ w: 0, x: 0 });
270
+ const [alphaW, setAlphaW] = React.useState(0);
271
+ const alphaFromX = (pageX) => {
272
+ const { w, x } = alphaBox.current;
273
+ if (w) commitAlpha.current((pageX - x) / w);
274
+ };
275
+ const alphaFromXRef = React.useRef(alphaFromX);
276
+ alphaFromXRef.current = alphaFromX;
277
+ const alphaPan = React.useRef(
278
+ PanResponder.create({
279
+ onStartShouldSetPanResponder: () => !disabledRef.current,
280
+ onMoveShouldSetPanResponder: () => !disabledRef.current,
281
+ onPanResponderGrant: (e) => {
282
+ haptics.impact("light");
283
+ alphaFromXRef.current(e.nativeEvent.pageX);
284
+ },
285
+ onPanResponderMove: (e) => alphaFromXRef.current(e.nativeEvent.pageX)
286
+ })
287
+ ).current;
288
+ const onAlphaLayout = (e) => {
289
+ const { width } = e.nativeEvent.layout;
290
+ alphaBox.current.w = width;
291
+ setAlphaW(width);
292
+ alphaRef.current?.measureInWindow?.((x) => {
293
+ alphaBox.current.x = x;
294
+ });
295
+ };
296
+ const onAlphaKey = (e) => {
297
+ if (disabledRef.current) return;
298
+ const step = e.shiftKey ? 0.1 : 0.01;
299
+ const cur = alphaRefVal.current;
300
+ let next;
301
+ if (e.key === "ArrowRight" || e.key === "ArrowUp") next = cur + step;
302
+ else if (e.key === "ArrowLeft" || e.key === "ArrowDown") next = cur - step;
303
+ else if (e.key === "Home") next = 0;
304
+ else if (e.key === "End") next = 1;
305
+ else return;
306
+ e.preventDefault?.();
307
+ commitAlpha.current(next);
308
+ };
309
+ const onAlphaAction = (e) => {
310
+ if (disabledRef.current) return;
311
+ commitAlpha.current(alphaRefVal.current + (e.nativeEvent.actionName === "increment" ? 0.1 : -0.1));
312
+ };
313
+ const saveCurrent = () => {
314
+ const key = hex.toUpperCase();
315
+ const rest = (savedColors ?? []).filter((c) => c.toUpperCase() !== key);
316
+ onSavedColorsChange?.([key, ...rest]);
317
+ };
318
+ const pickSaved = (c) => {
319
+ if (disabled) return;
320
+ const next = hexToHsv(c, hsvRef.current.h);
321
+ if (next) commit(next);
322
+ };
194
323
  const onHexChange = (text) => {
195
324
  setHexText(text);
196
325
  const next = hexToHsv(text, hsvRef.current.h);
@@ -201,6 +330,7 @@ function ColorField({
201
330
  const planeThumbY = (1 - hsv.v / 100) * geo.plane - geo.thumb / 2;
202
331
  const hueThumbX = hsv.h / 360 * hueW - geo.thumb / 2;
203
332
  const hexValid = normalizeHex(hexText) !== null;
333
+ const hexError = !hexValid && (hexTouched || !/^\s*#?[0-9a-fA-F]{0,6}\s*$/.test(hexText));
204
334
  return /* @__PURE__ */ jsxs(View, { style: [styles.wrap, style], children: [
205
335
  /* @__PURE__ */ jsxs(
206
336
  View,
@@ -208,17 +338,18 @@ function ColorField({
208
338
  ref: planeRef,
209
339
  onLayout: onPlaneLayout,
210
340
  accessibilityRole: "adjustable",
211
- accessibilityLabel: accessibilityLabel ? `${accessibilityLabel}, saturation and brightness` : "Saturation and brightness",
341
+ accessibilityLabel: accessibilityLabel ? labels.planeNamed(accessibilityLabel) : labels.saturationBrightness,
212
342
  accessibilityValue: {
213
- text: `Saturation ${Math.round(hsv.s)} percent, brightness ${Math.round(hsv.v)} percent`
343
+ text: labels.planeValue(Math.round(hsv.s), Math.round(hsv.v))
214
344
  },
215
345
  accessibilityState: { disabled },
216
346
  "aria-valuemin": 0,
217
347
  "aria-valuemax": 100,
218
348
  "aria-valuenow": Math.round(hsv.v),
219
- "aria-valuetext": `Saturation ${Math.round(hsv.s)} percent, brightness ${Math.round(hsv.v)} percent`,
349
+ "aria-valuetext": labels.planeValue(Math.round(hsv.s), Math.round(hsv.v)),
220
350
  style: [styles.plane, !disabled && DRAG_CURSOR],
221
351
  ...disabled ? {} : planePan.panHandlers,
352
+ ...{ tabIndex: disabled ? -1 : 0, onKeyDown: keyHandler("plane") },
222
353
  children: [
223
354
  planeW > 0 ? /* @__PURE__ */ jsxs(Svg, { width: planeW, height: geo.plane, style: StyleSheet.absoluteFill, children: [
224
355
  /* @__PURE__ */ jsxs(Defs, { children: [
@@ -253,14 +384,17 @@ function ColorField({
253
384
  ref: hueRef,
254
385
  onLayout: onHueLayout,
255
386
  accessibilityRole: "adjustable",
256
- accessibilityLabel: accessibilityLabel ? `${accessibilityLabel}, hue` : "Hue",
387
+ accessibilityLabel: accessibilityLabel ? labels.hueNamed(accessibilityLabel) : labels.hue,
257
388
  accessibilityValue: { min: 0, max: 360, now: Math.round(hsv.h) },
258
389
  accessibilityState: { disabled },
259
390
  "aria-valuemin": 0,
260
391
  "aria-valuemax": 360,
261
392
  "aria-valuenow": Math.round(hsv.h),
393
+ accessibilityActions: hueActions,
394
+ onAccessibilityAction: onHueAction,
262
395
  style: [styles.hue, !disabled && DRAG_CURSOR],
263
396
  ...disabled ? {} : huePan.panHandlers,
397
+ ...{ tabIndex: disabled ? -1 : 0, onKeyDown: keyHandler("hue") },
264
398
  children: [
265
399
  hueW > 0 ? /* @__PURE__ */ jsxs(Svg, { width: hueW, height: geo.hue, style: StyleSheet.absoluteFill, children: [
266
400
  /* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsxs(LinearGradient, { id: "loam-cf-hue", x1: "0", y1: "0", x2: "1", y2: "0", children: [
@@ -288,8 +422,55 @@ function ColorField({
288
422
  ]
289
423
  }
290
424
  ),
425
+ showAlpha ? /* @__PURE__ */ jsxs(
426
+ View,
427
+ {
428
+ ref: alphaRef,
429
+ onLayout: onAlphaLayout,
430
+ accessibilityRole: "adjustable",
431
+ accessibilityLabel: accessibilityLabel ? labels.opacityNamed(accessibilityLabel) : labels.opacity,
432
+ accessibilityValue: { min: 0, max: 100, now: Math.round(alpha * 100), text: labels.opacityValue(Math.round(alpha * 100)) },
433
+ accessibilityState: { disabled },
434
+ "aria-valuemin": 0,
435
+ "aria-valuemax": 100,
436
+ "aria-valuenow": Math.round(alpha * 100),
437
+ "aria-valuetext": labels.opacityValue(Math.round(alpha * 100)),
438
+ accessibilityActions: hueActions,
439
+ onAccessibilityAction: onAlphaAction,
440
+ style: [styles.hue, !disabled && DRAG_CURSOR],
441
+ ...disabled ? {} : alphaPan.panHandlers,
442
+ ...{ tabIndex: disabled ? -1 : 0, onKeyDown: onAlphaKey },
443
+ children: [
444
+ alphaW > 0 ? /* @__PURE__ */ jsxs(Svg, { width: alphaW, height: geo.hue, style: StyleSheet.absoluteFill, children: [
445
+ /* @__PURE__ */ jsxs(Defs, { children: [
446
+ /* @__PURE__ */ jsx(Checker, { id: "loam-cf-check" }),
447
+ /* @__PURE__ */ jsxs(LinearGradient, { id: "loam-cf-alpha", x1: "0", y1: "0", x2: "1", y2: "0", children: [
448
+ /* @__PURE__ */ jsx(Stop, { offset: "0", stopColor: hex, stopOpacity: 0 }),
449
+ /* @__PURE__ */ jsx(Stop, { offset: "1", stopColor: hex, stopOpacity: 1 })
450
+ ] })
451
+ ] }),
452
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: alphaW, height: geo.hue, rx: geo.hue / 2, fill: "url(#loam-cf-check)" }),
453
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: alphaW, height: geo.hue, rx: geo.hue / 2, fill: "url(#loam-cf-alpha)" })
454
+ ] }) : null,
455
+ /* @__PURE__ */ jsx(
456
+ View,
457
+ {
458
+ style: [
459
+ styles.thumb,
460
+ styles.hueThumb,
461
+ { transform: [{ translateX: alpha * alphaW - geo.thumb / 2 }] }
462
+ ]
463
+ }
464
+ )
465
+ ]
466
+ }
467
+ ) : null,
291
468
  showInput ? /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
292
- /* @__PURE__ */ jsx(View, { style: [styles.preview, { backgroundColor: hex }] }),
469
+ showAlpha ? /* @__PURE__ */ jsx(View, { style: [styles.preview, styles.alphaPreview], testID: "color-field-alpha-preview", children: [false, true].map((dark) => /* @__PURE__ */ jsxs(Svg, { width: "50%", height: "100%", children: [
470
+ /* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsx(Checker, { id: dark ? "loam-cf-pd" : "loam-cf-pl", dark }) }),
471
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: "100%", height: "100%", fill: `url(#${dark ? "loam-cf-pd" : "loam-cf-pl"})` }),
472
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: "100%", height: "100%", fill: hex, fillOpacity: alpha })
473
+ ] }, String(dark))) }) : /* @__PURE__ */ jsx(PreviewSwatch, { color: hex, style: styles.preview }),
293
474
  /* @__PURE__ */ jsx(View, { style: styles.inputWrap, children: /* @__PURE__ */ jsx(
294
475
  Input,
295
476
  {
@@ -300,6 +481,7 @@ function ColorField({
300
481
  },
301
482
  onBlur: () => {
302
483
  editingHex.current = false;
484
+ setHexTouched(true);
303
485
  setHexText(hex);
304
486
  },
305
487
  editable: !disabled,
@@ -307,16 +489,74 @@ function ColorField({
307
489
  autoCorrect: false,
308
490
  maxLength: 7,
309
491
  size: size === "sm" ? "sm" : "md",
310
- validationState: hexValid ? "default" : "invalid",
492
+ validationState: hexError ? "invalid" : "default",
493
+ message: hexError ? labels.hexError : void 0,
311
494
  showStatusIcon: false,
312
- accessibilityLabel: "Hex colour",
495
+ accessibilityLabel: labels.hexColour,
313
496
  style: { fontFamily: theme.font.mono }
314
497
  }
315
498
  ) })
499
+ ] }) : null,
500
+ savedColors || onSavedColorsChange ? /* @__PURE__ */ jsxs(View, { accessibilityRole: "group", accessibilityLabel: labels.savedColours, style: styles.saved, children: [
501
+ (savedColors ?? []).map((c) => /* @__PURE__ */ jsx(
502
+ Pressable,
503
+ {
504
+ accessibilityRole: "button",
505
+ accessibilityLabel: labels.useSaved(c.toUpperCase()),
506
+ accessibilityState: { disabled },
507
+ disabled,
508
+ onPress: () => pickSaved(c),
509
+ hitSlop: theme.space[4],
510
+ style: [styles.swatch, { backgroundColor: c }]
511
+ },
512
+ c
513
+ )),
514
+ onSavedColorsChange ? (
515
+ // A swatch-sized slot rather than a 30px button, so the row reads
516
+ // as one strip of equal squares with the next free slot at its end.
517
+ /* @__PURE__ */ jsx(
518
+ Pressable,
519
+ {
520
+ accessibilityRole: "button",
521
+ accessibilityLabel: labels.saveColour,
522
+ accessibilityState: { disabled },
523
+ disabled,
524
+ onPress: saveCurrent,
525
+ hitSlop: theme.space[4],
526
+ style: ({ pressed }) => [
527
+ styles.swatch,
528
+ styles.saveSlot,
529
+ pressed ? { backgroundColor: theme.state.pressed } : null,
530
+ disabled ? { opacity: theme.state.disabledOpacity } : null
531
+ ],
532
+ children: /* @__PURE__ */ jsx(Icon, { name: "plus", size: 14, color: theme.color.text2 })
533
+ }
534
+ )
535
+ ) : null
316
536
  ] }) : null
317
537
  ] });
318
538
  }
319
539
  var HEAVY_SHADOW_RATIO = 1.2;
540
+ function PreviewSwatch({ color, style }) {
541
+ const theme = useLoamTheme("color-field");
542
+ const progress = React.useRef(new Animated.Value(1)).current;
543
+ const [range, setRange] = React.useState([color, color]);
544
+ React.useEffect(() => {
545
+ setRange((prev) => prev[1] === color ? prev : [prev[1], color]);
546
+ }, [color]);
547
+ React.useEffect(() => {
548
+ if (range[0] === range[1]) return;
549
+ progress.setValue(0);
550
+ Animated.timing(progress, {
551
+ toValue: 1,
552
+ duration: theme.spring.fe.duration,
553
+ easing: Easing.out(Easing.quad),
554
+ useNativeDriver: false
555
+ }).start();
556
+ }, [range, progress, theme.spring.fe.duration]);
557
+ const backgroundColor = progress.interpolate({ inputRange: [0, 1], outputRange: range });
558
+ return /* @__PURE__ */ jsx(Animated.View, { style: [style, { backgroundColor }] });
559
+ }
320
560
  var sheet = createStyleSheet((theme) => ({
321
561
  // The per-size `width` is the picker's preferred measure: a plane a little wider
322
562
  // than it is tall, which also leaves the swatch and the hex field a line they
@@ -418,6 +658,30 @@ var sheet = createStyleSheet((theme) => ({
418
658
  },
419
659
  inputWrap: {
420
660
  flex: 1
661
+ },
662
+ // Light and dark checker halves side by side, clipped to the swatch shape.
663
+ alphaPreview: {
664
+ flexDirection: "row",
665
+ overflow: "hidden"
666
+ },
667
+ saved: {
668
+ flexDirection: "row",
669
+ flexWrap: "wrap",
670
+ alignItems: "center",
671
+ gap: theme.space.s1
672
+ },
673
+ swatch: {
674
+ width: theme.space[24],
675
+ height: theme.space[24],
676
+ borderRadius: theme.radius.sm,
677
+ borderWidth: theme.borderWidth.base,
678
+ borderColor: theme.color.border
679
+ },
680
+ saveSlot: {
681
+ alignItems: "center",
682
+ justifyContent: "center",
683
+ borderStyle: "dashed",
684
+ borderColor: theme.color.borderStrong
421
685
  }
422
686
  }));
423
687
 
@@ -1,12 +1,16 @@
1
+ import { useLabels } from './chunk-APCWFOZW.js';
1
2
  import * as React from 'react';
2
3
  import { Animated, Easing, View, Text } from 'react-native';
3
4
  import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
4
5
  import { jsxs, jsx } from 'react/jsx-runtime';
5
6
 
6
- // src/thinking/thinking.tsx
7
+ var DEFAULT_LABELS = {
8
+ label: "Thinking\u2026",
9
+ accessibleLabel: "Thinking"
10
+ };
7
11
  var DOT_BOX = { sm: 6, md: 8, lg: 10 };
8
12
  function useThinkingPulse(active) {
9
- const theme = useLoamTheme();
13
+ const theme = useLoamTheme("thinking");
10
14
  const p = React.useRef(new Animated.Value(0)).current;
11
15
  const { duration, easing } = theme.motion.loop;
12
16
  React.useEffect(() => {
@@ -30,17 +34,21 @@ function useThinkingPulse(active) {
30
34
  } : null;
31
35
  }
32
36
  function Thinking({
33
- label = "Thinking\u2026",
37
+ label: labelProp,
34
38
  size = "md",
35
39
  tone = "working",
36
40
  motion = "full",
37
41
  announce = true,
38
- accessibleLabel = "Thinking",
42
+ accessibleLabel: accessibleLabelProp,
43
+ labels: labelsProp,
39
44
  style,
40
45
  testID
41
46
  }) {
47
+ const labels = useLabels("thinking", DEFAULT_LABELS, labelsProp);
48
+ const label = labelProp ?? labels.label;
49
+ const accessibleLabel = accessibleLabelProp ?? labels.accessibleLabel;
42
50
  const { styles } = useStyles(sheet, { tone, size });
43
- const theme = useLoamTheme();
51
+ const theme = useLoamTheme("thinking");
44
52
  const pulseStyle = useThinkingPulse(motion === "full" && !theme.reduceMotion);
45
53
  const hasLabel = label !== "";
46
54
  const box = DOT_BOX[size];