@unif/react-native-design 0.19.0 → 0.21.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 (566) hide show
  1. package/README.md +68 -12
  2. package/lib/module/components/business/AvatarWithRing/AvatarWithRing.js +4 -5
  3. package/lib/module/components/business/AvatarWithRing/AvatarWithRing.js.map +1 -1
  4. package/lib/module/components/business/AvatarWithRing/styles.js +10 -9
  5. package/lib/module/components/business/AvatarWithRing/styles.js.map +1 -1
  6. package/lib/module/components/business/VersionPill/VersionPill.js +32 -15
  7. package/lib/module/components/business/VersionPill/VersionPill.js.map +1 -1
  8. package/lib/module/components/business/VersionPill/content.js +30 -0
  9. package/lib/module/components/business/VersionPill/content.js.map +1 -0
  10. package/lib/module/components/business/VersionPill/styles.js +4 -0
  11. package/lib/module/components/business/VersionPill/styles.js.map +1 -1
  12. package/lib/module/components/business/useSvgId.js +17 -8
  13. package/lib/module/components/business/useSvgId.js.map +1 -1
  14. package/lib/module/components/ui/Avatar/Avatar.js +22 -29
  15. package/lib/module/components/ui/Avatar/Avatar.js.map +1 -1
  16. package/lib/module/components/ui/Button/Button.js +40 -23
  17. package/lib/module/components/ui/Button/Button.js.map +1 -1
  18. package/lib/module/components/ui/Button/ButtonBase.js +13 -13
  19. package/lib/module/components/ui/Button/ButtonBase.js.map +1 -1
  20. package/lib/module/components/ui/Carousel/Carousel.js +89 -65
  21. package/lib/module/components/ui/Carousel/Carousel.js.map +1 -1
  22. package/lib/module/components/ui/Carousel/behavior.js +60 -0
  23. package/lib/module/components/ui/Carousel/behavior.js.map +1 -0
  24. package/lib/module/components/ui/Carousel/styles.js +9 -14
  25. package/lib/module/components/ui/Carousel/styles.js.map +1 -1
  26. package/lib/module/components/ui/Cell/Cell.js +76 -65
  27. package/lib/module/components/ui/Cell/Cell.js.map +1 -1
  28. package/lib/module/components/ui/Cell/Leading.js +11 -5
  29. package/lib/module/components/ui/Cell/Leading.js.map +1 -1
  30. package/lib/module/components/ui/Cell/content.js +34 -0
  31. package/lib/module/components/ui/Cell/content.js.map +1 -0
  32. package/lib/module/components/ui/Checkbox/Checkbox.js +25 -8
  33. package/lib/module/components/ui/Checkbox/Checkbox.js.map +1 -1
  34. package/lib/module/components/ui/Confirm/ConfirmHost.js +49 -25
  35. package/lib/module/components/ui/Confirm/ConfirmHost.js.map +1 -1
  36. package/lib/module/components/ui/Confirm/confirm.js +15 -29
  37. package/lib/module/components/ui/Confirm/confirm.js.map +1 -1
  38. package/lib/module/components/ui/Confirm/labels.js +10 -0
  39. package/lib/module/components/ui/Confirm/labels.js.map +1 -0
  40. package/lib/module/components/ui/Confirm/store.js +113 -0
  41. package/lib/module/components/ui/Confirm/store.js.map +1 -0
  42. package/lib/module/components/ui/Confirm/styles.js +4 -0
  43. package/lib/module/components/ui/Confirm/styles.js.map +1 -1
  44. package/lib/module/components/ui/DrawerHeader/DrawerHeader.js +17 -25
  45. package/lib/module/components/ui/DrawerHeader/DrawerHeader.js.map +1 -1
  46. package/lib/module/components/ui/Grid/Grid.js +26 -9
  47. package/lib/module/components/ui/Grid/Grid.js.map +1 -1
  48. package/lib/module/components/ui/Grid/accessibility.js +13 -0
  49. package/lib/module/components/ui/Grid/accessibility.js.map +1 -0
  50. package/lib/module/components/ui/IconButton/IconButton.js +16 -3
  51. package/lib/module/components/ui/IconButton/IconButton.js.map +1 -1
  52. package/lib/module/components/ui/Input/Input.js +8 -5
  53. package/lib/module/components/ui/Input/Input.js.map +1 -1
  54. package/lib/module/components/ui/Logo/Logo.js +22 -4
  55. package/lib/module/components/ui/Logo/Logo.js.map +1 -1
  56. package/lib/module/components/ui/NavBar/NavBar.js +23 -14
  57. package/lib/module/components/ui/NavBar/NavBar.js.map +1 -1
  58. package/lib/module/components/ui/NavBar/isSlot.js +297 -4
  59. package/lib/module/components/ui/NavBar/isSlot.js.map +1 -1
  60. package/lib/module/components/ui/PasswordInput/PasswordInput.js +61 -66
  61. package/lib/module/components/ui/PasswordInput/PasswordInput.js.map +1 -1
  62. package/lib/module/components/ui/Pulse/Pulse.js +1 -1
  63. package/lib/module/components/ui/Pulse/Pulse.js.map +1 -1
  64. package/lib/module/components/ui/Pulse/PulseDot.js +5 -7
  65. package/lib/module/components/ui/Pulse/PulseDot.js.map +1 -1
  66. package/lib/module/components/ui/Pulse/index.js +1 -1
  67. package/lib/module/components/ui/Pulse/index.js.map +1 -1
  68. package/lib/module/components/ui/Pulse/normalizePulseOptions.js +45 -0
  69. package/lib/module/components/ui/Pulse/normalizePulseOptions.js.map +1 -0
  70. package/lib/module/components/ui/Pulse/usePulse.js +61 -24
  71. package/lib/module/components/ui/Pulse/usePulse.js.map +1 -1
  72. package/lib/module/components/ui/Pulse/usePulseDriver.js +44 -0
  73. package/lib/module/components/ui/Pulse/usePulseDriver.js.map +1 -0
  74. package/lib/module/components/ui/Pulse/usePulseDriver.web.js +67 -0
  75. package/lib/module/components/ui/Pulse/usePulseDriver.web.js.map +1 -0
  76. package/lib/module/components/ui/Radio/Radio.js +31 -14
  77. package/lib/module/components/ui/Radio/Radio.js.map +1 -1
  78. package/lib/module/components/ui/Radio/RadioGroup.js +15 -2
  79. package/lib/module/components/ui/Radio/RadioGroup.js.map +1 -1
  80. package/lib/module/components/ui/Reveal/Reveal.js +4 -3
  81. package/lib/module/components/ui/Reveal/Reveal.js.map +1 -1
  82. package/lib/module/components/ui/Reveal/Reveal.web.js +55 -32
  83. package/lib/module/components/ui/Reveal/Reveal.web.js.map +1 -1
  84. package/lib/module/components/ui/Reveal/webTransition.js +157 -0
  85. package/lib/module/components/ui/Reveal/webTransition.js.map +1 -0
  86. package/lib/module/components/ui/Search/Search.js +85 -58
  87. package/lib/module/components/ui/Search/Search.js.map +1 -1
  88. package/lib/module/components/ui/Segmented/Segmented.js +4 -2
  89. package/lib/module/components/ui/Segmented/Segmented.js.map +1 -1
  90. package/lib/module/components/ui/Skeleton/Skeleton.js +5 -7
  91. package/lib/module/components/ui/Skeleton/Skeleton.js.map +1 -1
  92. package/lib/module/components/ui/Spinner/Spinner.js +18 -11
  93. package/lib/module/components/ui/Spinner/Spinner.js.map +1 -1
  94. package/lib/module/components/ui/Spinner/Spinner.web.js +18 -14
  95. package/lib/module/components/ui/Spinner/Spinner.web.js.map +1 -1
  96. package/lib/module/components/ui/Spinner/shared.js +6 -0
  97. package/lib/module/components/ui/Spinner/shared.js.map +1 -1
  98. package/lib/module/components/ui/Stepper/Stepper.js +131 -99
  99. package/lib/module/components/ui/Stepper/Stepper.js.map +1 -1
  100. package/lib/module/components/ui/Stepper/StepperPressable.js +4 -0
  101. package/lib/module/components/ui/Stepper/StepperPressable.js.map +1 -0
  102. package/lib/module/components/ui/Stepper/StepperPressable.web.js +4 -0
  103. package/lib/module/components/ui/Stepper/StepperPressable.web.js.map +1 -0
  104. package/lib/module/components/ui/Stepper/accessibility.js +30 -0
  105. package/lib/module/components/ui/Stepper/accessibility.js.map +1 -0
  106. package/lib/module/components/ui/Stepper/accessibility.types.js +4 -0
  107. package/lib/module/components/ui/Stepper/accessibility.types.js.map +1 -0
  108. package/lib/module/components/ui/Stepper/accessibility.web.js +57 -0
  109. package/lib/module/components/ui/Stepper/accessibility.web.js.map +1 -0
  110. package/lib/module/components/ui/Stepper/layout.js +28 -0
  111. package/lib/module/components/ui/Stepper/layout.js.map +1 -0
  112. package/lib/module/components/ui/Stepper/normalizeStepper.js +53 -0
  113. package/lib/module/components/ui/Stepper/normalizeStepper.js.map +1 -0
  114. package/lib/module/components/ui/Stepper/styles.js +9 -2
  115. package/lib/module/components/ui/Stepper/styles.js.map +1 -1
  116. package/lib/module/components/ui/Switch/Switch.js +45 -19
  117. package/lib/module/components/ui/Switch/Switch.js.map +1 -1
  118. package/lib/module/components/ui/Switch/Switch.web.js +47 -20
  119. package/lib/module/components/ui/Switch/Switch.web.js.map +1 -1
  120. package/lib/module/components/ui/Switch/styles.js +12 -5
  121. package/lib/module/components/ui/Switch/styles.js.map +1 -1
  122. package/lib/module/components/ui/Tag/Tag.js +3 -2
  123. package/lib/module/components/ui/Tag/Tag.js.map +1 -1
  124. package/lib/module/components/ui/TextField/TextFieldBase.js +131 -86
  125. package/lib/module/components/ui/TextField/TextFieldBase.js.map +1 -1
  126. package/lib/module/components/ui/TextField/TextFieldSlot.js +82 -0
  127. package/lib/module/components/ui/TextField/TextFieldSlot.js.map +1 -0
  128. package/lib/module/components/ui/TextField/normalize.js +238 -0
  129. package/lib/module/components/ui/TextField/normalize.js.map +1 -0
  130. package/lib/module/components/ui/TextField/styles.js +31 -0
  131. package/lib/module/components/ui/TextField/styles.js.map +1 -1
  132. package/lib/module/components/ui/TextField/useErrorAnnouncement.js +27 -0
  133. package/lib/module/components/ui/TextField/useErrorAnnouncement.js.map +1 -0
  134. package/lib/module/components/ui/TextField/useTextFieldValue.js +66 -0
  135. package/lib/module/components/ui/TextField/useTextFieldValue.js.map +1 -0
  136. package/lib/module/components/ui/TextField/valueState.js +93 -0
  137. package/lib/module/components/ui/TextField/valueState.js.map +1 -0
  138. package/lib/module/components/ui/Textarea/Textarea.js +7 -3
  139. package/lib/module/components/ui/Textarea/Textarea.js.map +1 -1
  140. package/lib/module/components/ui/Thumbnail/Thumbnail.js +67 -48
  141. package/lib/module/components/ui/Thumbnail/Thumbnail.js.map +1 -1
  142. package/lib/module/components/ui/Thumbnail/normalize.js +58 -0
  143. package/lib/module/components/ui/Thumbnail/normalize.js.map +1 -0
  144. package/lib/module/components/ui/Thumbnail/styles.js +6 -11
  145. package/lib/module/components/ui/Thumbnail/styles.js.map +1 -1
  146. package/lib/module/components/ui/Toast/ToastHost.js +64 -21
  147. package/lib/module/components/ui/Toast/ToastHost.js.map +1 -1
  148. package/lib/module/components/ui/Toast/ToastHost.web.js +73 -24
  149. package/lib/module/components/ui/Toast/ToastHost.web.js.map +1 -1
  150. package/lib/module/components/ui/Toast/store.js +110 -0
  151. package/lib/module/components/ui/Toast/store.js.map +1 -0
  152. package/lib/module/components/ui/Toast/toast.js +17 -7
  153. package/lib/module/components/ui/Toast/toast.js.map +1 -1
  154. package/lib/module/components/ui/index.js.map +1 -1
  155. package/lib/module/components/ui/shared/ImageAttempt.js +28 -0
  156. package/lib/module/components/ui/shared/ImageAttempt.js.map +1 -0
  157. package/lib/module/components/ui/shared/a11y.js +21 -0
  158. package/lib/module/components/ui/shared/a11y.js.map +1 -0
  159. package/lib/module/components/ui/shared/accessibilityName.js +9 -0
  160. package/lib/module/components/ui/shared/accessibilityName.js.map +1 -0
  161. package/lib/module/components/ui/shared/selectImageAttemptSource.js +5 -0
  162. package/lib/module/components/ui/shared/selectImageAttemptSource.js.map +1 -0
  163. package/lib/module/components/ui/shared/selectImageAttemptSource.shared.js +13 -0
  164. package/lib/module/components/ui/shared/selectImageAttemptSource.shared.js.map +1 -0
  165. package/lib/module/components/ui/shared/selectImageAttemptSource.web.js +5 -0
  166. package/lib/module/components/ui/shared/selectImageAttemptSource.web.js.map +1 -0
  167. package/lib/module/icons/data.js +1 -1
  168. package/lib/module/icons/data.js.map +1 -1
  169. package/lib/module/theme/ThemeProvider.js +14 -4
  170. package/lib/module/theme/ThemeProvider.js.map +1 -1
  171. package/lib/module/theme/fontScale.js +13 -0
  172. package/lib/module/theme/fontScale.js.map +1 -0
  173. package/lib/module/theme/index.js +2 -4
  174. package/lib/module/theme/index.js.map +1 -1
  175. package/lib/module/theme/themeContext.js +15 -0
  176. package/lib/module/theme/themeContext.js.map +1 -0
  177. package/lib/module/theme/themeDiagnostics.js +29 -0
  178. package/lib/module/theme/themeDiagnostics.js.map +1 -0
  179. package/lib/module/theme/usePrefersReducedMotion.js +11 -4
  180. package/lib/module/theme/usePrefersReducedMotion.js.map +1 -1
  181. package/lib/module/theme/usePrefersReducedMotion.web.js +5 -2
  182. package/lib/module/theme/usePrefersReducedMotion.web.js.map +1 -1
  183. package/lib/module/theme/useTheme.js +12 -25
  184. package/lib/module/theme/useTheme.js.map +1 -1
  185. package/lib/module/theme/useThemedStyles.js +9 -6
  186. package/lib/module/theme/useThemedStyles.js.map +1 -1
  187. package/lib/module/utils/imageSource.js +198 -0
  188. package/lib/module/utils/imageSource.js.map +1 -0
  189. package/lib/typescript/manual-tests/runtime-api/RuntimeApiScreen.d.ts +12 -0
  190. package/lib/typescript/manual-tests/runtime-api/RuntimeApiScreen.d.ts.map +1 -0
  191. package/lib/typescript/src/components/business/AvatarWithRing/AvatarWithRing.d.ts.map +1 -1
  192. package/lib/typescript/src/components/business/AvatarWithRing/styles.d.ts +8 -7
  193. package/lib/typescript/src/components/business/AvatarWithRing/styles.d.ts.map +1 -1
  194. package/lib/typescript/src/components/business/VersionPill/VersionPill.d.ts +1 -1
  195. package/lib/typescript/src/components/business/VersionPill/VersionPill.d.ts.map +1 -1
  196. package/lib/typescript/src/components/business/VersionPill/content.d.ts +19 -0
  197. package/lib/typescript/src/components/business/VersionPill/content.d.ts.map +1 -0
  198. package/lib/typescript/src/components/business/VersionPill/index.d.ts +1 -1
  199. package/lib/typescript/src/components/business/VersionPill/index.d.ts.map +1 -1
  200. package/lib/typescript/src/components/business/VersionPill/styles.d.ts +4 -0
  201. package/lib/typescript/src/components/business/VersionPill/styles.d.ts.map +1 -1
  202. package/lib/typescript/src/components/business/VersionPill/types.d.ts +6 -2
  203. package/lib/typescript/src/components/business/VersionPill/types.d.ts.map +1 -1
  204. package/lib/typescript/src/components/business/index.d.ts +1 -1
  205. package/lib/typescript/src/components/business/index.d.ts.map +1 -1
  206. package/lib/typescript/src/components/business/useSvgId.d.ts +6 -5
  207. package/lib/typescript/src/components/business/useSvgId.d.ts.map +1 -1
  208. package/lib/typescript/src/components/ui/Avatar/Avatar.d.ts +2 -2
  209. package/lib/typescript/src/components/ui/Avatar/Avatar.d.ts.map +1 -1
  210. package/lib/typescript/src/components/ui/Avatar/types.d.ts +6 -2
  211. package/lib/typescript/src/components/ui/Avatar/types.d.ts.map +1 -1
  212. package/lib/typescript/src/components/ui/Button/Button.d.ts +1 -1
  213. package/lib/typescript/src/components/ui/Button/Button.d.ts.map +1 -1
  214. package/lib/typescript/src/components/ui/Button/ButtonBase.d.ts +5 -3
  215. package/lib/typescript/src/components/ui/Button/ButtonBase.d.ts.map +1 -1
  216. package/lib/typescript/src/components/ui/Button/types.d.ts +5 -3
  217. package/lib/typescript/src/components/ui/Button/types.d.ts.map +1 -1
  218. package/lib/typescript/src/components/ui/Carousel/Carousel.d.ts +3 -3
  219. package/lib/typescript/src/components/ui/Carousel/Carousel.d.ts.map +1 -1
  220. package/lib/typescript/src/components/ui/Carousel/behavior.d.ts +25 -0
  221. package/lib/typescript/src/components/ui/Carousel/behavior.d.ts.map +1 -0
  222. package/lib/typescript/src/components/ui/Carousel/index.d.ts +1 -1
  223. package/lib/typescript/src/components/ui/Carousel/index.d.ts.map +1 -1
  224. package/lib/typescript/src/components/ui/Carousel/styles.d.ts +7 -12
  225. package/lib/typescript/src/components/ui/Carousel/styles.d.ts.map +1 -1
  226. package/lib/typescript/src/components/ui/Carousel/types.d.ts +28 -17
  227. package/lib/typescript/src/components/ui/Carousel/types.d.ts.map +1 -1
  228. package/lib/typescript/src/components/ui/Cell/Cell.d.ts +1 -1
  229. package/lib/typescript/src/components/ui/Cell/Cell.d.ts.map +1 -1
  230. package/lib/typescript/src/components/ui/Cell/Leading.d.ts +2 -3
  231. package/lib/typescript/src/components/ui/Cell/Leading.d.ts.map +1 -1
  232. package/lib/typescript/src/components/ui/Cell/content.d.ts +18 -0
  233. package/lib/typescript/src/components/ui/Cell/content.d.ts.map +1 -0
  234. package/lib/typescript/src/components/ui/Cell/index.d.ts +1 -1
  235. package/lib/typescript/src/components/ui/Cell/index.d.ts.map +1 -1
  236. package/lib/typescript/src/components/ui/Cell/types.d.ts +66 -30
  237. package/lib/typescript/src/components/ui/Cell/types.d.ts.map +1 -1
  238. package/lib/typescript/src/components/ui/Checkbox/Checkbox.d.ts +1 -1
  239. package/lib/typescript/src/components/ui/Checkbox/Checkbox.d.ts.map +1 -1
  240. package/lib/typescript/src/components/ui/Checkbox/types.d.ts +12 -3
  241. package/lib/typescript/src/components/ui/Checkbox/types.d.ts.map +1 -1
  242. package/lib/typescript/src/components/ui/Confirm/ConfirmHost.d.ts +6 -3
  243. package/lib/typescript/src/components/ui/Confirm/ConfirmHost.d.ts.map +1 -1
  244. package/lib/typescript/src/components/ui/Confirm/confirm.d.ts +10 -4
  245. package/lib/typescript/src/components/ui/Confirm/confirm.d.ts.map +1 -1
  246. package/lib/typescript/src/components/ui/Confirm/labels.d.ts +6 -0
  247. package/lib/typescript/src/components/ui/Confirm/labels.d.ts.map +1 -0
  248. package/lib/typescript/src/components/ui/Confirm/store.d.ts +44 -0
  249. package/lib/typescript/src/components/ui/Confirm/store.d.ts.map +1 -0
  250. package/lib/typescript/src/components/ui/Confirm/styles.d.ts +3 -0
  251. package/lib/typescript/src/components/ui/Confirm/styles.d.ts.map +1 -1
  252. package/lib/typescript/src/components/ui/Confirm/types.d.ts +0 -9
  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.map +1 -1
  255. package/lib/typescript/src/components/ui/DrawerHeader/types.d.ts +7 -1
  256. package/lib/typescript/src/components/ui/DrawerHeader/types.d.ts.map +1 -1
  257. package/lib/typescript/src/components/ui/Grid/Grid.d.ts.map +1 -1
  258. package/lib/typescript/src/components/ui/Grid/accessibility.d.ts +5 -0
  259. package/lib/typescript/src/components/ui/Grid/accessibility.d.ts.map +1 -0
  260. package/lib/typescript/src/components/ui/Grid/types.d.ts +2 -0
  261. package/lib/typescript/src/components/ui/Grid/types.d.ts.map +1 -1
  262. package/lib/typescript/src/components/ui/IconButton/IconButton.d.ts +1 -1
  263. package/lib/typescript/src/components/ui/IconButton/IconButton.d.ts.map +1 -1
  264. package/lib/typescript/src/components/ui/IconButton/types.d.ts +4 -2
  265. package/lib/typescript/src/components/ui/IconButton/types.d.ts.map +1 -1
  266. package/lib/typescript/src/components/ui/Input/Input.d.ts +5 -383
  267. package/lib/typescript/src/components/ui/Input/Input.d.ts.map +1 -1
  268. package/lib/typescript/src/components/ui/Input/index.d.ts +1 -0
  269. package/lib/typescript/src/components/ui/Input/index.d.ts.map +1 -1
  270. package/lib/typescript/src/components/ui/Input/types.d.ts +3 -17
  271. package/lib/typescript/src/components/ui/Input/types.d.ts.map +1 -1
  272. package/lib/typescript/src/components/ui/Logo/Logo.d.ts +2 -2
  273. package/lib/typescript/src/components/ui/Logo/Logo.d.ts.map +1 -1
  274. package/lib/typescript/src/components/ui/Logo/types.d.ts +2 -2
  275. package/lib/typescript/src/components/ui/Logo/types.d.ts.map +1 -1
  276. package/lib/typescript/src/components/ui/NavBar/NavBar.d.ts.map +1 -1
  277. package/lib/typescript/src/components/ui/NavBar/index.d.ts +1 -1
  278. package/lib/typescript/src/components/ui/NavBar/index.d.ts.map +1 -1
  279. package/lib/typescript/src/components/ui/NavBar/isSlot.d.ts +24 -4
  280. package/lib/typescript/src/components/ui/NavBar/isSlot.d.ts.map +1 -1
  281. package/lib/typescript/src/components/ui/NavBar/types.d.ts +8 -8
  282. package/lib/typescript/src/components/ui/NavBar/types.d.ts.map +1 -1
  283. package/lib/typescript/src/components/ui/PasswordInput/PasswordInput.d.ts +6 -14
  284. package/lib/typescript/src/components/ui/PasswordInput/PasswordInput.d.ts.map +1 -1
  285. package/lib/typescript/src/components/ui/PasswordInput/types.d.ts +4 -14
  286. package/lib/typescript/src/components/ui/PasswordInput/types.d.ts.map +1 -1
  287. package/lib/typescript/src/components/ui/Pulse/PulseDot.d.ts +1 -1
  288. package/lib/typescript/src/components/ui/Pulse/PulseDot.d.ts.map +1 -1
  289. package/lib/typescript/src/components/ui/Pulse/normalizePulseOptions.d.ts +32 -0
  290. package/lib/typescript/src/components/ui/Pulse/normalizePulseOptions.d.ts.map +1 -0
  291. package/lib/typescript/src/components/ui/Pulse/usePulse.d.ts +10 -5
  292. package/lib/typescript/src/components/ui/Pulse/usePulse.d.ts.map +1 -1
  293. package/lib/typescript/src/components/ui/Pulse/usePulseDriver.d.ts +11 -0
  294. package/lib/typescript/src/components/ui/Pulse/usePulseDriver.d.ts.map +1 -0
  295. package/lib/typescript/src/components/ui/Pulse/usePulseDriver.web.d.ts +18 -0
  296. package/lib/typescript/src/components/ui/Pulse/usePulseDriver.web.d.ts.map +1 -0
  297. package/lib/typescript/src/components/ui/Radio/Radio.d.ts +1 -1
  298. package/lib/typescript/src/components/ui/Radio/Radio.d.ts.map +1 -1
  299. package/lib/typescript/src/components/ui/Radio/RadioGroup.d.ts +2 -2
  300. package/lib/typescript/src/components/ui/Radio/RadioGroup.d.ts.map +1 -1
  301. package/lib/typescript/src/components/ui/Radio/types.d.ts +14 -3
  302. package/lib/typescript/src/components/ui/Radio/types.d.ts.map +1 -1
  303. package/lib/typescript/src/components/ui/Reveal/Reveal.d.ts.map +1 -1
  304. package/lib/typescript/src/components/ui/Reveal/Reveal.web.d.ts +2 -8
  305. package/lib/typescript/src/components/ui/Reveal/Reveal.web.d.ts.map +1 -1
  306. package/lib/typescript/src/components/ui/Reveal/types.d.ts +1 -1
  307. package/lib/typescript/src/components/ui/Reveal/types.d.ts.map +1 -1
  308. package/lib/typescript/src/components/ui/Reveal/webTransition.d.ts +38 -0
  309. package/lib/typescript/src/components/ui/Reveal/webTransition.d.ts.map +1 -0
  310. package/lib/typescript/src/components/ui/Search/Search.d.ts +4 -214
  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 +13 -6
  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.map +1 -1
  315. package/lib/typescript/src/components/ui/Skeleton/Skeleton.d.ts +3 -3
  316. package/lib/typescript/src/components/ui/Skeleton/Skeleton.d.ts.map +1 -1
  317. package/lib/typescript/src/components/ui/Spinner/Spinner.d.ts +1 -1
  318. package/lib/typescript/src/components/ui/Spinner/Spinner.d.ts.map +1 -1
  319. package/lib/typescript/src/components/ui/Spinner/Spinner.web.d.ts +1 -1
  320. package/lib/typescript/src/components/ui/Spinner/Spinner.web.d.ts.map +1 -1
  321. package/lib/typescript/src/components/ui/Spinner/shared.d.ts +5 -0
  322. package/lib/typescript/src/components/ui/Spinner/shared.d.ts.map +1 -1
  323. package/lib/typescript/src/components/ui/Spinner/types.d.ts +1 -1
  324. package/lib/typescript/src/components/ui/Spinner/types.d.ts.map +1 -1
  325. package/lib/typescript/src/components/ui/Stepper/Stepper.d.ts +3 -3
  326. package/lib/typescript/src/components/ui/Stepper/Stepper.d.ts.map +1 -1
  327. package/lib/typescript/src/components/ui/Stepper/StepperPressable.d.ts +2 -0
  328. package/lib/typescript/src/components/ui/Stepper/StepperPressable.d.ts.map +1 -0
  329. package/lib/typescript/src/components/ui/Stepper/StepperPressable.web.d.ts +2 -0
  330. package/lib/typescript/src/components/ui/Stepper/StepperPressable.web.d.ts.map +1 -0
  331. package/lib/typescript/src/components/ui/Stepper/accessibility.d.ts +3 -0
  332. package/lib/typescript/src/components/ui/Stepper/accessibility.d.ts.map +1 -0
  333. package/lib/typescript/src/components/ui/Stepper/accessibility.types.d.ts +23 -0
  334. package/lib/typescript/src/components/ui/Stepper/accessibility.types.d.ts.map +1 -0
  335. package/lib/typescript/src/components/ui/Stepper/accessibility.web.d.ts +9 -0
  336. package/lib/typescript/src/components/ui/Stepper/accessibility.web.d.ts.map +1 -0
  337. package/lib/typescript/src/components/ui/Stepper/layout.d.ts +22 -0
  338. package/lib/typescript/src/components/ui/Stepper/layout.d.ts.map +1 -0
  339. package/lib/typescript/src/components/ui/Stepper/normalizeStepper.d.ts +31 -0
  340. package/lib/typescript/src/components/ui/Stepper/normalizeStepper.d.ts.map +1 -0
  341. package/lib/typescript/src/components/ui/Stepper/styles.d.ts +9 -2
  342. package/lib/typescript/src/components/ui/Stepper/styles.d.ts.map +1 -1
  343. package/lib/typescript/src/components/ui/Stepper/types.d.ts +3 -1
  344. package/lib/typescript/src/components/ui/Stepper/types.d.ts.map +1 -1
  345. package/lib/typescript/src/components/ui/Switch/Switch.d.ts.map +1 -1
  346. package/lib/typescript/src/components/ui/Switch/Switch.web.d.ts.map +1 -1
  347. package/lib/typescript/src/components/ui/Switch/styles.d.ts +9 -3
  348. package/lib/typescript/src/components/ui/Switch/styles.d.ts.map +1 -1
  349. package/lib/typescript/src/components/ui/Switch/types.d.ts +2 -2
  350. package/lib/typescript/src/components/ui/Switch/types.d.ts.map +1 -1
  351. package/lib/typescript/src/components/ui/Tag/Tag.d.ts.map +1 -1
  352. package/lib/typescript/src/components/ui/TextField/TextFieldBase.d.ts +4 -401
  353. package/lib/typescript/src/components/ui/TextField/TextFieldBase.d.ts.map +1 -1
  354. package/lib/typescript/src/components/ui/TextField/TextFieldSlot.d.ts +13 -0
  355. package/lib/typescript/src/components/ui/TextField/TextFieldSlot.d.ts.map +1 -0
  356. package/lib/typescript/src/components/ui/TextField/normalize.d.ts +51 -0
  357. package/lib/typescript/src/components/ui/TextField/normalize.d.ts.map +1 -0
  358. package/lib/typescript/src/components/ui/TextField/styles.d.ts +30 -0
  359. package/lib/typescript/src/components/ui/TextField/styles.d.ts.map +1 -1
  360. package/lib/typescript/src/components/ui/TextField/types.d.ts +92 -18
  361. package/lib/typescript/src/components/ui/TextField/types.d.ts.map +1 -1
  362. package/lib/typescript/src/components/ui/TextField/useErrorAnnouncement.d.ts +3 -0
  363. package/lib/typescript/src/components/ui/TextField/useErrorAnnouncement.d.ts.map +1 -0
  364. package/lib/typescript/src/components/ui/TextField/useTextFieldValue.d.ts +18 -0
  365. package/lib/typescript/src/components/ui/TextField/useTextFieldValue.d.ts.map +1 -0
  366. package/lib/typescript/src/components/ui/TextField/valueState.d.ts +50 -0
  367. package/lib/typescript/src/components/ui/TextField/valueState.d.ts.map +1 -0
  368. package/lib/typescript/src/components/ui/Textarea/Textarea.d.ts +4 -382
  369. package/lib/typescript/src/components/ui/Textarea/Textarea.d.ts.map +1 -1
  370. package/lib/typescript/src/components/ui/Textarea/index.d.ts +1 -0
  371. package/lib/typescript/src/components/ui/Textarea/index.d.ts.map +1 -1
  372. package/lib/typescript/src/components/ui/Textarea/types.d.ts +3 -14
  373. package/lib/typescript/src/components/ui/Textarea/types.d.ts.map +1 -1
  374. package/lib/typescript/src/components/ui/Thumbnail/Thumbnail.d.ts +5 -12
  375. package/lib/typescript/src/components/ui/Thumbnail/Thumbnail.d.ts.map +1 -1
  376. package/lib/typescript/src/components/ui/Thumbnail/index.d.ts +1 -1
  377. package/lib/typescript/src/components/ui/Thumbnail/index.d.ts.map +1 -1
  378. package/lib/typescript/src/components/ui/Thumbnail/normalize.d.ts +13 -0
  379. package/lib/typescript/src/components/ui/Thumbnail/normalize.d.ts.map +1 -0
  380. package/lib/typescript/src/components/ui/Thumbnail/styles.d.ts +4 -8
  381. package/lib/typescript/src/components/ui/Thumbnail/styles.d.ts.map +1 -1
  382. package/lib/typescript/src/components/ui/Thumbnail/types.d.ts +21 -13
  383. package/lib/typescript/src/components/ui/Thumbnail/types.d.ts.map +1 -1
  384. package/lib/typescript/src/components/ui/Toast/ToastHost.d.ts +6 -2
  385. package/lib/typescript/src/components/ui/Toast/ToastHost.d.ts.map +1 -1
  386. package/lib/typescript/src/components/ui/Toast/ToastHost.web.d.ts +6 -3
  387. package/lib/typescript/src/components/ui/Toast/ToastHost.web.d.ts.map +1 -1
  388. package/lib/typescript/src/components/ui/Toast/store.d.ts +39 -0
  389. package/lib/typescript/src/components/ui/Toast/store.d.ts.map +1 -0
  390. package/lib/typescript/src/components/ui/Toast/toast.d.ts +7 -2
  391. package/lib/typescript/src/components/ui/Toast/toast.d.ts.map +1 -1
  392. package/lib/typescript/src/components/ui/Toast/types.d.ts +5 -3
  393. package/lib/typescript/src/components/ui/Toast/types.d.ts.map +1 -1
  394. package/lib/typescript/src/components/ui/index.d.ts +5 -5
  395. package/lib/typescript/src/components/ui/index.d.ts.map +1 -1
  396. package/lib/typescript/src/components/ui/shared/ImageAttempt.d.ts +13 -0
  397. package/lib/typescript/src/components/ui/shared/ImageAttempt.d.ts.map +1 -0
  398. package/lib/typescript/src/components/ui/shared/a11y.d.ts +19 -0
  399. package/lib/typescript/src/components/ui/shared/a11y.d.ts.map +1 -0
  400. package/lib/typescript/src/components/ui/shared/accessibilityName.d.ts +3 -0
  401. package/lib/typescript/src/components/ui/shared/accessibilityName.d.ts.map +1 -0
  402. package/lib/typescript/src/components/ui/shared/selectImageAttemptSource.d.ts +3 -0
  403. package/lib/typescript/src/components/ui/shared/selectImageAttemptSource.d.ts.map +1 -0
  404. package/lib/typescript/src/components/ui/shared/selectImageAttemptSource.shared.d.ts +4 -0
  405. package/lib/typescript/src/components/ui/shared/selectImageAttemptSource.shared.d.ts.map +1 -0
  406. package/lib/typescript/src/components/ui/shared/selectImageAttemptSource.web.d.ts +3 -0
  407. package/lib/typescript/src/components/ui/shared/selectImageAttemptSource.web.d.ts.map +1 -0
  408. package/lib/typescript/src/theme/ThemeProvider.d.ts +2 -3
  409. package/lib/typescript/src/theme/ThemeProvider.d.ts.map +1 -1
  410. package/lib/typescript/src/theme/fontScale.d.ts +4 -0
  411. package/lib/typescript/src/theme/fontScale.d.ts.map +1 -0
  412. package/lib/typescript/src/theme/index.d.ts +2 -1
  413. package/lib/typescript/src/theme/index.d.ts.map +1 -1
  414. package/lib/typescript/src/theme/themeContext.d.ts +6 -0
  415. package/lib/typescript/src/theme/themeContext.d.ts.map +1 -0
  416. package/lib/typescript/src/theme/themeDiagnostics.d.ts +6 -0
  417. package/lib/typescript/src/theme/themeDiagnostics.d.ts.map +1 -0
  418. package/lib/typescript/src/theme/usePrefersReducedMotion.d.ts +8 -3
  419. package/lib/typescript/src/theme/usePrefersReducedMotion.d.ts.map +1 -1
  420. package/lib/typescript/src/theme/usePrefersReducedMotion.web.d.ts +5 -2
  421. package/lib/typescript/src/theme/usePrefersReducedMotion.web.d.ts.map +1 -1
  422. package/lib/typescript/src/theme/useTheme.d.ts +1 -1
  423. package/lib/typescript/src/theme/useTheme.d.ts.map +1 -1
  424. package/lib/typescript/src/theme/useThemedStyles.d.ts +1 -1
  425. package/lib/typescript/src/theme/useThemedStyles.d.ts.map +1 -1
  426. package/lib/typescript/src/utils/imageSource.d.ts +20 -0
  427. package/lib/typescript/src/utils/imageSource.d.ts.map +1 -0
  428. package/lib/typescript/type-tests/public-api.d.ts +2 -0
  429. package/lib/typescript/type-tests/public-api.d.ts.map +1 -0
  430. package/lib/typescript/website/src/components/iconCatalogCategories.d.ts +11 -0
  431. package/lib/typescript/website/src/components/iconCatalogCategories.d.ts.map +1 -0
  432. package/package.json +31 -17
  433. package/src/components/business/AvatarWithRing/AvatarWithRing.tsx +11 -4
  434. package/src/components/business/AvatarWithRing/styles.ts +11 -9
  435. package/src/components/business/VersionPill/VersionPill.tsx +31 -25
  436. package/src/components/business/VersionPill/content.ts +47 -0
  437. package/src/components/business/VersionPill/index.ts +1 -1
  438. package/src/components/business/VersionPill/styles.ts +4 -0
  439. package/src/components/business/VersionPill/types.ts +7 -2
  440. package/src/components/business/index.ts +1 -1
  441. package/src/components/business/useSvgId.ts +29 -8
  442. package/src/components/ui/Avatar/Avatar.tsx +25 -34
  443. package/src/components/ui/Avatar/types.ts +6 -2
  444. package/src/components/ui/Button/Button.tsx +39 -20
  445. package/src/components/ui/Button/ButtonBase.tsx +21 -12
  446. package/src/components/ui/Button/types.ts +5 -3
  447. package/src/components/ui/Carousel/Carousel.tsx +125 -71
  448. package/src/components/ui/Carousel/behavior.ts +78 -0
  449. package/src/components/ui/Carousel/index.ts +1 -1
  450. package/src/components/ui/Carousel/styles.ts +8 -13
  451. package/src/components/ui/Carousel/types.ts +35 -17
  452. package/src/components/ui/Cell/Cell.tsx +85 -74
  453. package/src/components/ui/Cell/Leading.tsx +14 -14
  454. package/src/components/ui/Cell/content.ts +53 -0
  455. package/src/components/ui/Cell/index.ts +7 -1
  456. package/src/components/ui/Cell/types.ts +64 -30
  457. package/src/components/ui/Checkbox/Checkbox.tsx +35 -8
  458. package/src/components/ui/Checkbox/types.ts +15 -3
  459. package/src/components/ui/Confirm/ConfirmHost.tsx +51 -26
  460. package/src/components/ui/Confirm/confirm.ts +17 -34
  461. package/src/components/ui/Confirm/labels.ts +14 -0
  462. package/src/components/ui/Confirm/store.ts +147 -0
  463. package/src/components/ui/Confirm/styles.ts +4 -0
  464. package/src/components/ui/Confirm/types.ts +2 -10
  465. package/src/components/ui/DrawerHeader/DrawerHeader.tsx +22 -27
  466. package/src/components/ui/DrawerHeader/types.ts +7 -1
  467. package/src/components/ui/Grid/Grid.tsx +44 -12
  468. package/src/components/ui/Grid/accessibility.ts +21 -0
  469. package/src/components/ui/Grid/types.ts +2 -0
  470. package/src/components/ui/IconButton/IconButton.tsx +20 -3
  471. package/src/components/ui/IconButton/types.ts +4 -2
  472. package/src/components/ui/Input/Input.tsx +16 -6
  473. package/src/components/ui/Input/index.ts +5 -0
  474. package/src/components/ui/Input/types.ts +12 -23
  475. package/src/components/ui/Logo/Logo.tsx +27 -4
  476. package/src/components/ui/Logo/types.ts +2 -2
  477. package/src/components/ui/NavBar/NavBar.tsx +27 -19
  478. package/src/components/ui/NavBar/index.ts +1 -1
  479. package/src/components/ui/NavBar/isSlot.ts +372 -5
  480. package/src/components/ui/NavBar/types.ts +9 -8
  481. package/src/components/ui/PasswordInput/PasswordInput.tsx +67 -69
  482. package/src/components/ui/PasswordInput/types.ts +12 -14
  483. package/src/components/ui/Pulse/PulseDot.tsx +5 -4
  484. package/src/components/ui/Pulse/normalizePulseOptions.ts +76 -0
  485. package/src/components/ui/Pulse/usePulse.ts +80 -34
  486. package/src/components/ui/Pulse/usePulseDriver.ts +49 -0
  487. package/src/components/ui/Pulse/usePulseDriver.web.ts +66 -0
  488. package/src/components/ui/Radio/Radio.tsx +44 -15
  489. package/src/components/ui/Radio/RadioGroup.tsx +21 -3
  490. package/src/components/ui/Radio/types.ts +17 -3
  491. package/src/components/ui/Reveal/Reveal.tsx +5 -3
  492. package/src/components/ui/Reveal/Reveal.web.tsx +72 -29
  493. package/src/components/ui/Reveal/types.ts +1 -1
  494. package/src/components/ui/Reveal/webTransition.ts +206 -0
  495. package/src/components/ui/Search/Search.tsx +127 -58
  496. package/src/components/ui/Search/types.ts +30 -9
  497. package/src/components/ui/Segmented/Segmented.tsx +10 -2
  498. package/src/components/ui/Skeleton/Skeleton.tsx +9 -5
  499. package/src/components/ui/Spinner/Spinner.tsx +25 -17
  500. package/src/components/ui/Spinner/Spinner.web.tsx +23 -18
  501. package/src/components/ui/Spinner/shared.ts +7 -0
  502. package/src/components/ui/Spinner/types.ts +1 -1
  503. package/src/components/ui/Stepper/Stepper.tsx +166 -86
  504. package/src/components/ui/Stepper/StepperPressable.tsx +1 -0
  505. package/src/components/ui/Stepper/StepperPressable.web.tsx +1 -0
  506. package/src/components/ui/Stepper/accessibility.ts +32 -0
  507. package/src/components/ui/Stepper/accessibility.types.ts +22 -0
  508. package/src/components/ui/Stepper/accessibility.web.ts +65 -0
  509. package/src/components/ui/Stepper/layout.ts +44 -0
  510. package/src/components/ui/Stepper/normalizeStepper.ts +85 -0
  511. package/src/components/ui/Stepper/styles.ts +9 -2
  512. package/src/components/ui/Stepper/types.ts +3 -1
  513. package/src/components/ui/Switch/Switch.tsx +54 -15
  514. package/src/components/ui/Switch/Switch.web.tsx +57 -19
  515. package/src/components/ui/Switch/styles.ts +11 -4
  516. package/src/components/ui/Switch/types.ts +2 -2
  517. package/src/components/ui/Tag/Tag.tsx +6 -2
  518. package/src/components/ui/TextField/TextFieldBase.tsx +175 -70
  519. package/src/components/ui/TextField/TextFieldSlot.tsx +91 -0
  520. package/src/components/ui/TextField/normalize.ts +280 -0
  521. package/src/components/ui/TextField/styles.ts +31 -0
  522. package/src/components/ui/TextField/types.ts +118 -22
  523. package/src/components/ui/TextField/useErrorAnnouncement.ts +27 -0
  524. package/src/components/ui/TextField/useTextFieldValue.ts +94 -0
  525. package/src/components/ui/TextField/valueState.ts +125 -0
  526. package/src/components/ui/Textarea/Textarea.tsx +11 -4
  527. package/src/components/ui/Textarea/index.ts +5 -0
  528. package/src/components/ui/Textarea/types.ts +14 -22
  529. package/src/components/ui/Thumbnail/Thumbnail.tsx +86 -51
  530. package/src/components/ui/Thumbnail/index.ts +5 -1
  531. package/src/components/ui/Thumbnail/normalize.ts +78 -0
  532. package/src/components/ui/Thumbnail/styles.ts +5 -10
  533. package/src/components/ui/Thumbnail/types.ts +43 -13
  534. package/src/components/ui/Toast/ToastHost.tsx +81 -22
  535. package/src/components/ui/Toast/ToastHost.web.tsx +91 -29
  536. package/src/components/ui/Toast/store.ts +148 -0
  537. package/src/components/ui/Toast/toast.ts +19 -10
  538. package/src/components/ui/Toast/types.ts +7 -3
  539. package/src/components/ui/index.ts +20 -5
  540. package/src/components/ui/shared/ImageAttempt.tsx +30 -0
  541. package/src/components/ui/shared/a11y.ts +18 -0
  542. package/src/components/ui/shared/accessibilityName.ts +6 -0
  543. package/src/components/ui/shared/selectImageAttemptSource.shared.ts +17 -0
  544. package/src/components/ui/shared/selectImageAttemptSource.ts +3 -0
  545. package/src/components/ui/shared/selectImageAttemptSource.web.ts +3 -0
  546. package/src/icons/data.ts +1 -1
  547. package/src/theme/ThemeProvider.tsx +18 -7
  548. package/src/theme/fontScale.ts +15 -0
  549. package/src/theme/index.ts +2 -3
  550. package/src/theme/themeContext.ts +24 -0
  551. package/src/theme/themeDiagnostics.ts +41 -0
  552. package/src/theme/usePrefersReducedMotion.ts +11 -4
  553. package/src/theme/usePrefersReducedMotion.web.ts +5 -2
  554. package/src/theme/useTheme.ts +19 -27
  555. package/src/theme/useThemedStyles.ts +12 -7
  556. package/src/utils/imageSource.ts +303 -0
  557. package/lib/module/components/ui/PasswordInput/styles.js +0 -12
  558. package/lib/module/components/ui/PasswordInput/styles.js.map +0 -1
  559. package/lib/module/components/ui/Pulse/usePulse.web.js +0 -76
  560. package/lib/module/components/ui/Pulse/usePulse.web.js.map +0 -1
  561. package/lib/typescript/src/components/ui/PasswordInput/styles.d.ts +0 -7
  562. package/lib/typescript/src/components/ui/PasswordInput/styles.d.ts.map +0 -1
  563. package/lib/typescript/src/components/ui/Pulse/usePulse.web.d.ts +0 -21
  564. package/lib/typescript/src/components/ui/Pulse/usePulse.web.d.ts.map +0 -1
  565. package/src/components/ui/PasswordInput/styles.ts +0 -7
  566. package/src/components/ui/Pulse/usePulse.web.ts +0 -74
