@unif/react-native-chat 2.0.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 (345) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +48 -0
  3. package/lib/module/actions/index.js +2 -0
  4. package/lib/module/actions/index.js.map +1 -0
  5. package/lib/module/actions/types.js +4 -0
  6. package/lib/module/actions/types.js.map +1 -0
  7. package/lib/module/components/Attachments/AttachmentItem.js +108 -0
  8. package/lib/module/components/Attachments/AttachmentItem.js.map +1 -0
  9. package/lib/module/components/Attachments/Attachments.js +60 -0
  10. package/lib/module/components/Attachments/Attachments.js.map +1 -0
  11. package/lib/module/components/Attachments/constants.js +18 -0
  12. package/lib/module/components/Attachments/constants.js.map +1 -0
  13. package/lib/module/components/Attachments/index.js +4 -0
  14. package/lib/module/components/Attachments/index.js.map +1 -0
  15. package/lib/module/components/Attachments/styles.js +83 -0
  16. package/lib/module/components/Attachments/styles.js.map +1 -0
  17. package/lib/module/components/Attachments/types.js +4 -0
  18. package/lib/module/components/Attachments/types.js.map +1 -0
  19. package/lib/module/components/Chat/Chat.js +29 -0
  20. package/lib/module/components/Chat/Chat.js.map +1 -0
  21. package/lib/module/components/Chat/index.js +4 -0
  22. package/lib/module/components/Chat/index.js.map +1 -0
  23. package/lib/module/components/Chat/styles.js +17 -0
  24. package/lib/module/components/Chat/styles.js.map +1 -0
  25. package/lib/module/components/Chat/types.js +4 -0
  26. package/lib/module/components/Chat/types.js.map +1 -0
  27. package/lib/module/components/Citation/Citation.js +32 -0
  28. package/lib/module/components/Citation/Citation.js.map +1 -0
  29. package/lib/module/components/Citation/index.js +4 -0
  30. package/lib/module/components/Citation/index.js.map +1 -0
  31. package/lib/module/components/Citation/styles.js +15 -0
  32. package/lib/module/components/Citation/styles.js.map +1 -0
  33. package/lib/module/components/Citation/types.js +2 -0
  34. package/lib/module/components/Citation/types.js.map +1 -0
  35. package/lib/module/components/Composer/Composer.js +149 -0
  36. package/lib/module/components/Composer/Composer.js.map +1 -0
  37. package/lib/module/components/Composer/constants.js +14 -0
  38. package/lib/module/components/Composer/constants.js.map +1 -0
  39. package/lib/module/components/Composer/index.js +4 -0
  40. package/lib/module/components/Composer/index.js.map +1 -0
  41. package/lib/module/components/Composer/styles.js +43 -0
  42. package/lib/module/components/Composer/styles.js.map +1 -0
  43. package/lib/module/components/Composer/types.js +4 -0
  44. package/lib/module/components/Composer/types.js.map +1 -0
  45. package/lib/module/components/Confirmation/Confirmation.js +56 -0
  46. package/lib/module/components/Confirmation/Confirmation.js.map +1 -0
  47. package/lib/module/components/Confirmation/constants.js +10 -0
  48. package/lib/module/components/Confirmation/constants.js.map +1 -0
  49. package/lib/module/components/Confirmation/index.js +4 -0
  50. package/lib/module/components/Confirmation/index.js.map +1 -0
  51. package/lib/module/components/Confirmation/styles.js +34 -0
  52. package/lib/module/components/Confirmation/styles.js.map +1 -0
  53. package/lib/module/components/Confirmation/types.js +4 -0
  54. package/lib/module/components/Confirmation/types.js.map +1 -0
  55. package/lib/module/components/Feedback/Feedback.js +82 -0
  56. package/lib/module/components/Feedback/Feedback.js.map +1 -0
  57. package/lib/module/components/Feedback/constants.js +15 -0
  58. package/lib/module/components/Feedback/constants.js.map +1 -0
  59. package/lib/module/components/Feedback/index.js +4 -0
  60. package/lib/module/components/Feedback/index.js.map +1 -0
  61. package/lib/module/components/Feedback/styles.js +30 -0
  62. package/lib/module/components/Feedback/styles.js.map +1 -0
  63. package/lib/module/components/Feedback/types.js +4 -0
  64. package/lib/module/components/Feedback/types.js.map +1 -0
  65. package/lib/module/components/Message/MarkdownContent/MarkdownContent.js +68 -0
  66. package/lib/module/components/Message/MarkdownContent/MarkdownContent.js.map +1 -0
  67. package/lib/module/components/Message/MarkdownContent/MarkdownImage/MarkdownImage.js +53 -0
  68. package/lib/module/components/Message/MarkdownContent/MarkdownImage/MarkdownImage.js.map +1 -0
  69. package/lib/module/components/Message/MarkdownContent/MarkdownImage/styles.js +10 -0
  70. package/lib/module/components/Message/MarkdownContent/MarkdownImage/styles.js.map +1 -0
  71. package/lib/module/components/Message/MarkdownContent/MarkdownImage/types.js +2 -0
  72. package/lib/module/components/Message/MarkdownContent/MarkdownImage/types.js.map +1 -0
  73. package/lib/module/components/Message/MarkdownContent/styles.js +85 -0
  74. package/lib/module/components/Message/MarkdownContent/styles.js.map +1 -0
  75. package/lib/module/components/Message/MarkdownContent/types.js +2 -0
  76. package/lib/module/components/Message/MarkdownContent/types.js.map +1 -0
  77. package/lib/module/components/Message/Message.js +87 -0
  78. package/lib/module/components/Message/Message.js.map +1 -0
  79. package/lib/module/components/Message/constants.js +4 -0
  80. package/lib/module/components/Message/constants.js.map +1 -0
  81. package/lib/module/components/Message/index.js +4 -0
  82. package/lib/module/components/Message/index.js.map +1 -0
  83. package/lib/module/components/Message/isNestedAction.js +14 -0
  84. package/lib/module/components/Message/isNestedAction.js.map +1 -0
  85. package/lib/module/components/Message/styles.js +73 -0
  86. package/lib/module/components/Message/styles.js.map +1 -0
  87. package/lib/module/components/Message/types.js +4 -0
  88. package/lib/module/components/Message/types.js.map +1 -0
  89. package/lib/module/components/MessageList/MessageList.js +223 -0
  90. package/lib/module/components/MessageList/MessageList.js.map +1 -0
  91. package/lib/module/components/MessageList/constants.js +4 -0
  92. package/lib/module/components/MessageList/constants.js.map +1 -0
  93. package/lib/module/components/MessageList/index.js +4 -0
  94. package/lib/module/components/MessageList/index.js.map +1 -0
  95. package/lib/module/components/MessageList/styles.js +20 -0
  96. package/lib/module/components/MessageList/styles.js.map +1 -0
  97. package/lib/module/components/MessageList/types.js +4 -0
  98. package/lib/module/components/MessageList/types.js.map +1 -0
  99. package/lib/module/components/MessageList/webPrependAnchor/constants.js +4 -0
  100. package/lib/module/components/MessageList/webPrependAnchor/constants.js.map +1 -0
  101. package/lib/module/components/MessageList/webPrependAnchor/index.js +4 -0
  102. package/lib/module/components/MessageList/webPrependAnchor/index.js.map +1 -0
  103. package/lib/module/components/MessageList/webPrependAnchor/types.js +4 -0
  104. package/lib/module/components/MessageList/webPrependAnchor/types.js.map +1 -0
  105. package/lib/module/components/MessageList/webPrependAnchor/useWebPrependAnchor.js +19 -0
  106. package/lib/module/components/MessageList/webPrependAnchor/useWebPrependAnchor.js.map +1 -0
  107. package/lib/module/components/MessageList/webPrependAnchor/useWebPrependAnchor.web.js +208 -0
  108. package/lib/module/components/MessageList/webPrependAnchor/useWebPrependAnchor.web.js.map +1 -0
  109. package/lib/module/components/Process/Process.js +121 -0
  110. package/lib/module/components/Process/Process.js.map +1 -0
  111. package/lib/module/components/Process/constants.js +17 -0
  112. package/lib/module/components/Process/constants.js.map +1 -0
  113. package/lib/module/components/Process/index.js +4 -0
  114. package/lib/module/components/Process/index.js.map +1 -0
  115. package/lib/module/components/Process/styles.js +77 -0
  116. package/lib/module/components/Process/styles.js.map +1 -0
  117. package/lib/module/components/Process/types.js +4 -0
  118. package/lib/module/components/Process/types.js.map +1 -0
  119. package/lib/module/components/Sources/Sources.js +64 -0
  120. package/lib/module/components/Sources/Sources.js.map +1 -0
  121. package/lib/module/components/Sources/constants.js +4 -0
  122. package/lib/module/components/Sources/constants.js.map +1 -0
  123. package/lib/module/components/Sources/index.js +4 -0
  124. package/lib/module/components/Sources/index.js.map +1 -0
  125. package/lib/module/components/Sources/styles.js +52 -0
  126. package/lib/module/components/Sources/styles.js.map +1 -0
  127. package/lib/module/components/Sources/types.js +4 -0
  128. package/lib/module/components/Sources/types.js.map +1 -0
  129. package/lib/module/components/Suggestions/Suggestions.js +31 -0
  130. package/lib/module/components/Suggestions/Suggestions.js.map +1 -0
  131. package/lib/module/components/Suggestions/index.js +4 -0
  132. package/lib/module/components/Suggestions/index.js.map +1 -0
  133. package/lib/module/components/Suggestions/styles.js +18 -0
  134. package/lib/module/components/Suggestions/styles.js.map +1 -0
  135. package/lib/module/components/Suggestions/types.js +4 -0
  136. package/lib/module/components/Suggestions/types.js.map +1 -0
  137. package/lib/module/index.js +14 -0
  138. package/lib/module/index.js.map +1 -0
  139. package/lib/module/package.json +1 -0
  140. package/lib/typescript/package.json +1 -0
  141. package/lib/typescript/src/actions/index.d.ts +2 -0
  142. package/lib/typescript/src/actions/index.d.ts.map +1 -0
  143. package/lib/typescript/src/actions/types.d.ts +11 -0
  144. package/lib/typescript/src/actions/types.d.ts.map +1 -0
  145. package/lib/typescript/src/components/Attachments/AttachmentItem.d.ts +3 -0
  146. package/lib/typescript/src/components/Attachments/AttachmentItem.d.ts.map +1 -0
  147. package/lib/typescript/src/components/Attachments/Attachments.d.ts +3 -0
  148. package/lib/typescript/src/components/Attachments/Attachments.d.ts.map +1 -0
  149. package/lib/typescript/src/components/Attachments/constants.d.ts +13 -0
  150. package/lib/typescript/src/components/Attachments/constants.d.ts.map +1 -0
  151. package/lib/typescript/src/components/Attachments/index.d.ts +3 -0
  152. package/lib/typescript/src/components/Attachments/index.d.ts.map +1 -0
  153. package/lib/typescript/src/components/Attachments/styles.d.ts +80 -0
  154. package/lib/typescript/src/components/Attachments/styles.d.ts.map +1 -0
  155. package/lib/typescript/src/components/Attachments/types.d.ts +34 -0
  156. package/lib/typescript/src/components/Attachments/types.d.ts.map +1 -0
  157. package/lib/typescript/src/components/Chat/Chat.d.ts +3 -0
  158. package/lib/typescript/src/components/Chat/Chat.d.ts.map +1 -0
  159. package/lib/typescript/src/components/Chat/index.d.ts +3 -0
  160. package/lib/typescript/src/components/Chat/index.d.ts.map +1 -0
  161. package/lib/typescript/src/components/Chat/styles.d.ts +15 -0
  162. package/lib/typescript/src/components/Chat/styles.d.ts.map +1 -0
  163. package/lib/typescript/src/components/Chat/types.d.ts +12 -0
  164. package/lib/typescript/src/components/Chat/types.d.ts.map +1 -0
  165. package/lib/typescript/src/components/Citation/Citation.d.ts +3 -0
  166. package/lib/typescript/src/components/Citation/Citation.d.ts.map +1 -0
  167. package/lib/typescript/src/components/Citation/index.d.ts +3 -0
  168. package/lib/typescript/src/components/Citation/index.d.ts.map +1 -0
  169. package/lib/typescript/src/components/Citation/styles.d.ts +12 -0
  170. package/lib/typescript/src/components/Citation/styles.d.ts.map +1 -0
  171. package/lib/typescript/src/components/Citation/types.d.ts +8 -0
  172. package/lib/typescript/src/components/Citation/types.d.ts.map +1 -0
  173. package/lib/typescript/src/components/Composer/Composer.d.ts +4 -0
  174. package/lib/typescript/src/components/Composer/Composer.d.ts.map +1 -0
  175. package/lib/typescript/src/components/Composer/constants.d.ts +12 -0
  176. package/lib/typescript/src/components/Composer/constants.d.ts.map +1 -0
  177. package/lib/typescript/src/components/Composer/index.d.ts +3 -0
  178. package/lib/typescript/src/components/Composer/index.d.ts.map +1 -0
  179. package/lib/typescript/src/components/Composer/styles.d.ts +40 -0
  180. package/lib/typescript/src/components/Composer/styles.d.ts.map +1 -0
  181. package/lib/typescript/src/components/Composer/types.d.ts +53 -0
  182. package/lib/typescript/src/components/Composer/types.d.ts.map +1 -0
  183. package/lib/typescript/src/components/Confirmation/Confirmation.d.ts +3 -0
  184. package/lib/typescript/src/components/Confirmation/Confirmation.d.ts.map +1 -0
  185. package/lib/typescript/src/components/Confirmation/constants.d.ts +5 -0
  186. package/lib/typescript/src/components/Confirmation/constants.d.ts.map +1 -0
  187. package/lib/typescript/src/components/Confirmation/index.d.ts +3 -0
  188. package/lib/typescript/src/components/Confirmation/index.d.ts.map +1 -0
  189. package/lib/typescript/src/components/Confirmation/styles.d.ts +31 -0
  190. package/lib/typescript/src/components/Confirmation/styles.d.ts.map +1 -0
  191. package/lib/typescript/src/components/Confirmation/types.d.ts +19 -0
  192. package/lib/typescript/src/components/Confirmation/types.d.ts.map +1 -0
  193. package/lib/typescript/src/components/Feedback/Feedback.d.ts +3 -0
  194. package/lib/typescript/src/components/Feedback/Feedback.d.ts.map +1 -0
  195. package/lib/typescript/src/components/Feedback/constants.d.ts +5 -0
  196. package/lib/typescript/src/components/Feedback/constants.d.ts.map +1 -0
  197. package/lib/typescript/src/components/Feedback/index.d.ts +3 -0
  198. package/lib/typescript/src/components/Feedback/index.d.ts.map +1 -0
  199. package/lib/typescript/src/components/Feedback/styles.d.ts +27 -0
  200. package/lib/typescript/src/components/Feedback/styles.d.ts.map +1 -0
  201. package/lib/typescript/src/components/Feedback/types.d.ts +12 -0
  202. package/lib/typescript/src/components/Feedback/types.d.ts.map +1 -0
  203. package/lib/typescript/src/components/Message/MarkdownContent/MarkdownContent.d.ts +3 -0
  204. package/lib/typescript/src/components/Message/MarkdownContent/MarkdownContent.d.ts.map +1 -0
  205. package/lib/typescript/src/components/Message/MarkdownContent/MarkdownImage/MarkdownImage.d.ts +3 -0
  206. package/lib/typescript/src/components/Message/MarkdownContent/MarkdownImage/MarkdownImage.d.ts.map +1 -0
  207. package/lib/typescript/src/components/Message/MarkdownContent/MarkdownImage/styles.d.ts +7 -0
  208. package/lib/typescript/src/components/Message/MarkdownContent/MarkdownImage/styles.d.ts.map +1 -0
  209. package/lib/typescript/src/components/Message/MarkdownContent/MarkdownImage/types.d.ts +9 -0
  210. package/lib/typescript/src/components/Message/MarkdownContent/MarkdownImage/types.d.ts.map +1 -0
  211. package/lib/typescript/src/components/Message/MarkdownContent/styles.d.ts +92 -0
  212. package/lib/typescript/src/components/Message/MarkdownContent/styles.d.ts.map +1 -0
  213. package/lib/typescript/src/components/Message/MarkdownContent/types.d.ts +5 -0
  214. package/lib/typescript/src/components/Message/MarkdownContent/types.d.ts.map +1 -0
  215. package/lib/typescript/src/components/Message/Message.d.ts +3 -0
  216. package/lib/typescript/src/components/Message/Message.d.ts.map +1 -0
  217. package/lib/typescript/src/components/Message/constants.d.ts +2 -0
  218. package/lib/typescript/src/components/Message/constants.d.ts.map +1 -0
  219. package/lib/typescript/src/components/Message/index.d.ts +3 -0
  220. package/lib/typescript/src/components/Message/index.d.ts.map +1 -0
  221. package/lib/typescript/src/components/Message/isNestedAction.d.ts +3 -0
  222. package/lib/typescript/src/components/Message/isNestedAction.d.ts.map +1 -0
  223. package/lib/typescript/src/components/Message/styles.d.ts +70 -0
  224. package/lib/typescript/src/components/Message/styles.d.ts.map +1 -0
  225. package/lib/typescript/src/components/Message/types.d.ts +44 -0
  226. package/lib/typescript/src/components/Message/types.d.ts.map +1 -0
  227. package/lib/typescript/src/components/MessageList/MessageList.d.ts +4 -0
  228. package/lib/typescript/src/components/MessageList/MessageList.d.ts.map +1 -0
  229. package/lib/typescript/src/components/MessageList/constants.d.ts +2 -0
  230. package/lib/typescript/src/components/MessageList/constants.d.ts.map +1 -0
  231. package/lib/typescript/src/components/MessageList/index.d.ts +3 -0
  232. package/lib/typescript/src/components/MessageList/index.d.ts.map +1 -0
  233. package/lib/typescript/src/components/MessageList/styles.d.ts +16 -0
  234. package/lib/typescript/src/components/MessageList/styles.d.ts.map +1 -0
  235. package/lib/typescript/src/components/MessageList/types.d.ts +36 -0
  236. package/lib/typescript/src/components/MessageList/types.d.ts.map +1 -0
  237. package/lib/typescript/src/components/MessageList/webPrependAnchor/constants.d.ts +2 -0
  238. package/lib/typescript/src/components/MessageList/webPrependAnchor/constants.d.ts.map +1 -0
  239. package/lib/typescript/src/components/MessageList/webPrependAnchor/index.d.ts +3 -0
  240. package/lib/typescript/src/components/MessageList/webPrependAnchor/index.d.ts.map +1 -0
  241. package/lib/typescript/src/components/MessageList/webPrependAnchor/types.d.ts +72 -0
  242. package/lib/typescript/src/components/MessageList/webPrependAnchor/types.d.ts.map +1 -0
  243. package/lib/typescript/src/components/MessageList/webPrependAnchor/useWebPrependAnchor.d.ts +3 -0
  244. package/lib/typescript/src/components/MessageList/webPrependAnchor/useWebPrependAnchor.d.ts.map +1 -0
  245. package/lib/typescript/src/components/MessageList/webPrependAnchor/useWebPrependAnchor.web.d.ts +3 -0
  246. package/lib/typescript/src/components/MessageList/webPrependAnchor/useWebPrependAnchor.web.d.ts.map +1 -0
  247. package/lib/typescript/src/components/Process/Process.d.ts +3 -0
  248. package/lib/typescript/src/components/Process/Process.d.ts.map +1 -0
  249. package/lib/typescript/src/components/Process/constants.d.ts +5 -0
  250. package/lib/typescript/src/components/Process/constants.d.ts.map +1 -0
  251. package/lib/typescript/src/components/Process/index.d.ts +3 -0
  252. package/lib/typescript/src/components/Process/index.d.ts.map +1 -0
  253. package/lib/typescript/src/components/Process/styles.d.ts +74 -0
  254. package/lib/typescript/src/components/Process/styles.d.ts.map +1 -0
  255. package/lib/typescript/src/components/Process/types.d.ts +32 -0
  256. package/lib/typescript/src/components/Process/types.d.ts.map +1 -0
  257. package/lib/typescript/src/components/Sources/Sources.d.ts +3 -0
  258. package/lib/typescript/src/components/Sources/Sources.d.ts.map +1 -0
  259. package/lib/typescript/src/components/Sources/constants.d.ts +2 -0
  260. package/lib/typescript/src/components/Sources/constants.d.ts.map +1 -0
  261. package/lib/typescript/src/components/Sources/index.d.ts +3 -0
  262. package/lib/typescript/src/components/Sources/index.d.ts.map +1 -0
  263. package/lib/typescript/src/components/Sources/styles.d.ts +49 -0
  264. package/lib/typescript/src/components/Sources/styles.d.ts.map +1 -0
  265. package/lib/typescript/src/components/Sources/types.d.ts +16 -0
  266. package/lib/typescript/src/components/Sources/types.d.ts.map +1 -0
  267. package/lib/typescript/src/components/Suggestions/Suggestions.d.ts +3 -0
  268. package/lib/typescript/src/components/Suggestions/Suggestions.d.ts.map +1 -0
  269. package/lib/typescript/src/components/Suggestions/index.d.ts +3 -0
  270. package/lib/typescript/src/components/Suggestions/index.d.ts.map +1 -0
  271. package/lib/typescript/src/components/Suggestions/styles.d.ts +14 -0
  272. package/lib/typescript/src/components/Suggestions/styles.d.ts.map +1 -0
  273. package/lib/typescript/src/components/Suggestions/types.d.ts +18 -0
  274. package/lib/typescript/src/components/Suggestions/types.d.ts.map +1 -0
  275. package/lib/typescript/src/index.d.ts +24 -0
  276. package/lib/typescript/src/index.d.ts.map +1 -0
  277. package/package.json +178 -0
  278. package/src/actions/index.ts +1 -0
  279. package/src/actions/types.ts +11 -0
  280. package/src/components/Attachments/AttachmentItem.tsx +139 -0
  281. package/src/components/Attachments/Attachments.tsx +72 -0
  282. package/src/components/Attachments/constants.ts +21 -0
  283. package/src/components/Attachments/index.ts +6 -0
  284. package/src/components/Attachments/styles.ts +54 -0
  285. package/src/components/Attachments/types.ts +38 -0
  286. package/src/components/Chat/Chat.tsx +26 -0
  287. package/src/components/Chat/index.ts +2 -0
  288. package/src/components/Chat/styles.ts +12 -0
  289. package/src/components/Chat/types.ts +11 -0
  290. package/src/components/Citation/Citation.tsx +33 -0
  291. package/src/components/Citation/index.ts +2 -0
  292. package/src/components/Citation/styles.ts +15 -0
  293. package/src/components/Citation/types.ts +7 -0
  294. package/src/components/Composer/Composer.tsx +208 -0
  295. package/src/components/Composer/constants.ts +11 -0
  296. package/src/components/Composer/index.ts +11 -0
  297. package/src/components/Composer/styles.ts +25 -0
  298. package/src/components/Composer/types.ts +61 -0
  299. package/src/components/Confirmation/Confirmation.tsx +63 -0
  300. package/src/components/Confirmation/constants.ts +12 -0
  301. package/src/components/Confirmation/index.ts +2 -0
  302. package/src/components/Confirmation/styles.ts +39 -0
  303. package/src/components/Confirmation/types.ts +21 -0
  304. package/src/components/Feedback/Feedback.tsx +87 -0
  305. package/src/components/Feedback/constants.ts +16 -0
  306. package/src/components/Feedback/index.ts +2 -0
  307. package/src/components/Feedback/styles.ts +30 -0
  308. package/src/components/Feedback/types.ts +13 -0
  309. package/src/components/Message/MarkdownContent/MarkdownContent.tsx +70 -0
  310. package/src/components/Message/MarkdownContent/MarkdownImage/MarkdownImage.tsx +52 -0
  311. package/src/components/Message/MarkdownContent/MarkdownImage/styles.ts +4 -0
  312. package/src/components/Message/MarkdownContent/MarkdownImage/types.ts +8 -0
  313. package/src/components/Message/MarkdownContent/styles.ts +61 -0
  314. package/src/components/Message/MarkdownContent/types.ts +4 -0
  315. package/src/components/Message/Message.tsx +137 -0
  316. package/src/components/Message/constants.ts +2 -0
  317. package/src/components/Message/index.ts +10 -0
  318. package/src/components/Message/isNestedAction.ts +22 -0
  319. package/src/components/Message/styles.ts +42 -0
  320. package/src/components/Message/types.ts +45 -0
  321. package/src/components/MessageList/MessageList.tsx +238 -0
  322. package/src/components/MessageList/constants.ts +1 -0
  323. package/src/components/MessageList/index.ts +6 -0
  324. package/src/components/MessageList/styles.ts +7 -0
  325. package/src/components/MessageList/types.ts +36 -0
  326. package/src/components/MessageList/webPrependAnchor/constants.ts +6 -0
  327. package/src/components/MessageList/webPrependAnchor/index.ts +7 -0
  328. package/src/components/MessageList/webPrependAnchor/types.ts +92 -0
  329. package/src/components/MessageList/webPrependAnchor/useWebPrependAnchor.ts +27 -0
  330. package/src/components/MessageList/webPrependAnchor/useWebPrependAnchor.web.ts +293 -0
  331. package/src/components/Process/Process.tsx +160 -0
  332. package/src/components/Process/constants.ts +22 -0
  333. package/src/components/Process/index.ts +9 -0
  334. package/src/components/Process/styles.ts +77 -0
  335. package/src/components/Process/types.ts +39 -0
  336. package/src/components/Sources/Sources.tsx +70 -0
  337. package/src/components/Sources/constants.ts +1 -0
  338. package/src/components/Sources/index.ts +2 -0
  339. package/src/components/Sources/styles.ts +59 -0
  340. package/src/components/Sources/types.ts +17 -0
  341. package/src/components/Suggestions/Suggestions.tsx +34 -0
  342. package/src/components/Suggestions/index.ts +2 -0
  343. package/src/components/Suggestions/styles.ts +16 -0
  344. package/src/components/Suggestions/types.ts +19 -0
  345. package/src/index.tsx +61 -0
