@unif/react-native-design 0.8.1 → 0.9.0

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 (512) hide show
  1. package/README.md +3 -4
  2. package/lib/module/components/business/AvatarWithRing/AvatarWithRing.js +6 -4
  3. package/lib/module/components/business/AvatarWithRing/AvatarWithRing.js.map +1 -1
  4. package/lib/module/components/business/AvatarWithRing/styles.js +15 -3
  5. package/lib/module/components/business/AvatarWithRing/styles.js.map +1 -1
  6. package/lib/module/components/business/Decorations/GradientWash.js +50 -36
  7. package/lib/module/components/business/Decorations/GradientWash.js.map +1 -1
  8. package/lib/module/components/business/Decorations/RadialHalo.js +10 -4
  9. package/lib/module/components/business/Decorations/RadialHalo.js.map +1 -1
  10. package/lib/module/components/business/Decorations/ScreenBackdrop.js +22 -14
  11. package/lib/module/components/business/Decorations/ScreenBackdrop.js.map +1 -1
  12. package/lib/module/components/business/Decorations/index.js +3 -0
  13. package/lib/module/components/business/Decorations/index.js.map +1 -1
  14. package/lib/module/components/business/GlassStats/GlassStats.js +7 -4
  15. package/lib/module/components/business/GlassStats/GlassStats.js.map +1 -1
  16. package/lib/module/components/business/GlassStats/types.js +2 -0
  17. package/lib/module/components/business/VersionPill/VersionPill.js +23 -5
  18. package/lib/module/components/business/VersionPill/VersionPill.js.map +1 -1
  19. package/lib/module/components/business/VersionPill/styles.js +1 -1
  20. package/lib/module/components/business/index.js.map +1 -1
  21. package/lib/module/components/business/useSvgId.js +20 -0
  22. package/lib/module/components/business/useSvgId.js.map +1 -0
  23. package/lib/module/components/ui/Avatar/Avatar.js +13 -8
  24. package/lib/module/components/ui/Avatar/Avatar.js.map +1 -1
  25. package/lib/module/components/ui/Avatar/styles.js +7 -7
  26. package/lib/module/components/ui/Avatar/styles.js.map +1 -1
  27. package/lib/module/components/ui/BlurLayer/BlurLayer.js +5 -1
  28. package/lib/module/components/ui/BlurLayer/BlurLayer.js.map +1 -1
  29. package/lib/module/components/ui/BlurLayer/BlurLayer.web.js +7 -1
  30. package/lib/module/components/ui/BlurLayer/BlurLayer.web.js.map +1 -1
  31. package/lib/module/components/ui/Button/Button.js +2 -1
  32. package/lib/module/components/ui/Button/Button.js.map +1 -1
  33. package/lib/module/components/ui/Button/ButtonBase.js +36 -2
  34. package/lib/module/components/ui/Button/ButtonBase.js.map +1 -1
  35. package/lib/module/components/ui/Button/styles.js +27 -25
  36. package/lib/module/components/ui/Button/styles.js.map +1 -1
  37. package/lib/module/components/ui/Card/Card.js +17 -8
  38. package/lib/module/components/ui/Card/Card.js.map +1 -1
  39. package/lib/module/components/ui/Card/styles.js +6 -1
  40. package/lib/module/components/ui/Card/styles.js.map +1 -1
  41. package/lib/module/components/ui/Carousel/Carousel.js +36 -6
  42. package/lib/module/components/ui/Carousel/Carousel.js.map +1 -1
  43. package/lib/module/components/ui/Cell/Cell.js +23 -5
  44. package/lib/module/components/ui/Cell/Cell.js.map +1 -1
  45. package/lib/module/components/ui/Cell/Leading.js +2 -2
  46. package/lib/module/components/ui/Cell/Leading.js.map +1 -1
  47. package/lib/module/components/ui/Cell/List.js +10 -5
  48. package/lib/module/components/ui/Cell/List.js.map +1 -1
  49. package/lib/module/components/ui/Cell/styles.js +7 -6
  50. package/lib/module/components/ui/Cell/styles.js.map +1 -1
  51. package/lib/module/components/ui/Checkbox/Checkbox.js +10 -8
  52. package/lib/module/components/ui/Checkbox/Checkbox.js.map +1 -1
  53. package/lib/module/components/ui/Checkbox/styles.js +9 -1
  54. package/lib/module/components/ui/Checkbox/styles.js.map +1 -1
  55. package/lib/module/components/ui/Chip/Chip.js +19 -5
  56. package/lib/module/components/ui/Chip/Chip.js.map +1 -1
  57. package/lib/module/components/ui/Confirm/ConfirmHost.js +28 -11
  58. package/lib/module/components/ui/Confirm/ConfirmHost.js.map +1 -1
  59. package/lib/module/components/ui/Confirm/confirm.js +6 -0
  60. package/lib/module/components/ui/Confirm/confirm.js.map +1 -1
  61. package/lib/module/components/ui/DrawerHeader/DrawerHeader.js +14 -9
  62. package/lib/module/components/ui/DrawerHeader/DrawerHeader.js.map +1 -1
  63. package/lib/module/components/ui/DrawerHeader/styles.js +10 -6
  64. package/lib/module/components/ui/DrawerHeader/styles.js.map +1 -1
  65. package/lib/module/components/ui/Empty/Empty.js +5 -4
  66. package/lib/module/components/ui/Empty/Empty.js.map +1 -1
  67. package/lib/module/components/ui/EntryCard/EntryCard.js +5 -3
  68. package/lib/module/components/ui/EntryCard/EntryCard.js.map +1 -1
  69. package/lib/module/components/ui/EntryCard/styles.js +4 -4
  70. package/lib/module/components/ui/EntryCard/styles.js.map +1 -1
  71. package/lib/module/components/ui/Form/FormRow.js +1 -0
  72. package/lib/module/components/ui/Form/FormRow.js.map +1 -1
  73. package/lib/module/components/ui/Form/styles.js +3 -1
  74. package/lib/module/components/ui/Form/styles.js.map +1 -1
  75. package/lib/module/components/ui/Grid/Grid.js +39 -24
  76. package/lib/module/components/ui/Grid/Grid.js.map +1 -1
  77. package/lib/module/components/ui/Grid/styles.js +35 -46
  78. package/lib/module/components/ui/Grid/styles.js.map +1 -1
  79. package/lib/module/components/ui/Icon/Icon.js +46 -29
  80. package/lib/module/components/ui/Icon/Icon.js.map +1 -1
  81. package/lib/module/components/ui/IconButton/IconButton.js +2 -0
  82. package/lib/module/components/ui/IconButton/IconButton.js.map +1 -1
  83. package/lib/module/components/ui/Logo/Logo.js +2 -1
  84. package/lib/module/components/ui/Logo/Logo.js.map +1 -1
  85. package/lib/module/components/ui/NavBar/NavBar.js +15 -3
  86. package/lib/module/components/ui/NavBar/NavBar.js.map +1 -1
  87. package/lib/module/components/ui/PasswordInput/PasswordInput.js +43 -14
  88. package/lib/module/components/ui/PasswordInput/PasswordInput.js.map +1 -1
  89. package/lib/module/components/ui/PasswordInput/styles.js +1 -1
  90. package/lib/module/components/ui/Pulse/Pulse.js +2 -1
  91. package/lib/module/components/ui/Pulse/Pulse.js.map +1 -1
  92. package/lib/module/components/ui/Pulse/PulseDot.js +8 -10
  93. package/lib/module/components/ui/Pulse/PulseDot.js.map +1 -1
  94. package/lib/module/components/ui/Pulse/types.js +2 -0
  95. package/lib/module/components/ui/Pulse/usePulse.web.js +51 -30
  96. package/lib/module/components/ui/Pulse/usePulse.web.js.map +1 -1
  97. package/lib/module/components/ui/Radio/Radio.js +19 -5
  98. package/lib/module/components/ui/Radio/Radio.js.map +1 -1
  99. package/lib/module/components/ui/Radio/RadioGroup.js +10 -6
  100. package/lib/module/components/ui/Radio/RadioGroup.js.map +1 -1
  101. package/lib/module/components/ui/Radio/styles.js +10 -3
  102. package/lib/module/components/ui/Radio/styles.js.map +1 -1
  103. package/lib/module/components/ui/Reveal/Reveal.web.js +18 -3
  104. package/lib/module/components/ui/Reveal/Reveal.web.js.map +1 -1
  105. package/lib/module/components/ui/Search/Search.js +26 -10
  106. package/lib/module/components/ui/Search/Search.js.map +1 -1
  107. package/lib/module/components/ui/Segmented/Segmented.js +40 -30
  108. package/lib/module/components/ui/Segmented/Segmented.js.map +1 -1
  109. package/lib/module/components/ui/Segmented/styles.js +4 -2
  110. package/lib/module/components/ui/Segmented/styles.js.map +1 -1
  111. package/lib/module/components/ui/Skeleton/Skeleton.js +9 -8
  112. package/lib/module/components/ui/Skeleton/Skeleton.js.map +1 -1
  113. package/lib/module/components/ui/Spinner/Spinner.js +15 -16
  114. package/lib/module/components/ui/Spinner/Spinner.js.map +1 -1
  115. package/lib/module/components/ui/Spinner/Spinner.web.js +10 -14
  116. package/lib/module/components/ui/Spinner/Spinner.web.js.map +1 -1
  117. package/lib/module/components/ui/Spinner/shared.js +31 -0
  118. package/lib/module/components/ui/Spinner/shared.js.map +1 -0
  119. package/lib/module/components/ui/StatusDot/StatusDot.js +21 -4
  120. package/lib/module/components/ui/StatusDot/StatusDot.js.map +1 -1
  121. package/lib/module/components/ui/StatusDot/styles.js +1 -1
  122. package/lib/module/components/ui/StatusDot/types.js +2 -0
  123. package/lib/module/components/ui/Stepper/Stepper.js +46 -10
  124. package/lib/module/components/ui/Stepper/Stepper.js.map +1 -1
  125. package/lib/module/components/ui/Switch/Switch.js +6 -11
  126. package/lib/module/components/ui/Switch/Switch.js.map +1 -1
  127. package/lib/module/components/ui/Switch/Switch.web.js +2 -8
  128. package/lib/module/components/ui/Switch/Switch.web.js.map +1 -1
  129. package/lib/module/components/ui/Switch/styles.js +12 -3
  130. package/lib/module/components/ui/Switch/styles.js.map +1 -1
  131. package/lib/module/components/ui/TabBar/TabBar.js +10 -6
  132. package/lib/module/components/ui/TabBar/TabBar.js.map +1 -1
  133. package/lib/module/components/ui/TabBar/styles.js +28 -39
  134. package/lib/module/components/ui/TabBar/styles.js.map +1 -1
  135. package/lib/module/components/ui/Tabs/Tabs.js +19 -5
  136. package/lib/module/components/ui/Tabs/Tabs.js.map +1 -1
  137. package/lib/module/components/ui/Tabs/styles.js +6 -2
  138. package/lib/module/components/ui/Tabs/styles.js.map +1 -1
  139. package/lib/module/components/ui/Tabs/types.js +2 -0
  140. package/lib/module/components/ui/Tag/styles.js +15 -14
  141. package/lib/module/components/ui/Tag/styles.js.map +1 -1
  142. package/lib/module/components/ui/TextField/TextFieldBase.js +24 -6
  143. package/lib/module/components/ui/TextField/TextFieldBase.js.map +1 -1
  144. package/lib/module/components/ui/Thumbnail/Thumbnail.js +11 -3
  145. package/lib/module/components/ui/Thumbnail/Thumbnail.js.map +1 -1
  146. package/lib/module/components/ui/Thumbnail/styles.js +6 -2
  147. package/lib/module/components/ui/Thumbnail/styles.js.map +1 -1
  148. package/lib/module/components/ui/Toast/ToastHost.js +16 -5
  149. package/lib/module/components/ui/Toast/ToastHost.js.map +1 -1
  150. package/lib/module/components/ui/Toast/ToastHost.web.js +21 -4
  151. package/lib/module/components/ui/Toast/ToastHost.web.js.map +1 -1
  152. package/lib/module/components/ui/Toast/styles.js +2 -0
  153. package/lib/module/components/ui/Toast/styles.js.map +1 -1
  154. package/lib/module/components/ui/Toast/toast.js +23 -3
  155. package/lib/module/components/ui/Toast/toast.js.map +1 -1
  156. package/lib/module/components/ui/shared/badgeStyles.js +31 -0
  157. package/lib/module/components/ui/shared/badgeStyles.js.map +1 -0
  158. package/lib/module/icons/data.js +43 -18
  159. package/lib/module/icons/data.js.map +1 -1
  160. package/lib/module/theme/colors.js +28 -10
  161. package/lib/module/theme/colors.js.map +1 -1
  162. package/lib/module/theme/index.js +6 -2
  163. package/lib/module/theme/index.js.map +1 -1
  164. package/lib/module/theme/scale.js +9 -1
  165. package/lib/module/theme/scale.js.map +1 -1
  166. package/lib/module/theme/shadow.js +24 -41
  167. package/lib/module/theme/shadow.js.map +1 -1
  168. package/lib/module/theme/tokens.js +10 -5
  169. package/lib/module/theme/tokens.js.map +1 -1
  170. package/lib/module/theme/usePrefersReducedMotion.js +12 -0
  171. package/lib/module/theme/usePrefersReducedMotion.js.map +1 -0
  172. package/lib/module/theme/usePrefersReducedMotion.web.js +25 -0
  173. package/lib/module/theme/usePrefersReducedMotion.web.js.map +1 -0
  174. package/lib/module/theme/useTheme.js +13 -0
  175. package/lib/module/theme/useTheme.js.map +1 -1
  176. package/lib/module/utils/logger/logger.js +5 -1
  177. package/lib/module/utils/logger/logger.js.map +1 -1
  178. package/lib/module/utils/testID/testID.js +6 -3
  179. package/lib/module/utils/testID/testID.js.map +1 -1
  180. package/lib/typescript/src/components/business/AvatarWithRing/AvatarWithRing.d.ts +1 -1
  181. package/lib/typescript/src/components/business/AvatarWithRing/AvatarWithRing.d.ts.map +1 -1
  182. package/lib/typescript/src/components/business/AvatarWithRing/styles.d.ts +5 -5
  183. package/lib/typescript/src/components/business/AvatarWithRing/styles.d.ts.map +1 -1
  184. package/lib/typescript/src/components/business/AvatarWithRing/types.d.ts +3 -1
  185. package/lib/typescript/src/components/business/AvatarWithRing/types.d.ts.map +1 -1
  186. package/lib/typescript/src/components/business/Decorations/GradientWash.d.ts +25 -0
  187. package/lib/typescript/src/components/business/Decorations/GradientWash.d.ts.map +1 -1
  188. package/lib/typescript/src/components/business/Decorations/RadialHalo.d.ts.map +1 -1
  189. package/lib/typescript/src/components/business/Decorations/ScreenBackdrop.d.ts +1 -1
  190. package/lib/typescript/src/components/business/Decorations/ScreenBackdrop.d.ts.map +1 -1
  191. package/lib/typescript/src/components/business/Decorations/index.d.ts +1 -1
  192. package/lib/typescript/src/components/business/Decorations/index.d.ts.map +1 -1
  193. package/lib/typescript/src/components/business/Decorations/types.d.ts +2 -0
  194. package/lib/typescript/src/components/business/Decorations/types.d.ts.map +1 -1
  195. package/lib/typescript/src/components/business/GlassStats/GlassStats.d.ts +1 -1
  196. package/lib/typescript/src/components/business/GlassStats/GlassStats.d.ts.map +1 -1
  197. package/lib/typescript/src/components/business/GlassStats/styles.d.ts +2 -2
  198. package/lib/typescript/src/components/business/GlassStats/types.d.ts +5 -0
  199. package/lib/typescript/src/components/business/GlassStats/types.d.ts.map +1 -1
  200. package/lib/typescript/src/components/business/VersionPill/VersionPill.d.ts +1 -1
  201. package/lib/typescript/src/components/business/VersionPill/VersionPill.d.ts.map +1 -1
  202. package/lib/typescript/src/components/business/VersionPill/styles.d.ts +1 -1
  203. package/lib/typescript/src/components/business/VersionPill/styles.d.ts.map +1 -1
  204. package/lib/typescript/src/components/business/VersionPill/types.d.ts +13 -1
  205. package/lib/typescript/src/components/business/VersionPill/types.d.ts.map +1 -1
  206. package/lib/typescript/src/components/business/index.d.ts +1 -1
  207. package/lib/typescript/src/components/business/index.d.ts.map +1 -1
  208. package/lib/typescript/src/components/business/useSvgId.d.ts +12 -0
  209. package/lib/typescript/src/components/business/useSvgId.d.ts.map +1 -0
  210. package/lib/typescript/src/components/ui/Avatar/Avatar.d.ts +1 -1
  211. package/lib/typescript/src/components/ui/Avatar/Avatar.d.ts.map +1 -1
  212. package/lib/typescript/src/components/ui/Avatar/styles.d.ts +1 -1
  213. package/lib/typescript/src/components/ui/Avatar/styles.d.ts.map +1 -1
  214. package/lib/typescript/src/components/ui/Avatar/types.d.ts +3 -1
  215. package/lib/typescript/src/components/ui/Avatar/types.d.ts.map +1 -1
  216. package/lib/typescript/src/components/ui/BlurLayer/BlurLayer.d.ts +1 -1
  217. package/lib/typescript/src/components/ui/BlurLayer/BlurLayer.d.ts.map +1 -1
  218. package/lib/typescript/src/components/ui/BlurLayer/BlurLayer.web.d.ts.map +1 -1
  219. package/lib/typescript/src/components/ui/Button/Button.d.ts +1 -1
  220. package/lib/typescript/src/components/ui/Button/Button.d.ts.map +1 -1
  221. package/lib/typescript/src/components/ui/Button/ButtonBase.d.ts.map +1 -1
  222. package/lib/typescript/src/components/ui/Button/styles.d.ts +2 -1
  223. package/lib/typescript/src/components/ui/Button/styles.d.ts.map +1 -1
  224. package/lib/typescript/src/components/ui/Button/types.d.ts +1 -1
  225. package/lib/typescript/src/components/ui/Button/types.d.ts.map +1 -1
  226. package/lib/typescript/src/components/ui/Card/Card.d.ts.map +1 -1
  227. package/lib/typescript/src/components/ui/Card/styles.d.ts +2 -0
  228. package/lib/typescript/src/components/ui/Card/styles.d.ts.map +1 -1
  229. package/lib/typescript/src/components/ui/Card/types.d.ts +4 -4
  230. package/lib/typescript/src/components/ui/Card/types.d.ts.map +1 -1
  231. package/lib/typescript/src/components/ui/Carousel/Carousel.d.ts +4 -11
  232. package/lib/typescript/src/components/ui/Carousel/Carousel.d.ts.map +1 -1
  233. package/lib/typescript/src/components/ui/Carousel/index.d.ts +1 -1
  234. package/lib/typescript/src/components/ui/Carousel/index.d.ts.map +1 -1
  235. package/lib/typescript/src/components/ui/Carousel/types.d.ts +4 -0
  236. package/lib/typescript/src/components/ui/Carousel/types.d.ts.map +1 -1
  237. package/lib/typescript/src/components/ui/Cell/Cell.d.ts.map +1 -1
  238. package/lib/typescript/src/components/ui/Cell/List.d.ts.map +1 -1
  239. package/lib/typescript/src/components/ui/Cell/styles.d.ts +1 -1
  240. package/lib/typescript/src/components/ui/Cell/styles.d.ts.map +1 -1
  241. package/lib/typescript/src/components/ui/Cell/types.d.ts +5 -2
  242. package/lib/typescript/src/components/ui/Cell/types.d.ts.map +1 -1
  243. package/lib/typescript/src/components/ui/Checkbox/Checkbox.d.ts.map +1 -1
  244. package/lib/typescript/src/components/ui/Checkbox/styles.d.ts +6 -0
  245. package/lib/typescript/src/components/ui/Checkbox/styles.d.ts.map +1 -1
  246. package/lib/typescript/src/components/ui/Chip/Chip.d.ts +4 -3
  247. package/lib/typescript/src/components/ui/Chip/Chip.d.ts.map +1 -1
  248. package/lib/typescript/src/components/ui/Chip/types.d.ts +2 -0
  249. package/lib/typescript/src/components/ui/Chip/types.d.ts.map +1 -1
  250. package/lib/typescript/src/components/ui/Confirm/ConfirmHost.d.ts.map +1 -1
  251. package/lib/typescript/src/components/ui/Confirm/confirm.d.ts.map +1 -1
  252. package/lib/typescript/src/components/ui/Confirm/types.d.ts +4 -2
  253. package/lib/typescript/src/components/ui/Confirm/types.d.ts.map +1 -1
  254. package/lib/typescript/src/components/ui/DrawerHeader/DrawerHeader.d.ts +1 -1
  255. package/lib/typescript/src/components/ui/DrawerHeader/DrawerHeader.d.ts.map +1 -1
  256. package/lib/typescript/src/components/ui/DrawerHeader/styles.d.ts.map +1 -1
  257. package/lib/typescript/src/components/ui/DrawerHeader/types.d.ts +3 -1
  258. package/lib/typescript/src/components/ui/DrawerHeader/types.d.ts.map +1 -1
  259. package/lib/typescript/src/components/ui/Empty/Empty.d.ts +2 -2
  260. package/lib/typescript/src/components/ui/Empty/Empty.d.ts.map +1 -1
  261. package/lib/typescript/src/components/ui/Empty/types.d.ts +3 -0
  262. package/lib/typescript/src/components/ui/Empty/types.d.ts.map +1 -1
  263. package/lib/typescript/src/components/ui/EntryCard/EntryCard.d.ts.map +1 -1
  264. package/lib/typescript/src/components/ui/EntryCard/styles.d.ts.map +1 -1
  265. package/lib/typescript/src/components/ui/EntryCard/types.d.ts +2 -2
  266. package/lib/typescript/src/components/ui/EntryCard/types.d.ts.map +1 -1
  267. package/lib/typescript/src/components/ui/Form/FormRow.d.ts.map +1 -1
  268. package/lib/typescript/src/components/ui/Form/styles.d.ts +1 -0
  269. package/lib/typescript/src/components/ui/Form/styles.d.ts.map +1 -1
  270. package/lib/typescript/src/components/ui/Form/types.d.ts +7 -2
  271. package/lib/typescript/src/components/ui/Form/types.d.ts.map +1 -1
  272. package/lib/typescript/src/components/ui/Grid/Grid.d.ts +1 -1
  273. package/lib/typescript/src/components/ui/Grid/Grid.d.ts.map +1 -1
  274. package/lib/typescript/src/components/ui/Grid/styles.d.ts.map +1 -1
  275. package/lib/typescript/src/components/ui/Grid/types.d.ts +4 -1
  276. package/lib/typescript/src/components/ui/Grid/types.d.ts.map +1 -1
  277. package/lib/typescript/src/components/ui/Icon/Icon.d.ts.map +1 -1
  278. package/lib/typescript/src/components/ui/IconButton/IconButton.d.ts +1 -1
  279. package/lib/typescript/src/components/ui/IconButton/IconButton.d.ts.map +1 -1
  280. package/lib/typescript/src/components/ui/IconButton/types.d.ts +7 -2
  281. package/lib/typescript/src/components/ui/IconButton/types.d.ts.map +1 -1
  282. package/lib/typescript/src/components/ui/Input/Input.d.ts +16 -16
  283. package/lib/typescript/src/components/ui/Input/types.d.ts +3 -2
  284. package/lib/typescript/src/components/ui/Input/types.d.ts.map +1 -1
  285. package/lib/typescript/src/components/ui/Logo/Logo.d.ts.map +1 -1
  286. package/lib/typescript/src/components/ui/NavBar/NavBar.d.ts +8 -1
  287. package/lib/typescript/src/components/ui/NavBar/NavBar.d.ts.map +1 -1
  288. package/lib/typescript/src/components/ui/NavBar/types.d.ts +5 -1
  289. package/lib/typescript/src/components/ui/NavBar/types.d.ts.map +1 -1
  290. package/lib/typescript/src/components/ui/PasswordInput/PasswordInput.d.ts +13 -5
  291. package/lib/typescript/src/components/ui/PasswordInput/PasswordInput.d.ts.map +1 -1
  292. package/lib/typescript/src/components/ui/PasswordInput/styles.d.ts +1 -1
  293. package/lib/typescript/src/components/ui/PasswordInput/styles.d.ts.map +1 -1
  294. package/lib/typescript/src/components/ui/PasswordInput/types.d.ts +7 -2
  295. package/lib/typescript/src/components/ui/PasswordInput/types.d.ts.map +1 -1
  296. package/lib/typescript/src/components/ui/Pulse/Pulse.d.ts +1 -1
  297. package/lib/typescript/src/components/ui/Pulse/Pulse.d.ts.map +1 -1
  298. package/lib/typescript/src/components/ui/Pulse/PulseDot.d.ts +1 -1
  299. package/lib/typescript/src/components/ui/Pulse/PulseDot.d.ts.map +1 -1
  300. package/lib/typescript/src/components/ui/Pulse/types.d.ts +5 -0
  301. package/lib/typescript/src/components/ui/Pulse/types.d.ts.map +1 -1
  302. package/lib/typescript/src/components/ui/Pulse/usePulse.web.d.ts +12 -8
  303. package/lib/typescript/src/components/ui/Pulse/usePulse.web.d.ts.map +1 -1
  304. package/lib/typescript/src/components/ui/Radio/Radio.d.ts.map +1 -1
  305. package/lib/typescript/src/components/ui/Radio/RadioGroup.d.ts.map +1 -1
  306. package/lib/typescript/src/components/ui/Radio/styles.d.ts +4 -2
  307. package/lib/typescript/src/components/ui/Radio/styles.d.ts.map +1 -1
  308. package/lib/typescript/src/components/ui/Reveal/Reveal.web.d.ts +9 -0
  309. package/lib/typescript/src/components/ui/Reveal/Reveal.web.d.ts.map +1 -1
  310. package/lib/typescript/src/components/ui/Search/Search.d.ts +16 -15
  311. package/lib/typescript/src/components/ui/Search/Search.d.ts.map +1 -1
  312. package/lib/typescript/src/components/ui/Search/types.d.ts +3 -1
  313. package/lib/typescript/src/components/ui/Search/types.d.ts.map +1 -1
  314. package/lib/typescript/src/components/ui/Segmented/Segmented.d.ts +1 -1
  315. package/lib/typescript/src/components/ui/Segmented/Segmented.d.ts.map +1 -1
  316. package/lib/typescript/src/components/ui/Segmented/styles.d.ts +1 -1
  317. package/lib/typescript/src/components/ui/Segmented/styles.d.ts.map +1 -1
  318. package/lib/typescript/src/components/ui/Segmented/types.d.ts +2 -0
  319. package/lib/typescript/src/components/ui/Segmented/types.d.ts.map +1 -1
  320. package/lib/typescript/src/components/ui/Skeleton/Skeleton.d.ts +3 -2
  321. package/lib/typescript/src/components/ui/Skeleton/Skeleton.d.ts.map +1 -1
  322. package/lib/typescript/src/components/ui/Spinner/Spinner.d.ts.map +1 -1
  323. package/lib/typescript/src/components/ui/Spinner/Spinner.web.d.ts.map +1 -1
  324. package/lib/typescript/src/components/ui/Spinner/shared.d.ts +5 -0
  325. package/lib/typescript/src/components/ui/Spinner/shared.d.ts.map +1 -0
  326. package/lib/typescript/src/components/ui/StatusDot/StatusDot.d.ts +1 -5
  327. package/lib/typescript/src/components/ui/StatusDot/StatusDot.d.ts.map +1 -1
  328. package/lib/typescript/src/components/ui/StatusDot/styles.d.ts +1 -1
  329. package/lib/typescript/src/components/ui/StatusDot/types.d.ts +13 -1
  330. package/lib/typescript/src/components/ui/StatusDot/types.d.ts.map +1 -1
  331. package/lib/typescript/src/components/ui/Stepper/Stepper.d.ts.map +1 -1
  332. package/lib/typescript/src/components/ui/Switch/Switch.d.ts.map +1 -1
  333. package/lib/typescript/src/components/ui/Switch/Switch.web.d.ts.map +1 -1
  334. package/lib/typescript/src/components/ui/Switch/styles.d.ts +7 -1
  335. package/lib/typescript/src/components/ui/Switch/styles.d.ts.map +1 -1
  336. package/lib/typescript/src/components/ui/TabBar/TabBar.d.ts +2 -2
  337. package/lib/typescript/src/components/ui/TabBar/TabBar.d.ts.map +1 -1
  338. package/lib/typescript/src/components/ui/TabBar/styles.d.ts.map +1 -1
  339. package/lib/typescript/src/components/ui/TabBar/types.d.ts +3 -0
  340. package/lib/typescript/src/components/ui/TabBar/types.d.ts.map +1 -1
  341. package/lib/typescript/src/components/ui/Tabs/Tabs.d.ts +1 -1
  342. package/lib/typescript/src/components/ui/Tabs/Tabs.d.ts.map +1 -1
  343. package/lib/typescript/src/components/ui/Tabs/styles.d.ts.map +1 -1
  344. package/lib/typescript/src/components/ui/Tabs/types.d.ts +9 -1
  345. package/lib/typescript/src/components/ui/Tabs/types.d.ts.map +1 -1
  346. package/lib/typescript/src/components/ui/Tag/styles.d.ts +2 -1
  347. package/lib/typescript/src/components/ui/Tag/styles.d.ts.map +1 -1
  348. package/lib/typescript/src/components/ui/Tag/types.d.ts +6 -2
  349. package/lib/typescript/src/components/ui/Tag/types.d.ts.map +1 -1
  350. package/lib/typescript/src/components/ui/TextField/TextFieldBase.d.ts +16 -16
  351. package/lib/typescript/src/components/ui/TextField/TextFieldBase.d.ts.map +1 -1
  352. package/lib/typescript/src/components/ui/Textarea/Textarea.d.ts +16 -16
  353. package/lib/typescript/src/components/ui/Textarea/types.d.ts +2 -1
  354. package/lib/typescript/src/components/ui/Textarea/types.d.ts.map +1 -1
  355. package/lib/typescript/src/components/ui/Thumbnail/Thumbnail.d.ts.map +1 -1
  356. package/lib/typescript/src/components/ui/Thumbnail/styles.d.ts +3 -0
  357. package/lib/typescript/src/components/ui/Thumbnail/styles.d.ts.map +1 -1
  358. package/lib/typescript/src/components/ui/Toast/ToastHost.d.ts.map +1 -1
  359. package/lib/typescript/src/components/ui/Toast/ToastHost.web.d.ts.map +1 -1
  360. package/lib/typescript/src/components/ui/Toast/styles.d.ts.map +1 -1
  361. package/lib/typescript/src/components/ui/Toast/toast.d.ts +0 -5
  362. package/lib/typescript/src/components/ui/Toast/toast.d.ts.map +1 -1
  363. package/lib/typescript/src/components/ui/Toast/types.d.ts +1 -1
  364. package/lib/typescript/src/components/ui/Toast/types.d.ts.map +1 -1
  365. package/lib/typescript/src/components/ui/shared/badgeStyles.d.ts +27 -0
  366. package/lib/typescript/src/components/ui/shared/badgeStyles.d.ts.map +1 -0
  367. package/lib/typescript/src/icons/data.d.ts.map +1 -1
  368. package/lib/typescript/src/icons/types.d.ts +18 -12
  369. package/lib/typescript/src/icons/types.d.ts.map +1 -1
  370. package/lib/typescript/src/theme/colors.d.ts +9 -3
  371. package/lib/typescript/src/theme/colors.d.ts.map +1 -1
  372. package/lib/typescript/src/theme/index.d.ts +3 -2
  373. package/lib/typescript/src/theme/index.d.ts.map +1 -1
  374. package/lib/typescript/src/theme/scale.d.ts.map +1 -1
  375. package/lib/typescript/src/theme/shadow.d.ts +8 -8
  376. package/lib/typescript/src/theme/shadow.d.ts.map +1 -1
  377. package/lib/typescript/src/theme/tokens.d.ts +7 -3
  378. package/lib/typescript/src/theme/tokens.d.ts.map +1 -1
  379. package/lib/typescript/src/theme/usePrefersReducedMotion.d.ts +8 -0
  380. package/lib/typescript/src/theme/usePrefersReducedMotion.d.ts.map +1 -0
  381. package/lib/typescript/src/theme/usePrefersReducedMotion.web.d.ts +6 -0
  382. package/lib/typescript/src/theme/usePrefersReducedMotion.web.d.ts.map +1 -0
  383. package/lib/typescript/src/theme/useTheme.d.ts.map +1 -1
  384. package/lib/typescript/src/utils/logger/logger.d.ts.map +1 -1
  385. package/lib/typescript/src/utils/testID/testID.d.ts +6 -3
  386. package/lib/typescript/src/utils/testID/testID.d.ts.map +1 -1
  387. package/package.json +2 -1
  388. package/src/components/business/AvatarWithRing/AvatarWithRing.tsx +5 -4
  389. package/src/components/business/AvatarWithRing/styles.ts +21 -3
  390. package/src/components/business/AvatarWithRing/types.ts +3 -1
  391. package/src/components/business/Decorations/GradientWash.tsx +46 -22
  392. package/src/components/business/Decorations/RadialHalo.tsx +8 -4
  393. package/src/components/business/Decorations/ScreenBackdrop.tsx +23 -5
  394. package/src/components/business/Decorations/index.ts +4 -0
  395. package/src/components/business/Decorations/types.ts +2 -0
  396. package/src/components/business/GlassStats/GlassStats.tsx +8 -4
  397. package/src/components/business/GlassStats/types.ts +6 -0
  398. package/src/components/business/VersionPill/VersionPill.tsx +46 -6
  399. package/src/components/business/VersionPill/styles.ts +1 -1
  400. package/src/components/business/VersionPill/types.ts +13 -1
  401. package/src/components/business/index.ts +1 -0
  402. package/src/components/business/useSvgId.ts +17 -0
  403. package/src/components/ui/Avatar/Avatar.tsx +17 -10
  404. package/src/components/ui/Avatar/styles.ts +7 -7
  405. package/src/components/ui/Avatar/types.ts +3 -1
  406. package/src/components/ui/BlurLayer/BlurLayer.tsx +4 -1
  407. package/src/components/ui/BlurLayer/BlurLayer.web.tsx +7 -1
  408. package/src/components/ui/Button/Button.tsx +2 -1
  409. package/src/components/ui/Button/ButtonBase.tsx +26 -2
  410. package/src/components/ui/Button/styles.ts +27 -25
  411. package/src/components/ui/Button/types.ts +1 -1
  412. package/src/components/ui/Card/Card.tsx +17 -7
  413. package/src/components/ui/Card/styles.ts +5 -0
  414. package/src/components/ui/Card/types.ts +4 -4
  415. package/src/components/ui/Carousel/Carousel.tsx +44 -15
  416. package/src/components/ui/Carousel/index.ts +1 -1
  417. package/src/components/ui/Carousel/types.ts +5 -0
  418. package/src/components/ui/Cell/Cell.tsx +28 -6
  419. package/src/components/ui/Cell/Leading.tsx +2 -2
  420. package/src/components/ui/Cell/List.tsx +14 -8
  421. package/src/components/ui/Cell/styles.ts +8 -5
  422. package/src/components/ui/Cell/types.ts +5 -2
  423. package/src/components/ui/Checkbox/Checkbox.tsx +18 -5
  424. package/src/components/ui/Checkbox/styles.ts +8 -0
  425. package/src/components/ui/Chip/Chip.tsx +20 -5
  426. package/src/components/ui/Chip/types.ts +2 -0
  427. package/src/components/ui/Confirm/ConfirmHost.tsx +26 -10
  428. package/src/components/ui/Confirm/confirm.ts +8 -0
  429. package/src/components/ui/Confirm/types.ts +4 -2
  430. package/src/components/ui/DrawerHeader/DrawerHeader.tsx +18 -12
  431. package/src/components/ui/DrawerHeader/styles.ts +10 -6
  432. package/src/components/ui/DrawerHeader/types.ts +3 -1
  433. package/src/components/ui/Empty/Empty.tsx +5 -4
  434. package/src/components/ui/Empty/types.ts +3 -0
  435. package/src/components/ui/EntryCard/EntryCard.tsx +5 -3
  436. package/src/components/ui/EntryCard/styles.ts +13 -4
  437. package/src/components/ui/EntryCard/types.ts +2 -2
  438. package/src/components/ui/Form/FormRow.tsx +7 -1
  439. package/src/components/ui/Form/styles.ts +2 -0
  440. package/src/components/ui/Form/types.ts +7 -2
  441. package/src/components/ui/Grid/Grid.tsx +42 -25
  442. package/src/components/ui/Grid/styles.ts +8 -20
  443. package/src/components/ui/Grid/types.ts +4 -1
  444. package/src/components/ui/Icon/Icon.tsx +42 -27
  445. package/src/components/ui/IconButton/IconButton.tsx +2 -0
  446. package/src/components/ui/IconButton/types.ts +8 -2
  447. package/src/components/ui/Input/types.ts +3 -2
  448. package/src/components/ui/Logo/Logo.tsx +2 -1
  449. package/src/components/ui/NavBar/NavBar.tsx +16 -2
  450. package/src/components/ui/NavBar/types.ts +5 -1
  451. package/src/components/ui/PasswordInput/PasswordInput.tsx +77 -43
  452. package/src/components/ui/PasswordInput/styles.ts +1 -1
  453. package/src/components/ui/PasswordInput/types.ts +7 -2
  454. package/src/components/ui/Pulse/Pulse.tsx +2 -1
  455. package/src/components/ui/Pulse/PulseDot.tsx +7 -6
  456. package/src/components/ui/Pulse/types.ts +6 -0
  457. package/src/components/ui/Pulse/usePulse.web.ts +50 -33
  458. package/src/components/ui/Radio/Radio.tsx +29 -6
  459. package/src/components/ui/Radio/RadioGroup.tsx +10 -3
  460. package/src/components/ui/Radio/styles.ts +9 -2
  461. package/src/components/ui/Reveal/Reveal.web.tsx +18 -3
  462. package/src/components/ui/Search/Search.tsx +22 -9
  463. package/src/components/ui/Search/types.ts +7 -1
  464. package/src/components/ui/Segmented/Segmented.tsx +8 -3
  465. package/src/components/ui/Segmented/styles.ts +4 -2
  466. package/src/components/ui/Segmented/types.ts +2 -0
  467. package/src/components/ui/Skeleton/Skeleton.tsx +9 -8
  468. package/src/components/ui/Spinner/Spinner.tsx +17 -17
  469. package/src/components/ui/Spinner/Spinner.web.tsx +7 -15
  470. package/src/components/ui/Spinner/shared.ts +37 -0
  471. package/src/components/ui/StatusDot/StatusDot.tsx +21 -3
  472. package/src/components/ui/StatusDot/styles.ts +1 -1
  473. package/src/components/ui/StatusDot/types.ts +14 -1
  474. package/src/components/ui/Stepper/Stepper.tsx +45 -10
  475. package/src/components/ui/Switch/Switch.tsx +4 -10
  476. package/src/components/ui/Switch/Switch.web.tsx +2 -8
  477. package/src/components/ui/Switch/styles.ts +10 -1
  478. package/src/components/ui/TabBar/TabBar.tsx +14 -6
  479. package/src/components/ui/TabBar/styles.ts +9 -21
  480. package/src/components/ui/TabBar/types.ts +3 -0
  481. package/src/components/ui/Tabs/Tabs.tsx +24 -5
  482. package/src/components/ui/Tabs/styles.ts +6 -2
  483. package/src/components/ui/Tabs/types.ts +10 -1
  484. package/src/components/ui/Tag/styles.ts +18 -10
  485. package/src/components/ui/Tag/types.ts +6 -2
  486. package/src/components/ui/TextField/TextFieldBase.tsx +31 -6
  487. package/src/components/ui/Textarea/types.ts +2 -1
  488. package/src/components/ui/Thumbnail/Thumbnail.tsx +14 -3
  489. package/src/components/ui/Thumbnail/styles.ts +6 -2
  490. package/src/components/ui/Toast/ToastHost.tsx +16 -8
  491. package/src/components/ui/Toast/ToastHost.web.tsx +26 -4
  492. package/src/components/ui/Toast/styles.ts +2 -0
  493. package/src/components/ui/Toast/toast.ts +35 -2
  494. package/src/components/ui/Toast/types.ts +1 -1
  495. package/src/components/ui/shared/badgeStyles.ts +36 -0
  496. package/src/icons/data.ts +27 -0
  497. package/src/icons/types.ts +25 -10
  498. package/src/theme/colors.ts +29 -10
  499. package/src/theme/index.ts +10 -1
  500. package/src/theme/scale.ts +5 -1
  501. package/src/theme/shadow.ts +33 -24
  502. package/src/theme/tokens.ts +10 -5
  503. package/src/theme/usePrefersReducedMotion.ts +9 -0
  504. package/src/theme/usePrefersReducedMotion.web.ts +27 -0
  505. package/src/theme/useTheme.ts +15 -0
  506. package/src/utils/logger/logger.ts +5 -1
  507. package/src/utils/testID/testID.ts +6 -3
  508. package/lib/module/components/index.js +0 -5
  509. package/lib/module/components/index.js.map +0 -1
  510. package/lib/typescript/src/components/index.d.ts +0 -3
  511. package/lib/typescript/src/components/index.d.ts.map +0 -1
  512. package/src/components/index.ts +0 -2