@@ -1,4 +1,5 @@
1
1
  import React, { useEffect } from 'react';
2
+ import { View } from 'react-native';
2
3
  import { Pressable } from 'react-native-gesture-handler';
3
4
 
4
5
  import Animated, {
@@ -9,10 +10,21 @@ import Animated, {
9
10
  useSharedValue,
10
11
  withTiming,
11
12
  } from 'react-native-reanimated';
12
- import { fixed, motion, r, useColors, useThemedStyles } from '../../../theme';
13
- import { makeStyles, THUMB_OFF_X, THUMB_ON_X, TRACK_H } from './styles';
13
+ import {
14
+ motion,
15
+ useColors,
16
+ usePrefersReducedMotion,
17
+ useThemedStyles,
18
+ } from '../../../theme';
19
+ import { createLogger } from '../../../utils/logger';
20
+ import { childTestID } from '../../../utils/testID';
21
+ import { A11Y_HIDDEN_PROPS } from '../shared/a11y';
22
+ import { normalizeNonBlankText } from '../shared/accessibilityName';
23
+ import { makeStyles, THUMB_OFF_X, THUMB_ON_X } from './styles';
14
24
  import type { SwitchProps } from './types';
15
25
 
26
+ const log = createLogger('Switch');
27
+
16
28
  /**
17
29
  * 布尔切换。32×20 轨道 + 16×16 白色把手,200ms 缓动。
18
30
  *
@@ -28,12 +40,26 @@ export function Switch({
28
40
  }: SwitchProps): React.JSX.Element {
29
41
  const c = useColors();
30
42
  const styles = useThemedStyles(makeStyles);
43
+ const reducedMotion = usePrefersReducedMotion();
31
44
  const progress = useSharedValue(value ? 1 : 0);
45
+ const accessibleName = normalizeNonBlankText(accessibilityLabel);
46
+ const hasBlankLabel = accessibleName === undefined;
47
+ const isDisabled = disabled === true || hasBlankLabel;
32
48
 
33
49
  useEffect(() => {
34
- progress.value = withTiming(value ? 1 : 0, { duration: motion.base });
50
+ if (reducedMotion) {
51
+ cancelAnimation(progress);
52
+ progress.value = value ? 1 : 0;
53
+ } else {
54
+ progress.value = withTiming(value ? 1 : 0, { duration: motion.base });
55
+ }
35
56
  return () => cancelAnimation(progress);
36
- }, [value, progress]);
57
+ }, [progress, reducedMotion, value]);
58
+ useEffect(() => {
59
+ if (hasBlankLabel) {
60
+ log.warn('Switch accessibilityLabel 不能为空白,当前 action 已禁用。');
61
+ }
62
+ }, [hasBlankLabel]);
37
63
 
38
64
  const trackStyle = useAnimatedStyle(() => ({
39
65
  backgroundColor: interpolateColor(
@@ -57,19 +83,32 @@ export function Switch({
57
83
 
58
84
  return (
59
85
  <Pressable
60
- onPress={() => !disabled && onChange(!value)}
61
- disabled={disabled}
62
- // [M-7] 轨道高 r(20)≈20pt;补 (44-20)/2=12 到 fixed.hitTarget
63
- hitSlop={Math.round((fixed.hitTarget - r(TRACK_H)) / 2)}
64
- style={disabled ? styles.pressableDisabled : styles.pressableEnabled}
65
- accessibilityRole="switch"
66
- accessibilityState={{ checked: value, disabled: !!disabled }}
67
- accessibilityLabel={accessibilityLabel}
86
+ accessible={!hasBlankLabel}
87
+ onPress={isDisabled ? undefined : () => onChange(!value)}
88
+ disabled={isDisabled}
89
+ style={[styles.pressable, isDisabled && styles.pressableDisabled]}
90
+ accessibilityRole={hasBlankLabel ? undefined : 'switch'}
91
+ accessibilityState={
92
+ hasBlankLabel ? undefined : { checked: value, disabled: isDisabled }
93
+ }
94
+ accessibilityLabel={accessibleName}
68
95
  testID={testID}
69
96
  >
70
- <Animated.View style={[styles.track, trackStyle]}>
71
- <Animated.View style={[styles.thumb, thumbStyle]} />
72
- </Animated.View>
97
+ <View
98
+ {...A11Y_HIDDEN_PROPS}
99
+ style={styles.visualFrame}
100
+ testID={childTestID(testID, 'visual')}
101
+ >
102
+ <Animated.View
103
+ style={[styles.track, trackStyle]}
104
+ testID={childTestID(testID, 'track')}
105
+ >
106
+ <Animated.View
107
+ style={[styles.thumb, thumbStyle]}
108
+ testID={childTestID(testID, 'thumb')}
109
+ />
110
+ </Animated.View>
111
+ </View>
73
112
  </Pressable>
74
113
  );
75
114
  }
@@ -1,10 +1,21 @@
1
- import React from 'react';
1
+ import React, { useEffect } from 'react';
2
2
  import { Pressable } from 'react-native-gesture-handler';
3
3
  import { View } from 'react-native';
4
- import { motion, useColors, useThemedStyles } from '../../../theme';
4
+ import {
5
+ motion,
6
+ useColors,
7
+ usePrefersReducedMotion,
8
+ useThemedStyles,
9
+ } from '../../../theme';
10
+ import { createLogger } from '../../../utils/logger';
11
+ import { childTestID } from '../../../utils/testID';
12
+ import { A11Y_HIDDEN_PROPS } from '../shared/a11y';
13
+ import { normalizeNonBlankText } from '../shared/accessibilityName';
5
14
  import { makeStyles, THUMB_OFF_X, THUMB_ON_X } from './styles';
6
15
  import type { SwitchProps } from './types';
7
16
 
17
+ const log = createLogger('Switch');
18
+
8
19
  /**
9
20
  * Web 端 Switch —— RN-Web 上 reanimated 4 + worklets 0.9.x 的 useAnimatedStyle
10
21
  * 链路会抛 `Object.keys(undefined)` TypeError(切换时打印,thumb 卡住),走 CSS
@@ -24,37 +35,64 @@ export function Switch({
24
35
  }: SwitchProps): React.JSX.Element {
25
36
  const c = useColors();
26
37
  const styles = useThemedStyles(makeStyles);
38
+ const reducedMotion = usePrefersReducedMotion();
39
+ const accessibleName = normalizeNonBlankText(accessibilityLabel);
40
+ const hasBlankLabel = accessibleName === undefined;
41
+ const isDisabled = disabled === true || hasBlankLabel;
42
+
43
+ useEffect(() => {
44
+ if (hasBlankLabel) {
45
+ log.warn('Switch accessibilityLabel 不能为空白,当前 action 已禁用。');
46
+ }
47
+ }, [hasBlankLabel]);
27
48
 
28
- // 给 RN style 数组追加 web-only 字段:transition + 切换值
49
+ // 给 RN style 数组追加 web-only 字段;reduced motion 时连 transition key
50
+ // 都不输出,避免浏览器仍创建零时长 transition。
29
51
  const trackWebStyle = {
30
52
  ...styles.track,
31
53
  backgroundColor: value ? c.primary : c.surfaceContainerHighest,
32
- // RN style 不识 transition 但 RN-Web 会把它当 inline style 透传给 DOM
33
- transitionProperty: 'background-color',
34
- transitionDuration: `${motion.base}ms`,
35
- transitionTimingFunction: 'ease-out',
54
+ ...(reducedMotion
55
+ ? {}
56
+ : {
57
+ // RN style 不识 transition 但 RN-Web 会把它当 inline style 透传给 DOM
58
+ transitionProperty: 'background-color',
59
+ transitionDuration: `${motion.base}ms`,
60
+ transitionTimingFunction: 'ease-out',
61
+ }),
36
62
  } as unknown as object;
37
63
  const thumbWebStyle = {
38
64
  ...styles.thumb,
39
65
  transform: [{ translateX: value ? THUMB_ON_X : THUMB_OFF_X }],
40
- transitionProperty: 'transform',
41
- transitionDuration: `${motion.base}ms`,
42
- transitionTimingFunction: 'ease-out',
66
+ ...(reducedMotion
67
+ ? {}
68
+ : {
69
+ transitionProperty: 'transform',
70
+ transitionDuration: `${motion.base}ms`,
71
+ transitionTimingFunction: 'ease-out',
72
+ }),
43
73
  } as unknown as object;
44
74
 
45
75
  return (
46
76
  <Pressable
47
- onPress={() => !disabled && onChange(!value)}
48
- disabled={disabled}
49
- hitSlop={6}
50
- style={disabled ? styles.pressableDisabled : styles.pressableEnabled}
51
- accessibilityRole="switch"
52
- accessibilityState={{ checked: value, disabled: !!disabled }}
53
- accessibilityLabel={accessibilityLabel}
77
+ accessible={!hasBlankLabel}
78
+ onPress={isDisabled ? undefined : () => onChange(!value)}
79
+ disabled={isDisabled}
80
+ style={[styles.pressable, isDisabled && styles.pressableDisabled]}
81
+ accessibilityRole={hasBlankLabel ? undefined : 'switch'}
82
+ accessibilityState={
83
+ hasBlankLabel ? undefined : { checked: value, disabled: isDisabled }
84
+ }
85
+ accessibilityLabel={accessibleName}
54
86
  testID={testID}
55
87
  >
56
- <View style={trackWebStyle}>
57
- <View style={thumbWebStyle} />
88
+ <View
89
+ {...A11Y_HIDDEN_PROPS}
90
+ style={styles.visualFrame}
91
+ testID={childTestID(testID, 'visual')}
92
+ >
93
+ <View style={trackWebStyle} testID={childTestID(testID, 'track')}>
94
+ <View style={thumbWebStyle} testID={childTestID(testID, 'thumb')} />
95
+ </View>
58
96
  </View>
59
97
  </Pressable>
60
98
  );
@@ -1,5 +1,5 @@
1
1
  import { StyleSheet } from 'react-native';
2
- import { r, radius } from '../../../theme';
2
+ import { fixed, r, radius } from '../../../theme';
3
3
  import type { ColorTokens } from '../../../theme';
4
4
 
5
5
  /** 轨道宽 32 / 高 20、把手 16×16、轨道内边距 2 —— Unif 自有 Switch 物理尺寸。
@@ -16,14 +16,21 @@ export const THUMB_ON_X = r(TRACK_W - INSET - THUMB);
16
16
 
17
17
  export const makeStyles = (c: ColorTokens) =>
18
18
  StyleSheet.create({
19
- pressableEnabled: {
20
- opacity: 1,
19
+ // 固定命中框不走 r()/fontScale:它是手指可达性约束,不是视觉 token。
20
+ pressable: {
21
+ width: fixed.hitTarget,
22
+ height: fixed.hitTarget,
23
+ alignItems: 'center',
24
+ justifyContent: 'center',
21
25
  // [L-37] alignSelf:'flex-start' 防止父容器拉伸把手区域(与 Chip [M-8] 同口径)
22
26
  alignSelf: 'flex-start' as const,
23
27
  },
24
28
  pressableDisabled: {
25
29
  opacity: 0.5,
26
- alignSelf: 'flex-start' as const,
30
+ },
31
+ visualFrame: {
32
+ width: r(TRACK_W),
33
+ height: r(TRACK_H),
27
34
  },
28
35
  track: {
29
36
  width: r(TRACK_W),
@@ -1,8 +1,8 @@
1
1
  export type SwitchProps = {
2
2
  value: boolean;
3
3
  onChange: (value: boolean) => void;
4
+ /** Switch 没有内置可见文字,必须显式提供读屏名称 */
5
+ accessibilityLabel: string;
4
6
  disabled?: boolean;
5
- /** 用于无障碍 / 测试 */
6
- accessibilityLabel?: string;
7
7
  testID?: string;
8
8
  };