@@ -0,0 +1,208 @@
1
+ import {
2
+ forwardRef,
3
+ useEffect,
4
+ useImperativeHandle,
5
+ useRef,
6
+ useState,
7
+ } from 'react';
8
+ import { Text, View } from 'react-native';
9
+ import {
10
+ Button,
11
+ fixed,
12
+ IconButton,
13
+ Textarea,
14
+ useTheme,
15
+ useThemedStyles,
16
+ } from '@unif/react-native-design';
17
+ import type { TextFieldHandle } from '@unif/react-native-design';
18
+ import {
19
+ DEFAULT_MAX_INPUT_HEIGHT,
20
+ PRIMARY_LABELS,
21
+ VOICE_LABELS,
22
+ } from './constants';
23
+ import { createStyles } from './styles';
24
+ import type { ComposerHandle, ComposerProps } from './types';
25
+
26
+ export const Composer = forwardRef<ComposerHandle, ComposerProps>(
27
+ function ComposerInput(
28
+ {
29
+ value,
30
+ onChangeText,
31
+ primaryAction,
32
+ editable = true,
33
+ disabled = false,
34
+ placeholder = '输入消息…',
35
+ inputAccessibilityLabel = '消息输入框',
36
+ actions = [],
37
+ voice,
38
+ header,
39
+ footer,
40
+ surface = 'card',
41
+ minInputHeight,
42
+ maxInputHeight,
43
+ onFocusChange,
44
+ onHeightChange,
45
+ style,
46
+ testID,
47
+ },
48
+ ref
49
+ ) {
50
+ const styles = useThemedStyles(createStyles);
51
+ const { fontScale } = useTheme();
52
+ const inputRef = useRef<TextFieldHandle>(null);
53
+ const lastHeight = useRef<number | undefined>(undefined);
54
+ const [menuOpen, setMenuOpen] = useState(false);
55
+ const voiceActive = voice !== undefined && voice.status !== 'idle';
56
+ const minHeight = Number.isFinite(minInputHeight)
57
+ ? Math.max(fixed.hitTarget, minInputHeight!)
58
+ : fixed.hitTarget;
59
+ const defaultMaxHeight = Math.max(
60
+ minHeight,
61
+ DEFAULT_MAX_INPUT_HEIGHT * fontScale
62
+ );
63
+ const maxHeight = Number.isFinite(maxInputHeight)
64
+ ? Math.max(minHeight, maxInputHeight!)
65
+ : defaultMaxHeight;
66
+
67
+ useImperativeHandle(
68
+ ref,
69
+ () => ({
70
+ focus: () => {
71
+ if (!disabled && !voiceActive) inputRef.current?.focus();
72
+ },
73
+ blur: () => inputRef.current?.blur(),
74
+ }),
75
+ [disabled, voiceActive]
76
+ );
77
+
78
+ useEffect(() => {
79
+ if (voiceActive) inputRef.current?.blur();
80
+ if (voiceActive || disabled) setMenuOpen(false);
81
+ }, [voiceActive, disabled]);
82
+
83
+ const primaryDisabled =
84
+ disabled ||
85
+ primaryAction.kind === 'busy' ||
86
+ primaryAction.disabled ||
87
+ (primaryAction.kind === 'send' &&
88
+ !primaryAction.allowEmpty &&
89
+ value.trim().length === 0);
90
+
91
+ return (
92
+ <View
93
+ testID={testID}
94
+ style={[styles.root, surface === 'card' && styles.card, style]}
95
+ onLayout={({ nativeEvent: { layout } }) => {
96
+ if (layout.height !== lastHeight.current) {
97
+ lastHeight.current = layout.height;
98
+ onHeightChange?.(layout.height);
99
+ }
100
+ }}
101
+ >
102
+ {header}
103
+ <View
104
+ style={[styles.regular, voiceActive && styles.hidden]}
105
+ importantForAccessibility={
106
+ voiceActive ? 'no-hide-descendants' : 'auto'
107
+ }
108
+ >
109
+ <Textarea
110
+ ref={inputRef}
111
+ value={value}
112
+ onChangeText={onChangeText}
113
+ editable={editable}
114
+ disabled={disabled || voiceActive}
115
+ placeholder={placeholder}
116
+ accessibilityLabel={inputAccessibilityLabel}
117
+ minHeight={minHeight}
118
+ maxHeight={maxHeight}
119
+ submitBehavior="newline"
120
+ onFocus={() => {
121
+ setMenuOpen(false);
122
+ onFocusChange?.(true);
123
+ }}
124
+ onBlur={() => onFocusChange?.(false)}
125
+ />
126
+ <View style={styles.toolbar}>
127
+ {actions.length > 0 ? (
128
+ <IconButton
129
+ icon="more-h"
130
+ size="lg"
131
+ accessibilityLabel="更多操作"
132
+ accessibilityState={{ expanded: menuOpen }}
133
+ disabled={disabled}
134
+ onPress={() => setMenuOpen((open) => !open)}
135
+ />
136
+ ) : null}
137
+ {voice ? (
138
+ <IconButton
139
+ icon="mic"
140
+ size="lg"
141
+ accessibilityLabel="开始语音输入"
142
+ disabled={disabled || voice.disabled}
143
+ onPress={voice.onStart}
144
+ />
145
+ ) : null}
146
+ <Button
147
+ label={primaryAction.label ?? PRIMARY_LABELS[primaryAction.kind]}
148
+ size="lg"
149
+ style={styles.primary}
150
+ disabled={primaryDisabled}
151
+ loading={primaryAction.kind === 'busy'}
152
+ onPress={() => {
153
+ if (primaryDisabled) return;
154
+ if (primaryAction.kind === 'send') primaryAction.onPress(value);
155
+ else if (primaryAction.kind === 'stop') primaryAction.onPress();
156
+ }}
157
+ />
158
+ </View>
159
+ {menuOpen && actions.length > 0 ? (
160
+ <View style={styles.menu}>
161
+ {actions.map((action) => (
162
+ <Button
163
+ key={action.id}
164
+ label={action.label}
165
+ leftIcon={action.icon}
166
+ disabled={disabled || action.disabled}
167
+ loading={action.loading}
168
+ variant="secondary"
169
+ accessibilityHint={action.accessibilityHint}
170
+ onPress={() => {
171
+ if (disabled || action.disabled || action.loading) return;
172
+ setMenuOpen(false);
173
+ action.onPress();
174
+ }}
175
+ />
176
+ ))}
177
+ </View>
178
+ ) : null}
179
+ </View>
180
+ {voice && voice.status !== 'idle' ? (
181
+ <View style={styles.voice}>
182
+ <Text style={styles.transcript} accessibilityLiveRegion="polite">
183
+ {voice.status === 'starting'
184
+ ? VOICE_LABELS.starting
185
+ : voice.transcript || VOICE_LABELS[voice.status]}
186
+ </Text>
187
+ <View style={styles.toolbar}>
188
+ {voice.status === 'listening' ? (
189
+ <Button
190
+ label="停止语音输入"
191
+ disabled={disabled || voice.disabled}
192
+ onPress={voice.onStop}
193
+ />
194
+ ) : null}
195
+ <Button
196
+ label="取消语音输入"
197
+ variant="secondary"
198
+ disabled={disabled || voice.disabled}
199
+ onPress={voice.onCancel}
200
+ />
201
+ </View>
202
+ </View>
203
+ ) : null}
204
+ {footer}
205
+ </View>
206
+ );
207
+ }
208
+ );
@@ -0,0 +1,11 @@
1
+ export const DEFAULT_MAX_INPUT_HEIGHT = 120;
2
+ export const PRIMARY_LABELS = {
3
+ send: '发送',
4
+ stop: '停止回复',
5
+ busy: '正在处理…',
6
+ } as const;
7
+ export const VOICE_LABELS = {
8
+ starting: '正在准备语音输入…',
9
+ listening: '正在听取…',
10
+ finishing: '正在完成识别…',
11
+ } as const;
@@ -0,0 +1,11 @@
1
+ export { Composer } from './Composer';
2
+ export type {
3
+ ComposerBusyAction,
4
+ ComposerHandle,
5
+ ComposerPrimaryAction,
6
+ ComposerProps,
7
+ ComposerSendAction,
8
+ ComposerStopAction,
9
+ ComposerVoiceControl,
10
+ ComposerVoiceStatus,
11
+ } from './types';
@@ -0,0 +1,25 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { radius, space, type } from '@unif/react-native-design';
3
+ import type { ColorTokens } from '@unif/react-native-design';
4
+
5
+ export const createStyles = (colors: ColorTokens) =>
6
+ StyleSheet.create({
7
+ root: { gap: space[2], minWidth: 0 },
8
+ card: {
9
+ padding: space[3],
10
+ borderRadius: radius.lg,
11
+ backgroundColor: colors.surface,
12
+ },
13
+ regular: { gap: space[2] },
14
+ hidden: { display: 'none' },
15
+ toolbar: {
16
+ flexDirection: 'row',
17
+ flexWrap: 'wrap',
18
+ alignItems: 'center',
19
+ gap: space[2],
20
+ },
21
+ primary: { marginStart: 'auto' },
22
+ menu: { flexDirection: 'row', flexWrap: 'wrap', gap: space[2] },
23
+ voice: { gap: space[3] },
24
+ transcript: { color: colors.foreground, fontSize: type.body },
25
+ });
@@ -0,0 +1,61 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { StyleProp, ViewStyle } from 'react-native';
3
+ import type { TextFieldHandle } from '@unif/react-native-design';
4
+ import type { ChatAction } from '../../actions';
5
+
6
+ export interface ComposerSendAction {
7
+ kind: 'send';
8
+ onPress(value: string): void;
9
+ allowEmpty?: boolean;
10
+ disabled?: boolean;
11
+ label?: string;
12
+ }
13
+
14
+ export interface ComposerStopAction {
15
+ kind: 'stop';
16
+ onPress(): void;
17
+ disabled?: boolean;
18
+ label?: string;
19
+ }
20
+
21
+ export interface ComposerBusyAction {
22
+ kind: 'busy';
23
+ label?: string;
24
+ }
25
+
26
+ export type ComposerPrimaryAction =
27
+ ComposerSendAction | ComposerStopAction | ComposerBusyAction;
28
+ export type ComposerVoiceStatus =
29
+ 'idle' | 'starting' | 'listening' | 'finishing';
30
+
31
+ export interface ComposerVoiceControl {
32
+ status: ComposerVoiceStatus;
33
+ transcript?: string;
34
+ disabled?: boolean;
35
+ onStart(): void;
36
+ onStop(): void;
37
+ onCancel(): void;
38
+ }
39
+
40
+ export interface ComposerProps {
41
+ value: string;
42
+ onChangeText(value: string): void;
43
+ primaryAction: ComposerPrimaryAction;
44
+ editable?: boolean;
45
+ disabled?: boolean;
46
+ placeholder?: string;
47
+ inputAccessibilityLabel?: string;
48
+ actions?: readonly ChatAction[];
49
+ voice?: ComposerVoiceControl;
50
+ header?: ReactNode;
51
+ footer?: ReactNode;
52
+ surface?: 'card' | 'plain';
53
+ minInputHeight?: number;
54
+ maxInputHeight?: number;
55
+ onFocusChange?(focused: boolean): void;
56
+ onHeightChange?(height: number): void;
57
+ style?: StyleProp<ViewStyle>;
58
+ testID?: string;
59
+ }
60
+
61
+ export type ComposerHandle = TextFieldHandle;
@@ -0,0 +1,63 @@
1
+ import { Text, View } from 'react-native';
2
+ import { Button, useThemedStyles } from '@unif/react-native-design';
3
+ import {
4
+ CONFIRMATION_STATUS_TEXT,
5
+ DEFAULT_CANCEL_LABEL,
6
+ DEFAULT_CONFIRM_LABEL,
7
+ } from './constants';
8
+ import { createStyles } from './styles';
9
+ import type { ConfirmationProps } from './types';
10
+
11
+ export function Confirmation({
12
+ title,
13
+ children,
14
+ status,
15
+ onConfirm,
16
+ onCancel,
17
+ confirmLabel = DEFAULT_CONFIRM_LABEL,
18
+ cancelLabel = DEFAULT_CANCEL_LABEL,
19
+ confirmDisabled = false,
20
+ cancelDisabled = false,
21
+ statusText,
22
+ footer,
23
+ style,
24
+ testID,
25
+ }: ConfirmationProps): React.JSX.Element {
26
+ const styles = useThemedStyles(createStyles);
27
+ const resolvedStatusText =
28
+ status === 'pending'
29
+ ? statusText
30
+ : (statusText ?? CONFIRMATION_STATUS_TEXT[status]);
31
+
32
+ return (
33
+ <View style={[styles.root, style]} testID={testID}>
34
+ <Text style={styles.title}>{title}</Text>
35
+ <View>{children}</View>
36
+ {resolvedStatusText ? (
37
+ <Text style={styles.status}>{resolvedStatusText}</Text>
38
+ ) : null}
39
+ {status === 'pending' && (onConfirm || onCancel) ? (
40
+ <View style={styles.actions}>
41
+ {onConfirm ? (
42
+ <Button
43
+ label={confirmLabel}
44
+ onPress={onConfirm}
45
+ disabled={confirmDisabled}
46
+ size="sm"
47
+ />
48
+ ) : null}
49
+ {onCancel ? (
50
+ <Button
51
+ label={cancelLabel}
52
+ onPress={onCancel}
53
+ disabled={cancelDisabled}
54
+ size="sm"
55
+ variant="outline"
56
+ />
57
+ ) : null}
58
+ </View>
59
+ ) : null}
60
+ {footer ? <View style={styles.footer}>{footer}</View> : null}
61
+ </View>
62
+ );
63
+ }
@@ -0,0 +1,12 @@
1
+ import type { ConfirmationStatus } from './types';
2
+
3
+ export const DEFAULT_CONFIRM_LABEL = '确认';
4
+ export const DEFAULT_CANCEL_LABEL = '取消';
5
+
6
+ export const CONFIRMATION_STATUS_TEXT: Readonly<
7
+ Record<Exclude<ConfirmationStatus, 'pending'>, string>
8
+ > = {
9
+ processing: '正在处理…',
10
+ confirmed: '已确认',
11
+ cancelled: '已取消',
12
+ };
@@ -0,0 +1,2 @@
1
+ export { Confirmation } from './Confirmation';
2
+ export type { ConfirmationProps, ConfirmationStatus } from './types';
@@ -0,0 +1,39 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import {
3
+ fw,
4
+ radius,
5
+ space,
6
+ type,
7
+ type ColorTokens,
8
+ } from '@unif/react-native-design';
9
+
10
+ export const createStyles = (colors: ColorTokens) =>
11
+ StyleSheet.create({
12
+ root: {
13
+ gap: space[4],
14
+ padding: space[5],
15
+ borderWidth: 1,
16
+ borderColor: colors.outline,
17
+ borderRadius: radius.xl,
18
+ backgroundColor: colors.surface,
19
+ },
20
+ title: {
21
+ color: colors.foreground,
22
+ fontSize: type.h3,
23
+ fontWeight: fw.semi,
24
+ },
25
+ status: {
26
+ color: colors.foregroundMuted,
27
+ fontSize: type.sm,
28
+ },
29
+ actions: {
30
+ flexDirection: 'row',
31
+ flexWrap: 'wrap',
32
+ gap: space[3],
33
+ },
34
+ footer: {
35
+ paddingTop: space[2],
36
+ borderTopWidth: StyleSheet.hairlineWidth,
37
+ borderTopColor: colors.outline,
38
+ },
39
+ });
@@ -0,0 +1,21 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { StyleProp, ViewStyle } from 'react-native';
3
+
4
+ export type ConfirmationStatus =
5
+ 'pending' | 'processing' | 'confirmed' | 'cancelled';
6
+
7
+ export interface ConfirmationProps {
8
+ title: string;
9
+ children: ReactNode;
10
+ status: ConfirmationStatus;
11
+ onConfirm?(): void;
12
+ onCancel?(): void;
13
+ confirmLabel?: string;
14
+ cancelLabel?: string;
15
+ confirmDisabled?: boolean;
16
+ cancelDisabled?: boolean;
17
+ statusText?: string;
18
+ footer?: ReactNode;
19
+ style?: StyleProp<ViewStyle>;
20
+ testID?: string;
21
+ }
@@ -0,0 +1,87 @@
1
+ import { Text, View } from 'react-native';
2
+ import {
3
+ Button,
4
+ Icon,
5
+ useColors,
6
+ useThemedStyles,
7
+ } from '@unif/react-native-design';
8
+ import { FEEDBACK_TONE_ICONS, FEEDBACK_TONE_LABELS } from './constants';
9
+ import { createStyles } from './styles';
10
+ import type { FeedbackProps, FeedbackTone } from './types';
11
+
12
+ function colorsForTone(
13
+ tone: FeedbackTone,
14
+ colors: ReturnType<typeof useColors>
15
+ ) {
16
+ switch (tone) {
17
+ case 'success':
18
+ return {
19
+ backgroundColor: colors.successContainer,
20
+ iconColor: colors.success,
21
+ };
22
+ case 'warning':
23
+ return {
24
+ backgroundColor: colors.primaryContainer,
25
+ iconColor: colors.primary,
26
+ };
27
+ case 'error':
28
+ return {
29
+ backgroundColor: colors.errorContainer,
30
+ iconColor: colors.error,
31
+ };
32
+ case 'info':
33
+ return { backgroundColor: colors.infoContainer, iconColor: colors.info };
34
+ }
35
+ }
36
+
37
+ export function Feedback({
38
+ message,
39
+ title,
40
+ tone = 'info',
41
+ action,
42
+ style,
43
+ testID,
44
+ }: FeedbackProps): React.JSX.Element {
45
+ const styles = useThemedStyles(createStyles);
46
+ const colors = useColors();
47
+ const toneColors = colorsForTone(tone, colors);
48
+ const toneLabel = FEEDBACK_TONE_LABELS[tone];
49
+ const accessibilityLabel = `${toneLabel}:${title ? `${title}。` : ''}${message}`;
50
+
51
+ return (
52
+ <View
53
+ style={[
54
+ styles.root,
55
+ { backgroundColor: toneColors.backgroundColor },
56
+ style,
57
+ ]}
58
+ testID={testID}
59
+ >
60
+ <Icon name={FEEDBACK_TONE_ICONS[tone]} color={toneColors.iconColor} />
61
+ <View style={styles.content}>
62
+ <View accessible accessibilityLabel={accessibilityLabel}>
63
+ {title ? (
64
+ <Text style={styles.title} testID="feedback-title">
65
+ {title}
66
+ </Text>
67
+ ) : null}
68
+ <Text style={styles.message}>{message}</Text>
69
+ </View>
70
+ {action ? (
71
+ <View style={styles.action}>
72
+ <Button
73
+ label={action.label}
74
+ leftIcon={action.icon}
75
+ onPress={action.onPress}
76
+ disabled={action.disabled}
77
+ loading={action.loading}
78
+ accessibilityHint={action.accessibilityHint}
79
+ size="sm"
80
+ variant="outline"
81
+ />
82
+ </View>
83
+ ) : null}
84
+ </View>
85
+ </View>
86
+ );
87
+ }
@@ -0,0 +1,16 @@
1
+ import type { IconName } from '@unif/react-native-design';
2
+ import type { FeedbackTone } from './types';
3
+
4
+ export const FEEDBACK_TONE_LABELS: Readonly<Record<FeedbackTone, string>> = {
5
+ info: '信息',
6
+ success: '成功',
7
+ warning: '警告',
8
+ error: '错误',
9
+ };
10
+
11
+ export const FEEDBACK_TONE_ICONS: Readonly<Record<FeedbackTone, IconName>> = {
12
+ info: 'info',
13
+ success: 'success',
14
+ warning: 'warning',
15
+ error: 'error',
16
+ };
@@ -0,0 +1,2 @@
1
+ export { Feedback } from './Feedback';
2
+ export type { FeedbackProps, FeedbackTone } from './types';
@@ -0,0 +1,30 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { fw, radius, space, type } from '@unif/react-native-design';
3
+ import type { ColorTokens } from '@unif/react-native-design';
4
+
5
+ export const createStyles = (colors: ColorTokens) =>
6
+ StyleSheet.create({
7
+ root: {
8
+ flexDirection: 'row',
9
+ alignItems: 'flex-start',
10
+ gap: space[3],
11
+ padding: space[4],
12
+ borderRadius: radius.lg,
13
+ },
14
+ content: {
15
+ flex: 1,
16
+ gap: space[1],
17
+ },
18
+ title: {
19
+ color: colors.foreground,
20
+ fontSize: type.sm,
21
+ fontWeight: fw.semi,
22
+ },
23
+ message: {
24
+ color: colors.foregroundMuted,
25
+ fontSize: type.sm,
26
+ },
27
+ action: {
28
+ paddingTop: space[3],
29
+ },
30
+ });
@@ -0,0 +1,13 @@
1
+ import type { StyleProp, ViewStyle } from 'react-native';
2
+ import type { ChatAction } from '../../actions';
3
+
4
+ export type FeedbackTone = 'info' | 'success' | 'warning' | 'error';
5
+
6
+ export interface FeedbackProps {
7
+ message: string;
8
+ title?: string;
9
+ tone?: FeedbackTone;
10
+ action?: ChatAction;
11
+ style?: StyleProp<ViewStyle>;
12
+ testID?: string;
13
+ }
@@ -0,0 +1,70 @@
1
+ import { Children, Fragment, useMemo } from 'react';
2
+ import { Pressable, Text } from 'react-native';
3
+ import { Renderer, useMarkdown } from 'react-native-marked';
4
+ import { useTheme, useThemedStyles } from '@unif/react-native-design';
5
+ import { createStyles } from './styles';
6
+ import type { MarkdownContentProps } from './types';
7
+ import { MarkdownImage } from './MarkdownImage/MarkdownImage';
8
+
9
+ export function MarkdownContent({ text, onLinkPress }: MarkdownContentProps) {
10
+ const { scheme } = useTheme();
11
+ const styles = useThemedStyles(createStyles);
12
+ const markdown = useMemo(() => {
13
+ const instance = new Renderer();
14
+ // 上游 table 节点未提供 key,保留其渲染并补齐稳定的节点身份。
15
+ const renderTable = instance.table.bind(instance);
16
+ instance.table = (...args) => (
17
+ <Fragment key={instance.getKey()}>{renderTable(...args)}</Fragment>
18
+ );
19
+ instance.image = (uri, alt, _imageStyle, title) => (
20
+ <MarkdownImage key={instance.getKey()} uri={uri} label={alt || title} />
21
+ );
22
+ instance.link = (children, href, linkStyle, title) => (
23
+ <Text
24
+ key={instance.getKey()}
25
+ selectable
26
+ style={linkStyle}
27
+ accessibilityRole={onLinkPress ? 'link' : undefined}
28
+ accessibilityLabel={
29
+ title || (typeof children === 'string' ? children : undefined)
30
+ }
31
+ onPress={
32
+ onLinkPress
33
+ ? (event) => {
34
+ event.stopPropagation();
35
+ onLinkPress(href);
36
+ }
37
+ : undefined
38
+ }
39
+ >
40
+ {children}
41
+ </Text>
42
+ );
43
+ instance.linkImage = (href, uri, alt, imageStyle, title) => {
44
+ const content = instance.image(uri, alt, imageStyle, title);
45
+ return onLinkPress ? (
46
+ <Pressable
47
+ key={instance.getKey()}
48
+ accessibilityRole="link"
49
+ accessibilityLabel={alt || title || '图片链接'}
50
+ onPress={(event) => {
51
+ event.stopPropagation();
52
+ onLinkPress(href);
53
+ }}
54
+ >
55
+ {content}
56
+ </Pressable>
57
+ ) : (
58
+ content
59
+ );
60
+ };
61
+ return { renderer: instance, text, styles };
62
+ // Renderer 的 key 计数按每次解析重新开始,流式正文保留已有图片节点。
63
+ }, [onLinkPress, text, styles]);
64
+ const nodes = useMarkdown(markdown.text, {
65
+ renderer: markdown.renderer,
66
+ colorScheme: scheme,
67
+ styles: markdown.styles,
68
+ });
69
+ return <>{Children.toArray(nodes)}</>;
70
+ }