@@ -1,8 +1,16 @@
1
1
  import React, { useContext } from 'react';
2
2
  import { Text, View } from 'react-native';
3
3
  import { Pressable } from 'react-native-gesture-handler';
4
- import { useColors, useThemedStyles } from '../../../theme';
4
+ import {
5
+ fixed,
6
+ pressedOpacity,
7
+ r,
8
+ space,
9
+ useColors,
10
+ useThemedStyles,
11
+ } from '../../../theme';
5
12
  import { createLogger } from '../../../utils/logger';
13
+ import { childTestID } from '../../../utils/testID';
6
14
  import { RadioContext } from './RadioContext';
7
15
  import { RadioGroup } from './RadioGroup';
8
16
  import { makeStyles } from './styles';
@@ -10,6 +18,9 @@ import type { RadioProps } from './types';
10
18
 
11
19
  const log = createLogger('Radio');
12
20
 
21
+ // [L-30] 模块级 Set 去重 —— "must be inside Group" 只告警一次,避免 FlatList 滚动时刷屏
22
+ const _warnedCtx = new Set<string>();
23
+
13
24
  /**
14
25
  * 单个 radio 选项。必须放在 `<Radio.Group>` 里使用。
15
26
  */
@@ -23,25 +34,37 @@ export function Radio({
23
34
  const styles = useThemedStyles(makeStyles);
24
35
  const ctx = useContext(RadioContext);
25
36
  if (!ctx) {
26
- log.warn('<Radio> must be used inside <Radio.Group>');
37
+ // [L-30] 去重:同一 value warn 只打一次,避免渲染阶段反复刷屏
38
+ const warnKey = `no-ctx:${String(value)}`;
39
+ if (!_warnedCtx.has(warnKey)) {
40
+ _warnedCtx.add(warnKey);
41
+ log.warn('<Radio> must be used inside <Radio.Group>');
42
+ }
27
43
  return <View />;
28
44
  }
29
45
  const checked = ctx.value === value;
30
- const resolvedTestID =
31
- testID ?? (ctx.groupTestID ? `${ctx.groupTestID}-${value}` : undefined);
46
+ // [L-92] 改用 childTestID:收口 parent+id 拼接逻辑,保持空串 override 回落拼接语义
47
+ const resolvedTestID = childTestID(ctx.groupTestID, value, testID);
48
+
49
+ // [M-7] row 含 paddingVertical space[2](上下各 ~6pt) → 行高 ≈ r(20) + 2×space[2] ≈ 32pt
50
+ // 补足到 fixed.hitTarget:slop = (44 - 32) / 2 = 6
51
+ const hitSlopV = Math.max(
52
+ 0,
53
+ Math.round((fixed.hitTarget - (r(20) + 2 * space[2])) / 2)
54
+ );
32
55
 
33
56
  return (
34
57
  <Pressable
35
58
  onPress={() => !disabled && ctx.onChange(value)}
36
59
  disabled={disabled}
37
- hitSlop={4}
60
+ hitSlop={hitSlopV}
38
61
  accessibilityRole="radio"
39
62
  accessibilityState={{ checked, disabled: !!disabled }}
40
63
  accessibilityLabel={label}
41
64
  testID={resolvedTestID}
42
65
  style={({ pressed }) => [
43
66
  styles.row,
44
- { opacity: disabled ? 0.5 : pressed ? 0.7 : 1 },
67
+ { opacity: disabled ? 0.5 : pressed ? pressedOpacity : 1 },
45
68
  ]}
46
69
  >
47
70
  <View style={[styles.circle, checked && { borderColor: c.primary }]}>
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useMemo } from 'react';
2
2
  import { View } from 'react-native';
3
3
  import { useThemedStyles } from '../../../theme';
4
4
  import { RadioContext } from './RadioContext';
@@ -20,9 +20,16 @@ export function RadioGroup({
20
20
  testID,
21
21
  }: GroupProps): React.JSX.Element {
22
22
  const styles = useThemedStyles(makeStyles);
23
+ // [L-80b] useMemo 稳定 context value —— 避免每次渲染都产生新对象引用,
24
+ // 防止所有 Radio 子项因 context 变化而不必要 re-render。
25
+ const ctx = useMemo(
26
+ () => ({ value, onChange, groupTestID: testID }),
27
+ [value, onChange, testID]
28
+ );
23
29
  return (
24
- <RadioContext.Provider value={{ value, onChange, groupTestID: testID }}>
25
- <View style={styles.group} testID={testID}>
30
+ <RadioContext.Provider value={ctx}>
31
+ {/* [L-34] accessibilityRole="radiogroup" —— SR 宣读"单选按钮组" */}
32
+ <View style={styles.group} testID={testID} accessibilityRole="radiogroup">
26
33
  {children}
27
34
  </View>
28
35
  </RadioContext.Provider>
@@ -6,17 +6,21 @@ export const makeStyles = (c: ColorTokens) =>
6
6
  StyleSheet.create({
7
7
  group: {
8
8
  gap: space[1],
9
+ // [L-34] radiogroup 角色由 RadioGroup.tsx 容器 View 上设置
9
10
  },
10
11
  row: {
11
12
  flexDirection: 'row',
12
13
  alignItems: 'center',
14
+ // [L-37] alignSelf:'flex-start' 防止父容器拉伸(与 Chip [M-8] 同口径)
15
+ alignSelf: 'flex-start' as const,
13
16
  gap: space[4],
14
17
  paddingVertical: space[2],
15
18
  },
16
19
  circle: {
17
20
  width: r(20),
18
21
  height: r(20),
19
- borderRadius: radius.lg,
22
+ // [L-79] radius.pill —— sentinel 999 确保任何尺寸下都是真圆
23
+ borderRadius: radius.pill,
20
24
  borderWidth: r(1.5),
21
25
  borderColor: c.outline,
22
26
  alignItems: 'center',
@@ -25,12 +29,15 @@ export const makeStyles = (c: ColorTokens) =>
25
29
  dot: {
26
30
  width: r(8),
27
31
  height: r(8),
28
- borderRadius: radius.xs,
32
+ // [L-79] radius.pill —— 内圆点同理
33
+ borderRadius: radius.pill,
29
34
  backgroundColor: c.primary,
30
35
  },
31
36
  label: {
32
37
  fontSize: t.sm,
33
38
  color: c.foreground,
34
39
  fontWeight: fw.regular,
40
+ // flexShrink:长 label 在 row 内换行/截断,不溢出也不把同行控件挤没([M-10])
41
+ flexShrink: 1,
35
42
  },
36
43
  });
@@ -1,6 +1,6 @@
1
1
  import React, { useEffect, useRef, useState } from 'react';
2
2
  import { View } from 'react-native';
3
- import { motion } from '../../../theme';
3
+ import { motion, usePrefersReducedMotion } from '../../../theme';
4
4
  import type { RevealProps } from './types';
5
5
 
6
6
  /**
@@ -8,6 +8,15 @@ import type { RevealProps } from './types';
8
8
  * _updatePropsJS 里 Object.keys 抛 TypeError(layoutReanimation/web,渲染即每帧崩),
9
9
  * 改用 React state + CSS transition 复刻入场淡入。退场在 web 省略(消费者卸载即移除);
10
10
  * native 走 Reveal.tsx 的 reanimated 实现。
11
+ *
12
+ * **结构分叉说明(三层容器)**:
13
+ * - 外层 `<View style={style}>` —— 承接 RN StyleSheet 样式(flex/margin/padding 等),
14
+ * 与 native Reveal 保持相同的容器语义;
15
+ * - 中间 `<div style={animatedWebStyle}>` —— CSS opacity transition 动画层;
16
+ * 必须是真正的 DOM 元素才能触发 CSS transition(react-native-web 的 <View> 会先
17
+ * inline 合并 style 再设 opacity,时序不稳定);
18
+ * - 因此这里刻意不用 animationKeyframes(需要 @keyframes 注入 document),
19
+ * 而用 CSS transition + state 切换 opacity。
11
20
  */
12
21
  export function Reveal({
13
22
  children,
@@ -15,10 +24,16 @@ export function Reveal({
15
24
  duration = motion.base,
16
25
  testID,
17
26
  }: RevealProps): React.JSX.Element {
27
+ const reduced = usePrefersReducedMotion();
18
28
  const [visible, setVisible] = useState(false);
19
29
  const rafRef = useRef<number | null>(null);
20
30
 
21
31
  useEffect(() => {
32
+ // reduce-motion:跳过淡入,内容即时呈现(与 native FadeIn 在 ReduceMotion.System 下一致)。
33
+ if (reduced) {
34
+ setVisible(true);
35
+ return;
36
+ }
22
37
  let cancelled = false;
23
38
  // 双 RAF 过一帧 commit/paint,确保 CSS transition 有 opacity:0 起点(仿 ToastHost.web)。
24
39
  rafRef.current = requestAnimationFrame(() => {
@@ -31,11 +46,11 @@ export function Reveal({
31
46
  cancelled = true;
32
47
  if (rafRef.current != null) cancelAnimationFrame(rafRef.current);
33
48
  };
34
- }, []);
49
+ }, [reduced]);
35
50
 
36
51
  const animatedWebStyle: React.CSSProperties = {
37
52
  opacity: visible ? 1 : 0,
38
- transition: `opacity ${duration}ms ease-out`,
53
+ transition: reduced ? undefined : `opacity ${duration}ms ease-out`,
39
54
  };
40
55
 
41
56
  return (
@@ -1,7 +1,8 @@
1
1
  import React, { forwardRef } from 'react';
2
2
  import { Pressable } from 'react-native-gesture-handler';
3
3
 
4
- import { useColors } from '../../../theme';
4
+ import { control, fixed, r, useColors } from '../../../theme';
5
+ import { childTestID } from '../../../utils/testID';
5
6
  import { Icon } from '../Icon';
6
7
  import { Input } from '../Input';
7
8
  import type { TextInputRef } from '../TextField/TextFieldBase';
@@ -9,12 +10,12 @@ import type { SearchProps } from './types';
9
10
 
10
11
  /**
11
12
  * 搜索输入框 —— `<Input>` 的预设:前置搜索图标、清除按钮、
12
- * 高 36px、键盘 return 键为「搜索」。
13
+ * 高 control.md、键盘 return 键为「搜索」。
13
14
  *
14
15
  * Ref 透传到 Input 内部 TextInput,业务可调 `searchRef.current?.focus()`。
15
16
  */
16
17
  export const Search = forwardRef<TextInputRef, SearchProps>(function Search(
17
- { onSubmit, placeholder = '搜索…', value, onChangeText, ...rest },
18
+ { onSubmit, placeholder = '搜索…', value, onChangeText, testID, ...rest },
18
19
  ref
19
20
  ): React.JSX.Element {
20
21
  const c = useColors();
@@ -26,22 +27,34 @@ export const Search = forwardRef<TextInputRef, SearchProps>(function Search(
26
27
  value={value}
27
28
  onChangeText={onChangeText}
28
29
  placeholder={placeholder}
29
- height={36}
30
+ // [L-81] 高度裸 36 → control.md(r(36),随设备缩放)
31
+ height={control.md}
30
32
  returnKeyType="search"
31
33
  accessibilityRole="search"
32
- onSubmitEditing={() => {
33
- if (typeof value === 'string') onSubmit?.(value);
34
+ testID={testID}
35
+ onSubmitEditing={(e) => {
36
+ // [M-9] 改读 e.nativeEvent.text —— 不再依赖受控 value,非受控场景也能触发
37
+ const text = e.nativeEvent.text;
38
+ onSubmit?.(text);
34
39
  }}
35
- leading={<Icon name="search" size={18} color={c.foregroundSubtle} />}
40
+ leading={<Icon name="search" size={r(18)} color={c.foregroundSubtle} />}
36
41
  trailing={
37
42
  filled ? (
38
43
  <Pressable
39
44
  onPress={() => onChangeText?.('')}
40
- hitSlop={6}
45
+ // [M-7] 清除按钮 icon r(14)≈14pt;Input 高 control.md≈36pt 限制垂直扩展
46
+ // horizontal 走 (44-14)/2=15;vertical 走 (44-control.md)/2≈4
47
+ hitSlop={{
48
+ top: Math.round((fixed.hitTarget - control.md) / 2),
49
+ bottom: Math.round((fixed.hitTarget - control.md) / 2),
50
+ left: Math.round((fixed.hitTarget - r(14)) / 2),
51
+ right: Math.round((fixed.hitTarget - r(14)) / 2),
52
+ }}
41
53
  accessibilityRole="button"
42
54
  accessibilityLabel="清除"
55
+ testID={childTestID(testID, 'clear')}
43
56
  >
44
- <Icon name="close" size={14} color={c.foregroundSubtle} />
57
+ <Icon name="close" size={r(14)} color={c.foregroundSubtle} />
45
58
  </Pressable>
46
59
  ) : null
47
60
  }
@@ -1,8 +1,14 @@
1
1
  import type { TextInputProps } from 'react-native';
2
2
 
3
- export type SearchProps = Omit<TextInputProps, 'style'> & {
3
+ // [L-36] Omit 'multiline'/'numberOfLines' —— 搜索框固定单行,这两属性无意义
4
+ export type SearchProps = Omit<
5
+ TextInputProps,
6
+ 'style' | 'multiline' | 'numberOfLines'
7
+ > & {
4
8
  /** 提交回调(按下 return 键时触发) */
5
9
  onSubmit?: (value: string) => void;
6
10
  /** 覆盖 placeholder(默认:搜索…) */
7
11
  placeholder?: string;
12
+ /** E2E / 测试定位 */
13
+ testID?: string;
8
14
  };
@@ -16,6 +16,7 @@ export function Segmented({
16
16
  value,
17
17
  onChange,
18
18
  items,
19
+ disabled = false,
19
20
  testID,
20
21
  }: SegmentedProps): React.JSX.Element {
21
22
  const { colors: c, scheme, shadow } = useTheme();
@@ -24,16 +25,20 @@ export function Segmented({
24
25
  const activeShadow = scheme === 'dark' ? null : shadow.subtle;
25
26
 
26
27
  return (
27
- <View style={styles.seg} testID={testID}>
28
+ // [L-34] accessibilityRole="tablist" —— SR 宣读"标签列表"
29
+ <View style={styles.seg} testID={testID} accessibilityRole="tablist">
28
30
  {items.map((it) => {
29
31
  const on = it.id === value;
30
32
  const itemTestID = childTestID(testID, it.id, it.testID);
33
+ // [L-82] item 禁用 = 整体 disabled OR 单项 it.disabled
34
+ const itemDisabled = disabled || !!it.disabled;
31
35
  return (
32
36
  <Pressable
33
37
  key={it.id}
34
- onPress={() => onChange(it.id)}
38
+ onPress={() => !itemDisabled && onChange(it.id)}
39
+ disabled={itemDisabled}
35
40
  accessibilityRole="tab"
36
- accessibilityState={{ selected: on }}
41
+ accessibilityState={{ selected: on, disabled: itemDisabled }}
37
42
  accessibilityLabel={it.label}
38
43
  testID={itemTestID}
39
44
  style={({ pressed }) => [
@@ -1,6 +1,6 @@
1
1
  import { StyleSheet } from 'react-native';
2
2
  import type { ColorTokens } from '../../../theme';
3
- import { control, r, radius, space, type as t } from '../../../theme';
3
+ import { fixed, r, radius, space, type as t } from '../../../theme';
4
4
 
5
5
  export const makeStyles = (c: ColorTokens) =>
6
6
  StyleSheet.create({
@@ -12,7 +12,9 @@ export const makeStyles = (c: ColorTokens) =>
12
12
  alignSelf: 'flex-start',
13
13
  },
14
14
  segItem: {
15
- height: control.sm,
15
+ // [M-7] Segmented item 高原为 control.sm≈28pt < 44pt;
16
+ // hitSlop 不越父 seg 容器边界 → 改用 minHeight 直接对齐 fixed.hitTarget(44pt)
17
+ minHeight: fixed.hitTarget,
16
18
  paddingHorizontal: space[7],
17
19
  alignItems: 'center',
18
20
  justifyContent: 'center',
@@ -5,6 +5,8 @@ export type SegmentedProps = {
5
5
  value: string;
6
6
  onChange: (id: string) => void;
7
7
  items: TabItem[];
8
+ /** [L-82] 整体禁用 —— 所有 item 不可点击,a11y state 同步 */
9
+ disabled?: boolean;
8
10
  /** 容器 testID;item testID 自动派生为 `${testID}-${id}` */
9
11
  testID?: string;
10
12
  };
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import Animated from 'react-native-reanimated';
3
3
  import { usePulse } from '../Pulse';
4
- import { useColors } from '../../../theme';
4
+ import { r, useColors } from '../../../theme';
5
5
  import type { SkeletonProps } from './types';
6
6
 
7
7
  /**
@@ -13,13 +13,14 @@ import type { SkeletonProps } from './types';
13
13
  * <Skeleton shape="circle" size={40} /> // 头像占位
14
14
  * ```
15
15
  *
16
- * `usePulse({ from: 0.5 })` 全局共享脉冲(Reanimated 4 worklet 驱动 opacity),
17
- * 区别于 chat `Shimmer`(沿 X 横扫高光,流式语义) */
16
+ * `usePulse({ from: 0.5 })` 每实例独立脉冲 —— native 端走 Reanimated 4 worklet,
17
+ * web 端走 CSS transition + setInterval( rAF JS 帧),opacity 在 0.5~1 循环。
18
+ * 区别于沿 X 横扫高光的流式 shimmer。 */
18
19
  export function Skeleton({
19
20
  shape = 'rect',
20
21
  width,
21
22
  height,
22
- size = 40,
23
+ size = r(40),
23
24
  radius,
24
25
  style,
25
26
  testID,
@@ -35,14 +36,14 @@ export function Skeleton({
35
36
  if (shape === 'line') {
36
37
  return {
37
38
  width: width ?? '100%',
38
- height: height ?? 11,
39
- borderRadius: radius ?? 3,
39
+ height: height ?? r(11),
40
+ borderRadius: radius ?? r(3),
40
41
  };
41
42
  }
42
43
  return {
43
44
  width: width ?? '100%',
44
- height: height ?? 80,
45
- borderRadius: radius ?? 8,
45
+ height: height ?? r(80),
46
+ borderRadius: radius ?? r(8),
46
47
  };
47
48
  })();
48
49
 
@@ -2,42 +2,42 @@ import { useEffect } from 'react';
2
2
  import Animated, {
3
3
  cancelAnimation,
4
4
  Easing,
5
+ ReduceMotion,
5
6
  useAnimatedStyle,
6
7
  useSharedValue,
7
8
  withRepeat,
8
9
  withTiming,
9
10
  } from 'react-native-reanimated';
10
- import { useColors } from '../../../theme';
11
- import { createLogger } from '../../../utils/logger';
11
+ import { r, useColors } from '../../../theme';
12
+ import { sanitizeSpinnerProps } from './shared';
12
13
  import type { SpinnerProps } from './types';
13
14
 
14
- const log = createLogger('Spinner');
15
-
16
15
  export function Spinner({
17
- size = 18,
16
+ size = r(18),
18
17
  color,
19
- thickness = 2,
18
+ thickness = r(2),
20
19
  style,
21
20
  testID,
22
21
  }: SpinnerProps) {
23
22
  const c = useColors();
24
23
  const angle = useSharedValue(0);
25
24
  const stroke = color ?? c.primary;
26
- if (!Number.isFinite(size) || (size as number) < 8) {
27
- log.warn(`size 应为 ≥8 的有限数,传入 ${size},已钳到 8`);
28
- }
29
- if (Number.isFinite(thickness) && (thickness as number) <= 0) {
30
- log.warn(`thickness 应为正数,传入 ${thickness},已 fallback 为 2`);
31
- }
32
- const safeSize = Number.isFinite(size) && size > 8 ? size : 8;
33
- const safeThickness =
34
- Number.isFinite(thickness) && thickness > 0 ? thickness : 2;
25
+ const { safeSize, safeThickness } = sanitizeSpinnerProps(size, thickness);
35
26
 
36
27
  useEffect(() => {
28
+ // 加载指示属 essential motion(W3C):系统「减弱动态效果」下仍应旋转,否则会冻结成
29
+ // 与空闲/完成不可区分的静止圆环(形似卡死)。显式 ReduceMotion.Never 覆盖 reanimated
30
+ // 默认的 System —— 后者在 reduce-motion 下让 withTiming 跳端值、withRepeat 一轮即停。
37
31
  angle.value = withRepeat(
38
- withTiming(360, { duration: 900, easing: Easing.linear }),
32
+ withTiming(360, {
33
+ duration: 900,
34
+ easing: Easing.linear,
35
+ reduceMotion: ReduceMotion.Never,
36
+ }),
39
37
  -1,
40
- false
38
+ false,
39
+ undefined,
40
+ ReduceMotion.Never
41
41
  );
42
42
  return () => cancelAnimation(angle);
43
43
  }, [angle]);
@@ -1,11 +1,9 @@
1
1
  import React, { useEffect, useRef } from 'react';
2
2
  import { View } from 'react-native';
3
- import { useColors } from '../../../theme';
4
- import { createLogger } from '../../../utils/logger';
3
+ import { r, useColors } from '../../../theme';
4
+ import { sanitizeSpinnerProps } from './shared';
5
5
  import type { SpinnerProps } from './types';
6
6
 
7
- const log = createLogger('Spinner');
8
-
9
7
  // React-Native-Web 上 reanimated 4 + worklets 0.9.x 的 useAnimatedStyle 链路在
10
8
  // web bundle 里跑会触发 `_updatePropsJS` 里 `Object.keys(updates)` 的 worklet
11
9
  // 回值打包 edge case(animation frame 每帧抛 TypeError),旋转停滞。
@@ -33,9 +31,9 @@ function ensureKeyframes() {
33
31
  }
34
32
 
35
33
  export function Spinner({
36
- size = 18,
34
+ size = r(18),
37
35
  color,
38
- thickness = 2,
36
+ thickness = r(2),
39
37
  style,
40
38
  testID,
41
39
  }: SpinnerProps): React.JSX.Element {
@@ -45,15 +43,7 @@ export function Spinner({
45
43
 
46
44
  const ref = useRef<any>(null);
47
45
  const stroke = color ?? c.primary;
48
- if (!Number.isFinite(size) || (size as number) < 8) {
49
- log.warn(`size 应为 ≥8 的有限数,传入 ${size},已钳到 8`);
50
- }
51
- if (Number.isFinite(thickness) && (thickness as number) <= 0) {
52
- log.warn(`thickness 应为正数,传入 ${thickness},已 fallback 为 2`);
53
- }
54
- const safeSize = Number.isFinite(size) && size > 8 ? size : 8;
55
- const safeThickness =
56
- Number.isFinite(thickness) && thickness > 0 ? thickness : 2;
46
+ const { safeSize, safeThickness } = sanitizeSpinnerProps(size, thickness);
57
47
 
58
48
  // RN-Web 把 View 渲染成 div,我们用 ref 拿到底层 DOM 节点直接挂 CSS animation
59
49
  // (RN style 不支持 animation 字段;只能事后注入)。
@@ -61,6 +51,8 @@ export function Spinner({
61
51
  ensureKeyframes();
62
52
  const node = ref.current;
63
53
  if (node && node.style) {
54
+ // essential motion:加载指示在 prefers-reduced-motion 下仍应旋转(与 native 的
55
+ // ReduceMotion.Never 对齐),故意不加 @media (prefers-reduced-motion) 停转。
64
56
  node.style.animation = 'unif-spinner-spin 900ms linear infinite';
65
57
  }
66
58
  }, []);
@@ -0,0 +1,37 @@
1
+ import { createLogger } from '../../../utils/logger';
2
+
3
+ const log = createLogger('Spinner');
4
+
5
+ /**
6
+ * [M-24][L-11] 入参防御逻辑抽到单一模块,native/web 两端 import 同一份:
7
+ * - 去重 warn:同一异常值只告警一次(模块级 Set 记录),避免渲染路径每帧刷日志。
8
+ * - size / thickness 两字段均覆盖非有限值告警(thickness 原缺失 isFinite 守卫)。
9
+ * - 返回已钳制的安全值,调用方直接使用。
10
+ */
11
+
12
+ const warnedKeys = new Set<string>();
13
+
14
+ function warnOnce(key: string, msg: string) {
15
+ if (warnedKeys.has(key)) return;
16
+ warnedKeys.add(key);
17
+ log.warn(msg);
18
+ }
19
+
20
+ export function sanitizeSpinnerProps(
21
+ size: number,
22
+ thickness: number
23
+ ): { safeSize: number; safeThickness: number } {
24
+ if (!Number.isFinite(size) || size < 8) {
25
+ warnOnce(`size:${size}`, `size 应为 ≥8 的有限数,传入 ${size},已钳到 8`);
26
+ }
27
+ if (!Number.isFinite(thickness) || thickness <= 0) {
28
+ warnOnce(
29
+ `thickness:${thickness}`,
30
+ `thickness 应为正有限数,传入 ${thickness},已 fallback 为 2`
31
+ );
32
+ }
33
+ return {
34
+ safeSize: Number.isFinite(size) && size > 8 ? size : 8,
35
+ safeThickness: Number.isFinite(thickness) && thickness > 0 ? thickness : 2,
36
+ };
37
+ }
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { View } from 'react-native';
3
- import { useColors } from '../../../theme';
3
+ import { r, useColors } from '../../../theme';
4
4
  import { Icon } from '../Icon';
5
5
  import { PulseDot } from '../Pulse';
6
6
  import { paletteFor, styles } from './styles';
@@ -10,14 +10,28 @@ import type { StatusDotProps } from './types';
10
10
  * 任务列表 / 推理链通用的状态圆点。
11
11
  * done = 绿底 + 白勾;active = 边框 + 内部 PulseDot;pending = 仅边框。
12
12
  */
13
+ // status 派生默认 a11y label —— 不传时 SR 仍能播报状态语义。
14
+ const DEFAULT_A11Y: Record<string, string> = {
15
+ pending: 'pending',
16
+ active: 'active',
17
+ done: 'done',
18
+ };
19
+
13
20
  export function StatusDot({
14
21
  status,
15
- size = 16,
22
+ size = r(16),
16
23
  tone = 'flat',
24
+ accessibilityLabel,
25
+ style,
17
26
  testID,
18
27
  }: StatusDotProps): React.JSX.Element {
19
28
  const c = useColors();
20
29
  const { bg, border } = paletteFor(status, tone, c);
30
+ // [L-14] 优先用 caller 传入值;空字符串表示由容器负责播报,不派生默认。
31
+ const a11yLabel =
32
+ accessibilityLabel !== undefined
33
+ ? accessibilityLabel || undefined
34
+ : DEFAULT_A11Y[status];
21
35
 
22
36
  return (
23
37
  <View
@@ -30,7 +44,10 @@ export function StatusDot({
30
44
  backgroundColor: bg,
31
45
  borderColor: border,
32
46
  },
47
+ style,
33
48
  ]}
49
+ accessible={!!a11yLabel}
50
+ accessibilityLabel={a11yLabel}
34
51
  testID={testID}
35
52
  >
36
53
  {status === 'done' ? (
@@ -41,7 +58,8 @@ export function StatusDot({
41
58
  strokeWidth={2.5}
42
59
  />
43
60
  ) : status === 'active' ? (
44
- <PulseDot />
61
+ // [L-13] size 随外圈等比派生(系数 0.375 ≈ 6/16),视觉居中且不溢出。
62
+ <PulseDot size={Math.round(size * 0.375)} />
45
63
  ) : null}
46
64
  </View>
47
65
  );
@@ -16,7 +16,7 @@ export const styles = StyleSheet.create({
16
16
  });
17
17
 
18
18
  /** StatusDot 颜色推导:status × tone → { bg, border } 二色,全走 ColorTokens。
19
- * 签名 `(target, context, tokens)` 与 Tag/Tool 的 paletteFor 一致。
19
+ * 与 Tag/Button 的 paletteFor 同约定(状态入参 + ColorTokens → 配色对象),多一维 tone。
20
20
  * `flat` = pending/active 底色透明;`soft` = pending 走 surface、active 走 primaryContainer。 */
21
21
  export function paletteFor(
22
22
  status: StatusDotStatus,
@@ -1,8 +1,10 @@
1
+ import type { StyleProp, ViewStyle } from 'react-native';
2
+
1
3
  export type StatusDotStatus = 'pending' | 'active' | 'done';
2
4
 
3
5
  /**
4
6
  * `flat`:pending/active 底色透明(任务列表风格)。
5
- * `soft`:pending = bgCard、active = primary0,常用于推理链。
7
+ * `soft`:pending = surface、active = primaryContainer,常用于推理链。
6
8
  */
7
9
  export type StatusDotTone = 'flat' | 'soft';
8
10
 
@@ -10,6 +12,17 @@ export type StatusDotProps = {
10
12
  status: StatusDotStatus;
11
13
  size?: number;
12
14
  tone?: StatusDotTone;
15
+ /**
16
+ * [L-14] Screen Reader 朗读文本。
17
+ * 不传时按 status 派生默认值("pending" / "active" / "done")。
18
+ * 若状态语义已由父容器的 accessibilityLabel 覆盖,可传空字符串 "" 屏蔽默认值。
19
+ *
20
+ * 注:StatusDot 本身属于装饰性图标,状态语义通常由容器(列表行 / 任务项)负责播报;
21
+ * 对于需要独立播报的场景(独立状态指示器),请通过此 prop 传入有意义的描述。
22
+ */
23
+ accessibilityLabel?: string;
24
+ /** 容器附加样式(margin / position 等布局微调)。 */
25
+ style?: StyleProp<ViewStyle>;
13
26
  /** E2E / 测试定位 */
14
27
  testID?: string;
15
28
  };