@@ -1,5 +1,5 @@
1
1
  import { Text, View } from 'react-native';
2
- import { useColors } from '../../../theme';
2
+ import { scaleFontMetric, useColors, useFontScale } from '../../../theme';
3
3
  import { paletteFor, sizingFor, styles } from './styles';
4
4
  import type { TagProps } from './types';
5
5
 
@@ -12,6 +12,7 @@ export function Tag({
12
12
  testID,
13
13
  }: TagProps) {
14
14
  const c = useColors();
15
+ const fontScale = useFontScale();
15
16
  const palette = paletteFor(variant, c);
16
17
  const sizing = sizingFor(size);
17
18
 
@@ -22,7 +23,10 @@ export function Tag({
22
23
  borderColor: palette.border ?? 'transparent',
23
24
  borderWidth: palette.border ? 1 : 0,
24
25
  };
25
- const dynamicTextStyle = { color: palette.fg, fontSize: sizing.fs };
26
+ const dynamicTextStyle = {
27
+ color: palette.fg,
28
+ fontSize: scaleFontMetric(sizing.fs, fontScale),
29
+ };
26
30
 
27
31
  return (
28
32
  <View style={[styles.base, dynamicStyle, style]} testID={testID}>
@@ -1,35 +1,40 @@
1
- import React, { type ComponentRef, forwardRef, useState } from 'react';
2
- import { Text, TextInput, View } from 'react-native';
3
- import { control, r, space, useColors, useThemedStyles } from '../../../theme';
1
+ import React, {
2
+ type ComponentRef,
3
+ forwardRef,
4
+ useEffect,
5
+ useImperativeHandle,
6
+ useState,
7
+ } from 'react';
8
+ import { Platform, Text, TextInput, View } from 'react-native';
9
+ import type { TextInputProps } from 'react-native';
10
+ import { fixed, space, useColors, useThemedStyles } from '../../../theme';
4
11
  import { childTestID } from '../../../utils/testID';
12
+ import { createLogger } from '../../../utils/logger';
13
+ import {
14
+ normalizeInputHeight,
15
+ normalizeTextareaHeights,
16
+ sanitizeTextFieldContainerStyle,
17
+ } from './normalize';
5
18
  import { makeStyles } from './styles';
6
- import type { TextFieldBaseProps } from './types';
19
+ import { TextFieldSlot } from './TextFieldSlot';
20
+ import type { TextFieldBaseProps, TextFieldHandle } from './types';
21
+ import { useErrorAnnouncement } from './useErrorAnnouncement';
22
+ import { useTextFieldValue } from './useTextFieldValue';
7
23
 
8
- /** `TextInput` react-native-strict-api 下是组件类型(`TextInputType`),
9
- * ref 实例类型走 `ComponentRef<typeof TextInput>`(对应内部 `_TextInputInstance`)。 */
10
- export type TextInputRef = ComponentRef<typeof TextInput>;
24
+ const log = createLogger('TextField');
11
25
 
12
- /**
13
- * Input / Textarea 共享 primitive —— internal,不在主 barrel 导出。
14
- *
15
- * 行为:
16
- * - 视觉 4 态:idle(浅灰)/ focus(白底 brand 边)/ filled(白底 outline 边)/ error
17
- * - leading / trailing 左右 slot
18
- * - disabled 优先于 editable
19
- * - multiline=false → 单行 fixed height(默认 control.lg)
20
- * - multiline=true → 多行 minHeight/maxHeight,文字顶对齐,wrap 上下加 padding
21
- * - forwardRef<TextInput> —— 业务表单 inputRef.current?.focus() 聚焦
22
- *
23
- * 公开 API 是 Input / Textarea(本组件不直接给业务用)。
24
- */
25
- export const TextFieldBase = forwardRef<TextInputRef, TextFieldBaseProps>(
26
- function TextFieldBase(
27
- {
28
- multiline = false,
29
- height = control.lg,
30
- // [L-81] multiline minHeight 裸 96 → r(96),随设备缩放
31
- minHeight = r(96),
26
+ /** internal native ref type;公开 ref 一律用 TextFieldHandle。 */
27
+ type NativeTextInputRef = ComponentRef<typeof TextInput>;
28
+
29
+ /** Input / Textarea / Search 共享的严格输入 primitive — internal,不进公共 barrel。 */
30
+ export const TextFieldBase = forwardRef<TextFieldHandle, TextFieldBaseProps>(
31
+ function TextFieldBase(props, forwardedRef): React.JSX.Element {
32
+ const {
33
+ multiline,
34
+ height,
35
+ minHeight,
32
36
  maxHeight,
37
+ searchLayout,
33
38
  leading,
34
39
  trailing,
35
40
  error,
@@ -37,29 +42,96 @@ export const TextFieldBase = forwardRef<TextInputRef, TextFieldBaseProps>(
37
42
  editable,
38
43
  containerStyle,
39
44
  value,
45
+ defaultValue,
46
+ onChangeText,
47
+ accessibilityState,
48
+ accessibilityRole,
49
+ placeholderTextColor: callerPlaceholder,
40
50
  onFocus,
41
51
  onBlur,
42
- onChangeText,
43
52
  testID,
44
- ...rest
45
- },
46
- ref
47
- ): React.JSX.Element {
48
- const c = useColors();
53
+ style: _style,
54
+ numberOfLines: _numberOfLines,
55
+ ['aria-disabled']: _ariaDisabled,
56
+ readOnly: _readOnly,
57
+ role: _role,
58
+ enterKeyHint: _enterKeyHint,
59
+ clearTextOnFocus: _clearTextOnFocus,
60
+ ...allowedNativeProps
61
+ } = props as TextFieldBaseProps & Record<string, unknown>;
62
+ const removedNativeAliasKey = Object.entries({
63
+ 'style': _style,
64
+ 'numberOfLines': _numberOfLines,
65
+ 'aria-disabled': _ariaDisabled,
66
+ 'readOnly': _readOnly,
67
+ 'role': _role,
68
+ 'enterKeyHint': _enterKeyHint,
69
+ 'clearTextOnFocus': _clearTextOnFocus,
70
+ })
71
+ .filter(([, entry]) => entry !== undefined)
72
+ .map(([name]) => name)
73
+ .join(',');
74
+ const colors = useColors();
49
75
  const styles = useThemedStyles(makeStyles);
50
76
  const [focused, setFocused] = useState(false);
51
- // [M-9] 内部镜像 state:非受控场景 value 不传,用 _mirror 做 hasValue 判断
52
- const [_mirror, setMirror] = useState('');
53
- // [M-9] filled 在受控 value 和内部镜像 state 之间取 hasValue,
54
- // 保证非受控场景 filled 视觉态能正确响应用户输入,且受控用法行为不变
55
- const filled =
56
- value != null ? String(value).length > 0 : _mirror.length > 0;
57
- const isEditable = disabled ? false : editable;
58
- // [L-31] editable=false(非 disabled)时也应进入 disabled a11y state
59
- const isDisabledA11y = disabled || editable === false;
77
+ const nativeRef = React.useRef<NativeTextInputRef>(null);
78
+ const scope = multiline ? 'Textarea' : 'Input';
79
+ const controller = useTextFieldValue(
80
+ {
81
+ value,
82
+ defaultValue,
83
+ onChangeText:
84
+ typeof onChangeText === 'function'
85
+ ? (onChangeText as (next: string) => void)
86
+ : undefined,
87
+ },
88
+ scope
89
+ );
90
+ const normalizedInputHeight = normalizeInputHeight(
91
+ height === undefined ? fixed.hitTarget : height
92
+ );
93
+ const normalizedTextareaHeights = normalizeTextareaHeights(
94
+ minHeight,
95
+ maxHeight
96
+ );
97
+ const sanitizedContainer = sanitizeTextFieldContainerStyle(containerStyle);
98
+ const effectiveEditable = disabled !== true && editable !== false;
99
+ const mergedAccessibilityState = {
100
+ ...accessibilityState,
101
+ disabled: !effectiveEditable,
102
+ };
103
+ const normalizedHeight = multiline
104
+ ? normalizedTextareaHeights.minHeight
105
+ : normalizedInputHeight.value;
106
+ const filled = controller.value.length > 0;
107
+ const diagnostics = [
108
+ ...normalizedInputHeight.diagnostics,
109
+ ...normalizedTextareaHeights.diagnostics,
110
+ ...sanitizedContainer.diagnostics,
111
+ ];
112
+ const diagnosticKey = diagnostics.join(',');
113
+
114
+ useEffect(() => {
115
+ if (diagnosticKey.length > 0) {
116
+ log.warn(`${scope}: 非法布局值(${diagnosticKey})已回退。`);
117
+ }
118
+ }, [diagnosticKey, scope]);
119
+ useEffect(() => {
120
+ if (removedNativeAliasKey.length > 0) {
121
+ log.warn(`${scope}: 已忽略受管原生 props(${removedNativeAliasKey})。`);
122
+ }
123
+ }, [removedNativeAliasKey, scope]);
124
+ useErrorAnnouncement(error);
125
+
126
+ useImperativeHandle(
127
+ forwardedRef,
128
+ () => ({
129
+ focus: () => nativeRef.current?.focus(),
130
+ blur: () => nativeRef.current?.blur(),
131
+ }),
132
+ []
133
+ );
60
134
 
61
- // 视觉态优先级:error > focused > filled > idle。
62
- // active 三态(focus/filled/error)共享 wrapActive 白底,各自只覆 borderColor 差量。
63
135
  const wrapStateStyles = error
64
136
  ? [styles.wrapActive, styles.wrapError]
65
137
  : focused
@@ -67,62 +139,95 @@ export const TextFieldBase = forwardRef<TextInputRef, TextFieldBaseProps>(
67
139
  : filled
68
140
  ? [styles.wrapActive, styles.wrapFilled]
69
141
  : [styles.wrapIdle];
142
+ const interactiveHeight =
143
+ searchLayout?.interactiveHeight ?? normalizedHeight;
70
144
 
71
145
  return (
72
146
  <View
73
- style={[containerStyle, disabled && styles.containerDisabled]}
147
+ style={[
148
+ sanitizedContainer.style,
149
+ !effectiveEditable && styles.containerDisabled,
150
+ searchLayout !== undefined && !multiline && styles.rootCentered,
151
+ { minWidth: fixed.hitTarget, minHeight: normalizedHeight },
152
+ ]}
74
153
  testID={testID}
75
154
  >
76
155
  <View
77
156
  style={[
78
157
  styles.wrap,
79
158
  multiline && styles.wrapMultiline,
80
- ...wrapStateStyles,
159
+ searchLayout === undefined && wrapStateStyles,
160
+ searchLayout !== undefined && styles.searchInteractiveRow,
81
161
  multiline
82
- ? { minHeight, ...(maxHeight != null && { maxHeight }) }
83
- : { height },
162
+ ? {
163
+ minHeight: normalizedHeight,
164
+ ...(normalizedTextareaHeights.maxHeight !== undefined && {
165
+ maxHeight: normalizedTextareaHeights.maxHeight,
166
+ }),
167
+ }
168
+ : { height: interactiveHeight },
84
169
  ]}
85
170
  >
86
- {leading != null ? <View>{leading}</View> : null}
171
+ {searchLayout ? (
172
+ <View
173
+ pointerEvents="none"
174
+ style={[
175
+ styles.searchVisibleSurface,
176
+ ...wrapStateStyles,
177
+ {
178
+ top: searchLayout.verticalInset,
179
+ bottom: searchLayout.verticalInset,
180
+ },
181
+ ]}
182
+ />
183
+ ) : null}
184
+ <TextFieldSlot
185
+ slot={leading}
186
+ effectiveEditable={effectiveEditable}
187
+ testID={childTestID(testID, 'leading')}
188
+ />
87
189
  <TextInput
88
- ref={ref}
89
- {...rest}
90
- editable={isEditable}
91
- value={value}
92
- onChangeText={(text) => {
93
- // [M-9] 同步内部镜像,非受控场景 filled 视觉态依赖此 state
94
- setMirror(text);
95
- onChangeText?.(text);
96
- }}
190
+ ref={nativeRef}
191
+ {...(allowedNativeProps as TextInputProps)}
192
+ value={controller.value}
193
+ onChangeText={controller.onChangeText}
194
+ editable={effectiveEditable}
97
195
  multiline={multiline}
98
- onFocus={(e) => {
196
+ onFocus={(event) => {
99
197
  setFocused(true);
100
- onFocus?.(e);
198
+ onFocus?.(event);
101
199
  }}
102
- onBlur={(e) => {
200
+ onBlur={(event) => {
103
201
  setFocused(false);
104
- onBlur?.(e);
202
+ onBlur?.(event);
105
203
  }}
106
204
  style={[
107
205
  styles.input,
108
206
  multiline && styles.inputMultiline,
109
- // multiline:wrap 上下 padding 为 space[4]*2=20,input 内部 minHeight 减掉避免溢出
110
207
  multiline && {
111
- minHeight: Math.max(0, minHeight - space[4] * 2),
208
+ minHeight: Math.max(0, normalizedHeight - space[4] * 2),
209
+ },
210
+ searchLayout !== undefined && {
211
+ minHeight: searchLayout.interactiveHeight,
112
212
  },
113
213
  ]}
114
- placeholderTextColor={c.foregroundSubtle}
115
- // [L-31] editable=false 并入 disabled a11y state,SR 能正确播报不可编辑
116
- accessibilityState={isDisabledA11y ? { disabled: true } : undefined}
214
+ placeholderTextColor={callerPlaceholder ?? colors.foregroundSubtle}
215
+ accessibilityRole={accessibilityRole}
216
+ accessibilityState={mergedAccessibilityState}
117
217
  testID={childTestID(testID, 'input')}
118
218
  />
119
- {trailing != null ? <View>{trailing}</View> : null}
219
+ <TextFieldSlot
220
+ slot={trailing}
221
+ effectiveEditable={effectiveEditable}
222
+ testID={childTestID(testID, 'trailing')}
223
+ />
120
224
  </View>
121
- {/* [L-31] error Text 补 accessibilityLiveRegion="polite" —— 错误出现时 SR 自动播报 */}
122
225
  {error ? (
123
226
  <Text
124
227
  style={styles.errorMsg}
125
- accessibilityLiveRegion="polite"
228
+ accessibilityLiveRegion={
229
+ Platform.OS === 'android' ? 'polite' : undefined
230
+ }
126
231
  testID={childTestID(testID, 'error')}
127
232
  >
128
233
  {error}
@@ -0,0 +1,91 @@
1
+ import { useEffect } from 'react';
2
+ import { Text, View } from 'react-native';
3
+ import { Pressable } from 'react-native-gesture-handler';
4
+ import { useColors, useThemedStyles } from '../../../theme';
5
+ import { createLogger } from '../../../utils/logger';
6
+ import { A11Y_HIDDEN_PROPS } from '../shared/a11y';
7
+ import { Icon } from '../Icon';
8
+ import { normalizeSlotIconSize, normalizeTextFieldSlot } from './normalize';
9
+ import { makeStyles } from './styles';
10
+ import type { TextFieldSlot as TextFieldSlotConfig } from './types';
11
+
12
+ const log = createLogger('TextFieldSlot');
13
+
14
+ type TextFieldSlotProps = {
15
+ slot: TextFieldSlotConfig | unknown;
16
+ effectiveEditable: boolean;
17
+ testID?: string;
18
+ };
19
+
20
+ /**
21
+ * 受控 slot renderer。展示内容与真实操作在这里分叉,避免未知 ReactNode 绕过
22
+ * 44pt action frame 或可访问名称约束。
23
+ */
24
+ export function TextFieldSlot({
25
+ slot,
26
+ effectiveEditable,
27
+ testID,
28
+ }: TextFieldSlotProps): React.JSX.Element | null {
29
+ const colors = useColors();
30
+ const styles = useThemedStyles(makeStyles);
31
+ const normalizedSlot = normalizeTextFieldSlot(slot);
32
+ const safeSlot = normalizedSlot.slot;
33
+ const iconSize =
34
+ safeSlot?.kind === 'icon'
35
+ ? normalizeSlotIconSize(safeSlot.size)
36
+ : undefined;
37
+ const iconDiagnosticKey = iconSize?.diagnostics.join(',') ?? '';
38
+ const slotDiagnosticKey = normalizedSlot.diagnostics.join(',');
39
+
40
+ useEffect(() => {
41
+ if (iconDiagnosticKey.length > 0) {
42
+ log.warn('slot.icon.size 非法,已回退为 18。');
43
+ }
44
+ }, [iconDiagnosticKey]);
45
+ useEffect(() => {
46
+ if (slotDiagnosticKey.length > 0) {
47
+ log.warn(`非法 TextField slot(${slotDiagnosticKey})已移除。`);
48
+ }
49
+ }, [slotDiagnosticKey]);
50
+
51
+ if (!safeSlot) return null;
52
+
53
+ switch (safeSlot.kind) {
54
+ case 'icon':
55
+ return (
56
+ <View {...A11Y_HIDDEN_PROPS} style={styles.slotDisplay} testID={testID}>
57
+ <Icon
58
+ name={safeSlot.icon}
59
+ size={iconSize?.value ?? 18}
60
+ color={safeSlot.color ?? colors.foregroundMuted}
61
+ />
62
+ </View>
63
+ );
64
+ case 'text':
65
+ return (
66
+ <Text
67
+ {...A11Y_HIDDEN_PROPS}
68
+ style={[styles.slotDisplay, styles.slotText]}
69
+ testID={testID}
70
+ >
71
+ {safeSlot.value}
72
+ </Text>
73
+ );
74
+ case 'action': {
75
+ const disabled = !effectiveEditable || safeSlot.disabled === true;
76
+ return (
77
+ <Pressable
78
+ onPress={disabled ? undefined : safeSlot.onPress}
79
+ disabled={disabled}
80
+ accessibilityRole="button"
81
+ accessibilityLabel={safeSlot.accessibilityLabel}
82
+ accessibilityState={{ disabled }}
83
+ style={styles.actionFrame}
84
+ testID={testID}
85
+ >
86
+ <Icon name={safeSlot.icon} size={18} color={colors.foregroundMuted} />
87
+ </Pressable>
88
+ );
89
+ }
90
+ }
91
+ }