@oxy.so/bloom 5.1.0 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (430) hide show
  1. package/docs/adoption-matrix.mdx +9 -9
  2. package/docs/button.mdx +2 -0
  3. package/docs/card-form.mdx +2 -0
  4. package/docs/chat-composer.mdx +1 -1
  5. package/docs/earnings.mdx +2 -0
  6. package/docs/field.mdx +2 -0
  7. package/docs/label.mdx +2 -0
  8. package/docs/payment-method.mdx +2 -0
  9. package/docs/place-details.mdx +2 -2
  10. package/docs/proof-of-delivery.mdx +4 -0
  11. package/docs/select.mdx +2 -0
  12. package/lib/commonjs/button/Button.js +36 -3
  13. package/lib/commonjs/button/Button.js.map +1 -1
  14. package/lib/commonjs/button/GlyphButton.js +7 -3
  15. package/lib/commonjs/button/GlyphButton.js.map +1 -1
  16. package/lib/commonjs/card-form/shared.js +3 -2
  17. package/lib/commonjs/card-form/shared.js.map +1 -1
  18. package/lib/commonjs/chat-composer/AttachmentMenu.js +8 -227
  19. package/lib/commonjs/chat-composer/AttachmentMenu.js.map +1 -1
  20. package/lib/commonjs/chat-composer/AttachmentMenu.web.js +16 -0
  21. package/lib/commonjs/chat-composer/AttachmentMenu.web.js.map +1 -0
  22. package/lib/commonjs/chat-composer/ChatComposer.js +9 -388
  23. package/lib/commonjs/chat-composer/ChatComposer.js.map +1 -1
  24. package/lib/commonjs/chat-composer/ChatComposer.web.js +16 -0
  25. package/lib/commonjs/chat-composer/ChatComposer.web.js.map +1 -0
  26. package/lib/commonjs/chat-composer/ComposerAttachmentStrip.js +5 -200
  27. package/lib/commonjs/chat-composer/ComposerAttachmentStrip.js.map +1 -1
  28. package/lib/commonjs/chat-composer/ComposerAttachmentStrip.web.js +12 -0
  29. package/lib/commonjs/chat-composer/ComposerAttachmentStrip.web.js.map +1 -0
  30. package/lib/commonjs/chat-composer/ComposerBanner.js +5 -163
  31. package/lib/commonjs/chat-composer/ComposerBanner.js.map +1 -1
  32. package/lib/commonjs/chat-composer/ComposerBanner.web.js +12 -0
  33. package/lib/commonjs/chat-composer/ComposerBanner.web.js.map +1 -0
  34. package/lib/commonjs/chat-composer/EmojiPicker.js +6 -443
  35. package/lib/commonjs/chat-composer/EmojiPicker.js.map +1 -1
  36. package/lib/commonjs/chat-composer/EmojiPicker.web.js +14 -0
  37. package/lib/commonjs/chat-composer/EmojiPicker.web.js.map +1 -0
  38. package/lib/commonjs/chat-composer/MessageContextMenu.js +12 -102
  39. package/lib/commonjs/chat-composer/MessageContextMenu.js.map +1 -1
  40. package/lib/commonjs/chat-composer/MessageContextMenu.web.js +19 -0
  41. package/lib/commonjs/chat-composer/MessageContextMenu.web.js.map +1 -0
  42. package/lib/commonjs/chat-composer/ReactionPicker.js +6 -107
  43. package/lib/commonjs/chat-composer/ReactionPicker.js.map +1 -1
  44. package/lib/commonjs/chat-composer/ReactionPicker.web.js +14 -0
  45. package/lib/commonjs/chat-composer/ReactionPicker.web.js.map +1 -0
  46. package/lib/commonjs/chat-composer/SuggestionList.js +5 -222
  47. package/lib/commonjs/chat-composer/SuggestionList.js.map +1 -1
  48. package/lib/commonjs/chat-composer/SuggestionList.web.js +12 -0
  49. package/lib/commonjs/chat-composer/SuggestionList.web.js.map +1 -0
  50. package/lib/commonjs/chat-composer/VoiceRecorder.js +7 -263
  51. package/lib/commonjs/chat-composer/VoiceRecorder.js.map +1 -1
  52. package/lib/commonjs/chat-composer/VoiceRecorder.web.js +16 -0
  53. package/lib/commonjs/chat-composer/VoiceRecorder.web.js.map +1 -0
  54. package/lib/commonjs/chat-composer/create-attachment-menu.js +243 -0
  55. package/lib/commonjs/chat-composer/create-attachment-menu.js.map +1 -0
  56. package/lib/commonjs/chat-composer/create-chat-composer.js +400 -0
  57. package/lib/commonjs/chat-composer/create-chat-composer.js.map +1 -0
  58. package/lib/commonjs/chat-composer/create-composer-attachment-strip.js +212 -0
  59. package/lib/commonjs/chat-composer/create-composer-attachment-strip.js.map +1 -0
  60. package/lib/commonjs/chat-composer/create-composer-banner.js +176 -0
  61. package/lib/commonjs/chat-composer/create-composer-banner.js.map +1 -0
  62. package/lib/commonjs/chat-composer/create-emoji-picker.js +456 -0
  63. package/lib/commonjs/chat-composer/create-emoji-picker.js.map +1 -0
  64. package/lib/commonjs/chat-composer/create-message-context-menu.js +119 -0
  65. package/lib/commonjs/chat-composer/create-message-context-menu.js.map +1 -0
  66. package/lib/commonjs/chat-composer/create-reaction-picker.js +120 -0
  67. package/lib/commonjs/chat-composer/create-reaction-picker.js.map +1 -0
  68. package/lib/commonjs/chat-composer/create-suggestion-list.js +234 -0
  69. package/lib/commonjs/chat-composer/create-suggestion-list.js.map +1 -0
  70. package/lib/commonjs/chat-composer/create-voice-recorder.js +277 -0
  71. package/lib/commonjs/chat-composer/create-voice-recorder.js.map +1 -0
  72. package/lib/commonjs/chat-composer/index.js +9 -9
  73. package/lib/commonjs/chat-composer/index.web.js +18 -18
  74. package/lib/commonjs/chat-composer/index.web.js.map +1 -1
  75. package/lib/commonjs/earnings/EarningsSummary.js +12 -2
  76. package/lib/commonjs/earnings/EarningsSummary.js.map +1 -1
  77. package/lib/commonjs/field/Field.js +2 -0
  78. package/lib/commonjs/field/Field.js.map +1 -1
  79. package/lib/commonjs/item/Item.js +16 -8
  80. package/lib/commonjs/item/Item.js.map +1 -1
  81. package/lib/commonjs/job-board/JobCard.js +6 -2
  82. package/lib/commonjs/job-board/JobCard.js.map +1 -1
  83. package/lib/commonjs/label/Label.js +2 -1
  84. package/lib/commonjs/label/Label.js.map +1 -1
  85. package/lib/commonjs/listing-details/AmenityList.js +4 -3
  86. package/lib/commonjs/listing-details/AmenityList.js.map +1 -1
  87. package/lib/commonjs/mail-compose/MailComposeSurface.js +1 -1
  88. package/lib/commonjs/overlay/InteractionBoundary.js +28 -0
  89. package/lib/commonjs/overlay/InteractionBoundary.js.map +1 -0
  90. package/lib/commonjs/payment-method/PaymentMethodList.js +3 -2
  91. package/lib/commonjs/payment-method/PaymentMethodList.js.map +1 -1
  92. package/lib/commonjs/place-details/PlaceAmenities.js +17 -6
  93. package/lib/commonjs/place-details/PlaceAmenities.js.map +1 -1
  94. package/lib/commonjs/place-details/PlacePopularTimes.js +7 -1
  95. package/lib/commonjs/place-details/PlacePopularTimes.js.map +1 -1
  96. package/lib/commonjs/proof-of-delivery/ProofOfDelivery.js +10 -1
  97. package/lib/commonjs/proof-of-delivery/ProofOfDelivery.js.map +1 -1
  98. package/lib/commonjs/proof-of-delivery/shared.js +1 -1
  99. package/lib/commonjs/proof-of-delivery/shared.js.map +1 -1
  100. package/lib/commonjs/select/Select.js +7 -4
  101. package/lib/commonjs/select/Select.js.map +1 -1
  102. package/lib/commonjs/select/Select.web.js +7 -4
  103. package/lib/commonjs/select/Select.web.js.map +1 -1
  104. package/lib/commonjs/select/use-required-description.js +37 -0
  105. package/lib/commonjs/select/use-required-description.js.map +1 -0
  106. package/lib/module/button/Button.js +36 -3
  107. package/lib/module/button/Button.js.map +1 -1
  108. package/lib/module/button/GlyphButton.js +7 -3
  109. package/lib/module/button/GlyphButton.js.map +1 -1
  110. package/lib/module/card-form/shared.js +3 -2
  111. package/lib/module/card-form/shared.js.map +1 -1
  112. package/lib/module/chat-composer/AttachmentMenu.js +7 -226
  113. package/lib/module/chat-composer/AttachmentMenu.js.map +1 -1
  114. package/lib/module/chat-composer/AttachmentMenu.web.js +12 -0
  115. package/lib/module/chat-composer/AttachmentMenu.web.js.map +1 -0
  116. package/lib/module/chat-composer/ChatComposer.js +8 -385
  117. package/lib/module/chat-composer/ChatComposer.js.map +1 -1
  118. package/lib/module/chat-composer/ChatComposer.web.js +12 -0
  119. package/lib/module/chat-composer/ChatComposer.web.js.map +1 -0
  120. package/lib/module/chat-composer/ComposerAttachmentStrip.js +4 -196
  121. package/lib/module/chat-composer/ComposerAttachmentStrip.js.map +1 -1
  122. package/lib/module/chat-composer/ComposerAttachmentStrip.web.js +8 -0
  123. package/lib/module/chat-composer/ComposerAttachmentStrip.web.js.map +1 -0
  124. package/lib/module/chat-composer/ComposerBanner.js +4 -162
  125. package/lib/module/chat-composer/ComposerBanner.js.map +1 -1
  126. package/lib/module/chat-composer/ComposerBanner.web.js +8 -0
  127. package/lib/module/chat-composer/ComposerBanner.web.js.map +1 -0
  128. package/lib/module/chat-composer/EmojiPicker.js +5 -440
  129. package/lib/module/chat-composer/EmojiPicker.js.map +1 -1
  130. package/lib/module/chat-composer/EmojiPicker.web.js +10 -0
  131. package/lib/module/chat-composer/EmojiPicker.web.js.map +1 -0
  132. package/lib/module/chat-composer/MessageContextMenu.js +11 -99
  133. package/lib/module/chat-composer/MessageContextMenu.js.map +1 -1
  134. package/lib/module/chat-composer/MessageContextMenu.web.js +15 -0
  135. package/lib/module/chat-composer/MessageContextMenu.web.js.map +1 -0
  136. package/lib/module/chat-composer/ReactionPicker.js +5 -104
  137. package/lib/module/chat-composer/ReactionPicker.js.map +1 -1
  138. package/lib/module/chat-composer/ReactionPicker.web.js +10 -0
  139. package/lib/module/chat-composer/ReactionPicker.web.js.map +1 -0
  140. package/lib/module/chat-composer/SuggestionList.js +4 -219
  141. package/lib/module/chat-composer/SuggestionList.js.map +1 -1
  142. package/lib/module/chat-composer/SuggestionList.web.js +8 -0
  143. package/lib/module/chat-composer/SuggestionList.web.js.map +1 -0
  144. package/lib/module/chat-composer/VoiceRecorder.js +6 -260
  145. package/lib/module/chat-composer/VoiceRecorder.js.map +1 -1
  146. package/lib/module/chat-composer/VoiceRecorder.web.js +12 -0
  147. package/lib/module/chat-composer/VoiceRecorder.web.js.map +1 -0
  148. package/lib/module/chat-composer/create-attachment-menu.js +238 -0
  149. package/lib/module/chat-composer/create-attachment-menu.js.map +1 -0
  150. package/lib/module/chat-composer/create-chat-composer.js +395 -0
  151. package/lib/module/chat-composer/create-chat-composer.js.map +1 -0
  152. package/lib/module/chat-composer/create-composer-attachment-strip.js +206 -0
  153. package/lib/module/chat-composer/create-composer-attachment-strip.js.map +1 -0
  154. package/lib/module/chat-composer/create-composer-banner.js +171 -0
  155. package/lib/module/chat-composer/create-composer-banner.js.map +1 -0
  156. package/lib/module/chat-composer/create-emoji-picker.js +451 -0
  157. package/lib/module/chat-composer/create-emoji-picker.js.map +1 -0
  158. package/lib/module/chat-composer/create-message-context-menu.js +114 -0
  159. package/lib/module/chat-composer/create-message-context-menu.js.map +1 -0
  160. package/lib/module/chat-composer/create-reaction-picker.js +115 -0
  161. package/lib/module/chat-composer/create-reaction-picker.js.map +1 -0
  162. package/lib/module/chat-composer/create-suggestion-list.js +229 -0
  163. package/lib/module/chat-composer/create-suggestion-list.js.map +1 -0
  164. package/lib/module/chat-composer/create-voice-recorder.js +272 -0
  165. package/lib/module/chat-composer/create-voice-recorder.js.map +1 -0
  166. package/lib/module/chat-composer/index.js +9 -9
  167. package/lib/module/chat-composer/index.js.map +1 -1
  168. package/lib/module/chat-composer/index.web.js +9 -9
  169. package/lib/module/chat-composer/index.web.js.map +1 -1
  170. package/lib/module/earnings/EarningsSummary.js +12 -2
  171. package/lib/module/earnings/EarningsSummary.js.map +1 -1
  172. package/lib/module/field/Field.js +2 -0
  173. package/lib/module/field/Field.js.map +1 -1
  174. package/lib/module/item/Item.js +16 -8
  175. package/lib/module/item/Item.js.map +1 -1
  176. package/lib/module/job-board/JobCard.js +6 -2
  177. package/lib/module/job-board/JobCard.js.map +1 -1
  178. package/lib/module/label/Label.js +2 -1
  179. package/lib/module/label/Label.js.map +1 -1
  180. package/lib/module/listing-details/AmenityList.js +4 -3
  181. package/lib/module/listing-details/AmenityList.js.map +1 -1
  182. package/lib/module/mail-compose/MailComposeSurface.js +1 -1
  183. package/lib/module/mail-compose/MailComposeSurface.js.map +1 -1
  184. package/lib/module/overlay/InteractionBoundary.js +25 -0
  185. package/lib/module/overlay/InteractionBoundary.js.map +1 -0
  186. package/lib/module/payment-method/PaymentMethodList.js +3 -2
  187. package/lib/module/payment-method/PaymentMethodList.js.map +1 -1
  188. package/lib/module/place-details/PlaceAmenities.js +15 -4
  189. package/lib/module/place-details/PlaceAmenities.js.map +1 -1
  190. package/lib/module/place-details/PlacePopularTimes.js +7 -1
  191. package/lib/module/place-details/PlacePopularTimes.js.map +1 -1
  192. package/lib/module/proof-of-delivery/ProofOfDelivery.js +10 -1
  193. package/lib/module/proof-of-delivery/ProofOfDelivery.js.map +1 -1
  194. package/lib/module/proof-of-delivery/shared.js +1 -1
  195. package/lib/module/proof-of-delivery/shared.js.map +1 -1
  196. package/lib/module/select/Select.js +7 -4
  197. package/lib/module/select/Select.js.map +1 -1
  198. package/lib/module/select/Select.web.js +7 -4
  199. package/lib/module/select/Select.web.js.map +1 -1
  200. package/lib/module/select/use-required-description.js +33 -0
  201. package/lib/module/select/use-required-description.js.map +1 -0
  202. package/lib/typescript/commonjs/button/Button.d.ts.map +1 -1
  203. package/lib/typescript/commonjs/card-form/shared.d.ts +2 -1
  204. package/lib/typescript/commonjs/card-form/shared.d.ts.map +1 -1
  205. package/lib/typescript/commonjs/chat-composer/AttachmentMenu.d.ts +1 -2
  206. package/lib/typescript/commonjs/chat-composer/AttachmentMenu.d.ts.map +1 -1
  207. package/lib/typescript/commonjs/chat-composer/AttachmentMenu.web.d.ts +2 -0
  208. package/lib/typescript/commonjs/chat-composer/AttachmentMenu.web.d.ts.map +1 -0
  209. package/lib/typescript/commonjs/chat-composer/ChatComposer.d.ts +1 -2
  210. package/lib/typescript/commonjs/chat-composer/ChatComposer.d.ts.map +1 -1
  211. package/lib/typescript/commonjs/chat-composer/ChatComposer.web.d.ts +2 -0
  212. package/lib/typescript/commonjs/chat-composer/ChatComposer.web.d.ts.map +1 -0
  213. package/lib/typescript/commonjs/chat-composer/ComposerAttachmentStrip.d.ts +1 -2
  214. package/lib/typescript/commonjs/chat-composer/ComposerAttachmentStrip.d.ts.map +1 -1
  215. package/lib/typescript/commonjs/chat-composer/ComposerAttachmentStrip.web.d.ts +2 -0
  216. package/lib/typescript/commonjs/chat-composer/ComposerAttachmentStrip.web.d.ts.map +1 -0
  217. package/lib/typescript/commonjs/chat-composer/ComposerBanner.d.ts +1 -2
  218. package/lib/typescript/commonjs/chat-composer/ComposerBanner.d.ts.map +1 -1
  219. package/lib/typescript/commonjs/chat-composer/ComposerBanner.web.d.ts +2 -0
  220. package/lib/typescript/commonjs/chat-composer/ComposerBanner.web.d.ts.map +1 -0
  221. package/lib/typescript/commonjs/chat-composer/EmojiPicker.d.ts +1 -2
  222. package/lib/typescript/commonjs/chat-composer/EmojiPicker.d.ts.map +1 -1
  223. package/lib/typescript/commonjs/chat-composer/EmojiPicker.web.d.ts +2 -0
  224. package/lib/typescript/commonjs/chat-composer/EmojiPicker.web.d.ts.map +1 -0
  225. package/lib/typescript/commonjs/chat-composer/MessageContextMenu.d.ts +1 -2
  226. package/lib/typescript/commonjs/chat-composer/MessageContextMenu.d.ts.map +1 -1
  227. package/lib/typescript/commonjs/chat-composer/MessageContextMenu.web.d.ts +2 -0
  228. package/lib/typescript/commonjs/chat-composer/MessageContextMenu.web.d.ts.map +1 -0
  229. package/lib/typescript/commonjs/chat-composer/ReactionPicker.d.ts +1 -2
  230. package/lib/typescript/commonjs/chat-composer/ReactionPicker.d.ts.map +1 -1
  231. package/lib/typescript/commonjs/chat-composer/ReactionPicker.web.d.ts +2 -0
  232. package/lib/typescript/commonjs/chat-composer/ReactionPicker.web.d.ts.map +1 -0
  233. package/lib/typescript/commonjs/chat-composer/SuggestionList.d.ts +1 -2
  234. package/lib/typescript/commonjs/chat-composer/SuggestionList.d.ts.map +1 -1
  235. package/lib/typescript/commonjs/chat-composer/SuggestionList.web.d.ts +2 -0
  236. package/lib/typescript/commonjs/chat-composer/SuggestionList.web.d.ts.map +1 -0
  237. package/lib/typescript/commonjs/chat-composer/VoiceRecorder.d.ts +1 -2
  238. package/lib/typescript/commonjs/chat-composer/VoiceRecorder.d.ts.map +1 -1
  239. package/lib/typescript/commonjs/chat-composer/VoiceRecorder.web.d.ts +2 -0
  240. package/lib/typescript/commonjs/chat-composer/VoiceRecorder.web.d.ts.map +1 -0
  241. package/lib/typescript/commonjs/chat-composer/create-attachment-menu.d.ts +11 -0
  242. package/lib/typescript/commonjs/chat-composer/create-attachment-menu.d.ts.map +1 -0
  243. package/lib/typescript/commonjs/chat-composer/create-chat-composer.d.ts +11 -0
  244. package/lib/typescript/commonjs/chat-composer/create-chat-composer.d.ts.map +1 -0
  245. package/lib/typescript/commonjs/chat-composer/create-composer-attachment-strip.d.ts +7 -0
  246. package/lib/typescript/commonjs/chat-composer/create-composer-attachment-strip.d.ts.map +1 -0
  247. package/lib/typescript/commonjs/chat-composer/create-composer-banner.d.ts +7 -0
  248. package/lib/typescript/commonjs/chat-composer/create-composer-banner.d.ts.map +1 -0
  249. package/lib/typescript/commonjs/chat-composer/create-emoji-picker.d.ts +9 -0
  250. package/lib/typescript/commonjs/chat-composer/create-emoji-picker.d.ts.map +1 -0
  251. package/lib/typescript/commonjs/chat-composer/create-message-context-menu.d.ts +14 -0
  252. package/lib/typescript/commonjs/chat-composer/create-message-context-menu.d.ts.map +1 -0
  253. package/lib/typescript/commonjs/chat-composer/create-reaction-picker.d.ts +9 -0
  254. package/lib/typescript/commonjs/chat-composer/create-reaction-picker.d.ts.map +1 -0
  255. package/lib/typescript/commonjs/chat-composer/create-suggestion-list.d.ts +7 -0
  256. package/lib/typescript/commonjs/chat-composer/create-suggestion-list.d.ts.map +1 -0
  257. package/lib/typescript/commonjs/chat-composer/create-voice-recorder.d.ts +11 -0
  258. package/lib/typescript/commonjs/chat-composer/create-voice-recorder.d.ts.map +1 -0
  259. package/lib/typescript/commonjs/chat-composer/index.web.d.ts +9 -9
  260. package/lib/typescript/commonjs/chat-composer/index.web.d.ts.map +1 -1
  261. package/lib/typescript/commonjs/earnings/EarningsSummary.d.ts.map +1 -1
  262. package/lib/typescript/commonjs/field/Field.d.ts +1 -1
  263. package/lib/typescript/commonjs/field/Field.d.ts.map +1 -1
  264. package/lib/typescript/commonjs/field/types.d.ts +2 -0
  265. package/lib/typescript/commonjs/field/types.d.ts.map +1 -1
  266. package/lib/typescript/commonjs/floating/types.d.ts +1 -0
  267. package/lib/typescript/commonjs/floating/types.d.ts.map +1 -1
  268. package/lib/typescript/commonjs/item/Item.d.ts.map +1 -1
  269. package/lib/typescript/commonjs/job-board/JobCard.d.ts.map +1 -1
  270. package/lib/typescript/commonjs/label/Label.d.ts +1 -1
  271. package/lib/typescript/commonjs/label/Label.d.ts.map +1 -1
  272. package/lib/typescript/commonjs/label/types.d.ts +2 -0
  273. package/lib/typescript/commonjs/label/types.d.ts.map +1 -1
  274. package/lib/typescript/commonjs/listing-details/AmenityList.d.ts.map +1 -1
  275. package/lib/typescript/commonjs/overlay/InteractionBoundary.d.ts +7 -0
  276. package/lib/typescript/commonjs/overlay/InteractionBoundary.d.ts.map +1 -0
  277. package/lib/typescript/commonjs/payment-method/PaymentMethodList.d.ts.map +1 -1
  278. package/lib/typescript/commonjs/place-details/PlaceAmenities.d.ts.map +1 -1
  279. package/lib/typescript/commonjs/place-details/PlacePopularTimes.d.ts.map +1 -1
  280. package/lib/typescript/commonjs/proof-of-delivery/ProofOfDelivery.d.ts.map +1 -1
  281. package/lib/typescript/commonjs/select/Select.d.ts.map +1 -1
  282. package/lib/typescript/commonjs/select/Select.web.d.ts.map +1 -1
  283. package/lib/typescript/commonjs/select/use-required-description.d.ts +7 -0
  284. package/lib/typescript/commonjs/select/use-required-description.d.ts.map +1 -0
  285. package/lib/typescript/module/button/Button.d.ts.map +1 -1
  286. package/lib/typescript/module/card-form/shared.d.ts +2 -1
  287. package/lib/typescript/module/card-form/shared.d.ts.map +1 -1
  288. package/lib/typescript/module/chat-composer/AttachmentMenu.d.ts +1 -2
  289. package/lib/typescript/module/chat-composer/AttachmentMenu.d.ts.map +1 -1
  290. package/lib/typescript/module/chat-composer/AttachmentMenu.web.d.ts +2 -0
  291. package/lib/typescript/module/chat-composer/AttachmentMenu.web.d.ts.map +1 -0
  292. package/lib/typescript/module/chat-composer/ChatComposer.d.ts +1 -2
  293. package/lib/typescript/module/chat-composer/ChatComposer.d.ts.map +1 -1
  294. package/lib/typescript/module/chat-composer/ChatComposer.web.d.ts +2 -0
  295. package/lib/typescript/module/chat-composer/ChatComposer.web.d.ts.map +1 -0
  296. package/lib/typescript/module/chat-composer/ComposerAttachmentStrip.d.ts +1 -2
  297. package/lib/typescript/module/chat-composer/ComposerAttachmentStrip.d.ts.map +1 -1
  298. package/lib/typescript/module/chat-composer/ComposerAttachmentStrip.web.d.ts +2 -0
  299. package/lib/typescript/module/chat-composer/ComposerAttachmentStrip.web.d.ts.map +1 -0
  300. package/lib/typescript/module/chat-composer/ComposerBanner.d.ts +1 -2
  301. package/lib/typescript/module/chat-composer/ComposerBanner.d.ts.map +1 -1
  302. package/lib/typescript/module/chat-composer/ComposerBanner.web.d.ts +2 -0
  303. package/lib/typescript/module/chat-composer/ComposerBanner.web.d.ts.map +1 -0
  304. package/lib/typescript/module/chat-composer/EmojiPicker.d.ts +1 -2
  305. package/lib/typescript/module/chat-composer/EmojiPicker.d.ts.map +1 -1
  306. package/lib/typescript/module/chat-composer/EmojiPicker.web.d.ts +2 -0
  307. package/lib/typescript/module/chat-composer/EmojiPicker.web.d.ts.map +1 -0
  308. package/lib/typescript/module/chat-composer/MessageContextMenu.d.ts +1 -2
  309. package/lib/typescript/module/chat-composer/MessageContextMenu.d.ts.map +1 -1
  310. package/lib/typescript/module/chat-composer/MessageContextMenu.web.d.ts +2 -0
  311. package/lib/typescript/module/chat-composer/MessageContextMenu.web.d.ts.map +1 -0
  312. package/lib/typescript/module/chat-composer/ReactionPicker.d.ts +1 -2
  313. package/lib/typescript/module/chat-composer/ReactionPicker.d.ts.map +1 -1
  314. package/lib/typescript/module/chat-composer/ReactionPicker.web.d.ts +2 -0
  315. package/lib/typescript/module/chat-composer/ReactionPicker.web.d.ts.map +1 -0
  316. package/lib/typescript/module/chat-composer/SuggestionList.d.ts +1 -2
  317. package/lib/typescript/module/chat-composer/SuggestionList.d.ts.map +1 -1
  318. package/lib/typescript/module/chat-composer/SuggestionList.web.d.ts +2 -0
  319. package/lib/typescript/module/chat-composer/SuggestionList.web.d.ts.map +1 -0
  320. package/lib/typescript/module/chat-composer/VoiceRecorder.d.ts +1 -2
  321. package/lib/typescript/module/chat-composer/VoiceRecorder.d.ts.map +1 -1
  322. package/lib/typescript/module/chat-composer/VoiceRecorder.web.d.ts +2 -0
  323. package/lib/typescript/module/chat-composer/VoiceRecorder.web.d.ts.map +1 -0
  324. package/lib/typescript/module/chat-composer/create-attachment-menu.d.ts +11 -0
  325. package/lib/typescript/module/chat-composer/create-attachment-menu.d.ts.map +1 -0
  326. package/lib/typescript/module/chat-composer/create-chat-composer.d.ts +11 -0
  327. package/lib/typescript/module/chat-composer/create-chat-composer.d.ts.map +1 -0
  328. package/lib/typescript/module/chat-composer/create-composer-attachment-strip.d.ts +7 -0
  329. package/lib/typescript/module/chat-composer/create-composer-attachment-strip.d.ts.map +1 -0
  330. package/lib/typescript/module/chat-composer/create-composer-banner.d.ts +7 -0
  331. package/lib/typescript/module/chat-composer/create-composer-banner.d.ts.map +1 -0
  332. package/lib/typescript/module/chat-composer/create-emoji-picker.d.ts +9 -0
  333. package/lib/typescript/module/chat-composer/create-emoji-picker.d.ts.map +1 -0
  334. package/lib/typescript/module/chat-composer/create-message-context-menu.d.ts +14 -0
  335. package/lib/typescript/module/chat-composer/create-message-context-menu.d.ts.map +1 -0
  336. package/lib/typescript/module/chat-composer/create-reaction-picker.d.ts +9 -0
  337. package/lib/typescript/module/chat-composer/create-reaction-picker.d.ts.map +1 -0
  338. package/lib/typescript/module/chat-composer/create-suggestion-list.d.ts +7 -0
  339. package/lib/typescript/module/chat-composer/create-suggestion-list.d.ts.map +1 -0
  340. package/lib/typescript/module/chat-composer/create-voice-recorder.d.ts +11 -0
  341. package/lib/typescript/module/chat-composer/create-voice-recorder.d.ts.map +1 -0
  342. package/lib/typescript/module/chat-composer/index.web.d.ts +9 -9
  343. package/lib/typescript/module/chat-composer/index.web.d.ts.map +1 -1
  344. package/lib/typescript/module/earnings/EarningsSummary.d.ts.map +1 -1
  345. package/lib/typescript/module/field/Field.d.ts +1 -1
  346. package/lib/typescript/module/field/Field.d.ts.map +1 -1
  347. package/lib/typescript/module/field/types.d.ts +2 -0
  348. package/lib/typescript/module/field/types.d.ts.map +1 -1
  349. package/lib/typescript/module/floating/types.d.ts +1 -0
  350. package/lib/typescript/module/floating/types.d.ts.map +1 -1
  351. package/lib/typescript/module/item/Item.d.ts.map +1 -1
  352. package/lib/typescript/module/job-board/JobCard.d.ts.map +1 -1
  353. package/lib/typescript/module/label/Label.d.ts +1 -1
  354. package/lib/typescript/module/label/Label.d.ts.map +1 -1
  355. package/lib/typescript/module/label/types.d.ts +2 -0
  356. package/lib/typescript/module/label/types.d.ts.map +1 -1
  357. package/lib/typescript/module/listing-details/AmenityList.d.ts.map +1 -1
  358. package/lib/typescript/module/overlay/InteractionBoundary.d.ts +7 -0
  359. package/lib/typescript/module/overlay/InteractionBoundary.d.ts.map +1 -0
  360. package/lib/typescript/module/payment-method/PaymentMethodList.d.ts.map +1 -1
  361. package/lib/typescript/module/place-details/PlaceAmenities.d.ts.map +1 -1
  362. package/lib/typescript/module/place-details/PlacePopularTimes.d.ts.map +1 -1
  363. package/lib/typescript/module/proof-of-delivery/ProofOfDelivery.d.ts.map +1 -1
  364. package/lib/typescript/module/select/Select.d.ts.map +1 -1
  365. package/lib/typescript/module/select/Select.web.d.ts.map +1 -1
  366. package/lib/typescript/module/select/use-required-description.d.ts +7 -0
  367. package/lib/typescript/module/select/use-required-description.d.ts.map +1 -0
  368. package/package.json +1 -1
  369. package/src/__tests__/support/adoption-matrix.ts +708 -0
  370. package/src/__tests__/support/card-surface.ts +17 -0
  371. package/src/__tests__/support/collision-fixture-barrel.ts +20 -0
  372. package/src/__tests__/support/commerce-harness.tsx +97 -0
  373. package/src/__tests__/support/composite.ts +68 -0
  374. package/src/__tests__/support/constructed-style-sheets.ts +68 -0
  375. package/src/__tests__/support/press-host.ts +30 -0
  376. package/src/__tests__/support/rendered-style.ts +99 -0
  377. package/src/__tests__/support/unread-hook-fixture.ts +33 -0
  378. package/src/__tests__/support/worklet-capture-fixture.tsx +28 -0
  379. package/src/button/Button.tsx +35 -10
  380. package/src/button/GlyphButton.tsx +3 -3
  381. package/src/card-form/shared.ts +3 -2
  382. package/src/chat-composer/AttachmentMenu.tsx +2 -214
  383. package/src/chat-composer/AttachmentMenu.web.tsx +5 -0
  384. package/src/chat-composer/ChatComposer.tsx +2 -459
  385. package/src/chat-composer/ChatComposer.web.tsx +6 -0
  386. package/src/chat-composer/ComposerAttachmentStrip.tsx +2 -202
  387. package/src/chat-composer/ComposerAttachmentStrip.web.tsx +4 -0
  388. package/src/chat-composer/ComposerBanner.tsx +2 -157
  389. package/src/chat-composer/ComposerBanner.web.tsx +4 -0
  390. package/src/chat-composer/EmojiPicker.tsx +2 -402
  391. package/src/chat-composer/EmojiPicker.web.tsx +5 -0
  392. package/src/chat-composer/MessageContextMenu.tsx +2 -88
  393. package/src/chat-composer/MessageContextMenu.web.tsx +12 -0
  394. package/src/chat-composer/ReactionPicker.tsx +2 -100
  395. package/src/chat-composer/ReactionPicker.web.tsx +5 -0
  396. package/src/chat-composer/SuggestionList.tsx +2 -209
  397. package/src/chat-composer/SuggestionList.web.tsx +4 -0
  398. package/src/chat-composer/VoiceRecorder.tsx +2 -287
  399. package/src/chat-composer/VoiceRecorder.web.tsx +6 -0
  400. package/src/chat-composer/create-attachment-menu.tsx +228 -0
  401. package/src/chat-composer/create-chat-composer.tsx +473 -0
  402. package/src/chat-composer/create-composer-attachment-strip.tsx +212 -0
  403. package/src/chat-composer/create-composer-banner.tsx +167 -0
  404. package/src/chat-composer/create-emoji-picker.tsx +414 -0
  405. package/src/chat-composer/create-message-context-menu.tsx +112 -0
  406. package/src/chat-composer/create-reaction-picker.tsx +112 -0
  407. package/src/chat-composer/create-suggestion-list.tsx +219 -0
  408. package/src/chat-composer/create-voice-recorder.tsx +301 -0
  409. package/src/chat-composer/index.web.ts +9 -9
  410. package/src/earnings/EarningsSummary.tsx +9 -2
  411. package/src/field/Field.tsx +2 -1
  412. package/src/field/types.ts +2 -0
  413. package/src/floating/types.ts +1 -0
  414. package/src/item/Item.tsx +16 -11
  415. package/src/job-board/JobCard.tsx +4 -1
  416. package/src/label/Label.tsx +2 -1
  417. package/src/label/types.ts +2 -0
  418. package/src/listing-details/AmenityList.tsx +4 -3
  419. package/src/overlay/InteractionBoundary.tsx +24 -0
  420. package/src/payment-method/PaymentMethodList.tsx +2 -1
  421. package/src/place-details/PlaceAmenities.tsx +9 -0
  422. package/src/place-details/PlacePopularTimes.tsx +7 -1
  423. package/src/proof-of-delivery/ProofOfDelivery.tsx +9 -1
  424. package/src/proof-of-delivery/shared.ts +1 -1
  425. package/src/select/Select.tsx +5 -1
  426. package/src/select/Select.web.tsx +5 -1
  427. package/src/select/use-required-description.tsx +20 -0
  428. package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +9346 -0
  429. package/src/theme/__tests__/__fixtures__/tonal-glass-primary-failures.json +69 -0
  430. package/src/theme/__tests__/fixtures/color-engine-golden.json +1 -0
@@ -1,217 +1,5 @@
1
- /**
2
- * The plus/paperclip menu.
3
- *
4
- * It is `Popover`, not a hand-rolled surface, and that one choice is the whole
5
- * platform story: Bloom's popover is already an anchored panel on a pointer and
6
- * a bottom sheet on a phone, so this family adds no platform fork of its own
7
- * and inherits the dismissal, stacking and focus behaviour those surfaces were
8
- * gated for.
9
- */
10
- import React from 'react';
11
- import { View, type DimensionValue } from 'react-native';
12
-
13
1
  import { Button } from '../button';
14
2
  import { Popover, PopoverContent, PopoverTrigger } from '../popover';
15
- import type { WebCssStyle } from '../styles/web-view-style';
16
- import { useTheme } from '../theme/use-theme';
17
- import { Text } from '../typography';
18
- import { attachmentMenuItems, resolveChatComposerPalette } from './shared';
19
- import type { AttachmentMenuItem, AttachmentMenuProps } from './types';
20
- import { useChatComposerWebCss } from './web-hooks';
21
- import { useMessages } from '../locale/messages';
22
- import { CHAT_COMPOSER_MESSAGES } from './messages';
23
-
24
- /** A 48px tinted disc with its label under it. */
25
- function GridCell({
26
- item,
27
- onPress,
28
- width,
29
- testID,
30
- }: {
31
- item: AttachmentMenuItem;
32
- onPress: () => void;
33
- width: DimensionValue;
34
- testID?: string;
35
- }) {
36
- const theme = useTheme();
37
- const palette = resolveChatComposerPalette(theme);
38
- const tint = item.color ?? palette.accent;
39
- const cell: WebCssStyle = {
40
- width,
41
- height: 'auto',
42
- minHeight: 0,
43
- minWidth: 0,
44
- paddingLeft: 0,
45
- paddingRight: 0,
46
- alignItems: 'center',
47
- gap: 6,
48
- paddingTop: 8,
49
- paddingBottom: 8,
50
- borderRadius: 12,
51
- opacity: item.disabled ? 0.45 : 1,
52
- cursor: item.disabled ? 'auto' : 'pointer',
53
- };
54
- return (
55
- <Button
56
- appearance="plain"
57
- tone="neutral"
58
- accessibilityLabel={item.label}
59
- disabled={item.disabled}
60
- onPress={onPress}
61
- style={cell}
62
- testID={testID}>
63
- <View style={{ alignItems: 'center', gap: 6 }}>
64
- <View
65
- style={{
66
- width: 48,
67
- height: 48,
68
- borderRadius: 24,
69
- alignItems: 'center',
70
- justifyContent: 'center',
71
- backgroundColor: palette.accentSoft,
72
- }}>
73
- <item.icon width={22} height={22} fill={tint} />
74
- </View>
75
- <Text variant="caption-1-regular" numberOfLines={1} style={{ color: palette.textSecondary }}>
76
- {item.label}
77
- </Text>
78
- </View>
79
- </Button>
80
- );
81
- }
82
-
83
- /** A full-width row: glyph, label. */
84
- function ListRow({
85
- item,
86
- onPress,
87
- testID,
88
- }: {
89
- item: AttachmentMenuItem;
90
- onPress: () => void;
91
- testID?: string;
92
- }) {
93
- const theme = useTheme();
94
- const palette = resolveChatComposerPalette(theme);
95
- const tint = item.color ?? palette.accent;
96
- const row: WebCssStyle = {
97
- flexDirection: 'row',
98
- alignItems: 'center',
99
- gap: 12,
100
- minHeight: 40,
101
- height: 'auto',
102
- minWidth: 0,
103
- width: '100%',
104
- borderRadius: 10,
105
- paddingLeft: 8,
106
- paddingRight: 8,
107
- paddingTop: 6,
108
- paddingBottom: 6,
109
- opacity: item.disabled ? 0.45 : 1,
110
- cursor: item.disabled ? 'auto' : 'pointer',
111
- };
112
- return (
113
- <Button
114
- appearance="plain"
115
- tone="neutral"
116
- accessibilityLabel={item.label}
117
- disabled={item.disabled}
118
- onPress={onPress}
119
- style={row}
120
- testID={testID}>
121
- <View style={{ flexDirection: 'row', alignItems: 'center', gap: 12, width: '100%' }}>
122
- <View
123
- style={{
124
- width: 32,
125
- height: 32,
126
- borderRadius: 16,
127
- alignItems: 'center',
128
- justifyContent: 'center',
129
- backgroundColor: palette.accentSoft,
130
- }}>
131
- <item.icon width={18} height={18} fill={tint} />
132
- </View>
133
- <Text variant="body-medium" numberOfLines={1} style={{ color: palette.text }}>
134
- {item.label}
135
- </Text>
136
- </View>
137
- </Button>
138
- );
139
- }
140
-
141
- export function AttachmentMenu({
142
- children,
143
- open,
144
- defaultOpen,
145
- onOpenChange,
146
- items: itemsProp,
147
- layout = 'grid',
148
- columns = 4,
149
- onSelect,
150
- recent,
151
- label: labelProp,
152
- style,
153
- testID,
154
- }: AttachmentMenuProps) {
155
- useChatComposerWebCss();
156
- const { messages } = useMessages(CHAT_COMPOSER_MESSAGES);
157
- const localizedItems = React.useMemo(() => attachmentMenuItems(messages), [messages]);
158
- const items = itemsProp ?? localizedItems;
159
- const label = labelProp ?? messages.attach;
160
- const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen ?? false);
161
- const isOpen = open ?? uncontrolledOpen;
162
-
163
- const setOpen = (next: boolean) => {
164
- if (open === undefined) setUncontrolledOpen(next);
165
- onOpenChange?.(next);
166
- };
167
-
168
- // A percentage string is the only way to say "n per row" in a wrapping flex
169
- // row that has to work on both platforms; Yoga and CSS agree on it.
170
- const cellWidth: DimensionValue = `${100 / Math.max(1, columns)}%`;
3
+ import { createAttachmentMenu } from './create-attachment-menu';
171
4
 
172
- return (
173
- <Popover open={isOpen} onOpenChange={setOpen}>
174
- <PopoverTrigger asChild>{children}</PopoverTrigger>
175
- <PopoverContent
176
- label={label}
177
- side="top"
178
- align="start"
179
- minWidth={layout === 'grid' ? Math.max(264, columns * 72) : 220}
180
- style={style}
181
- testID={testID}>
182
- {recent ? <View style={{ paddingBottom: 8 }}>{recent}</View> : null}
183
- <View
184
- style={
185
- layout === 'grid'
186
- ? { flexDirection: 'row', flexWrap: 'wrap', alignItems: 'flex-start' }
187
- : { flexDirection: 'column', gap: 2 }
188
- }>
189
- {items.map((item) =>
190
- layout === 'grid' ? (
191
- <GridCell
192
- key={item.id}
193
- item={item}
194
- width={cellWidth}
195
- onPress={() => {
196
- onSelect?.(item.id, item);
197
- setOpen(false);
198
- }}
199
- testID={testID ? `${testID}-${item.id}` : undefined}
200
- />
201
- ) : (
202
- <ListRow
203
- key={item.id}
204
- item={item}
205
- onPress={() => {
206
- onSelect?.(item.id, item);
207
- setOpen(false);
208
- }}
209
- testID={testID ? `${testID}-${item.id}` : undefined}
210
- />
211
- ),
212
- )}
213
- </View>
214
- </PopoverContent>
215
- </Popover>
216
- );
217
- }
5
+ export const AttachmentMenu = createAttachmentMenu({ Button, Popover, PopoverContent, PopoverTrigger });
@@ -0,0 +1,5 @@
1
+ import { Button } from '../button/index.web';
2
+ import { Popover, PopoverContent, PopoverTrigger } from '../popover/index.web';
3
+ import { createAttachmentMenu } from './create-attachment-menu';
4
+
5
+ export const AttachmentMenu = createAttachmentMenu({ Button, Popover, PopoverContent, PopoverTrigger });
@@ -1,463 +1,6 @@
1
- /**
2
- * The message input bar of a person-to-person chat: a radius-24 pill with a
3
- * left attach button, an autosizing field, an emoji button and a right control
4
- * that swaps between a mic (nothing to send) and an accent send disc (there is).
5
- *
6
- * Presentational. Every piece of state — the draft, the banners, the pending
7
- * attachments, which suggestion is highlighted — arrives as a prop, because the
8
- * app owns drafts per conversation and a composer that kept its own would lose
9
- * them on every navigation.
10
- */
11
- import React, { useCallback, useMemo, useRef, useState } from 'react';
12
- import {
13
- TextInput,
14
- View,
15
- type NativeSyntheticEvent,
16
- type TextInputContentSizeChangeEventData,
17
- type TextInputKeyPressEventData,
18
- } from 'react-native';
19
- import Animated, {
20
- Easing,
21
- useAnimatedStyle,
22
- useReducedMotion,
23
- useSharedValue,
24
- withTiming,
25
- } from 'react-native-reanimated';
26
-
27
- import { RiAddLine } from '../icons/remix/RiAddLine';
28
- import { RiCameraLine } from '../icons/remix/RiCameraLine';
29
- import { RiEmotionLine } from '../icons/remix/RiEmotionLine';
30
- import { RiForbidLine } from '../icons/remix/RiForbidLine';
31
- import { RiMic2Line } from '../icons/remix/RiMic2Line';
32
- import { RiSendPlaneLine } from '../icons/remix/RiSendPlaneLine';
33
- import { useControllableState } from '../hooks/use-controllable-state';
34
- import { useTextareaAutosize } from '../hooks/use-textarea-autosize';
35
- import type { WebCssStyle } from '../styles/web-view-style';
36
- import { useTheme } from '../theme/use-theme';
37
- import { Text } from '../typography';
38
- import { TYPE_SCALE } from '../typography/scale';
39
1
  import { ComposerAttachmentStrip } from './ComposerAttachmentStrip';
40
2
  import { ComposerIconButton } from './ComposerIconButton';
41
- import {
42
- BAR_PADDING,
43
- BAR_RADIUS,
44
- chatComposerLabels,
45
- CONTROL_SIZE,
46
- DEFAULT_MAX_LINES,
47
- LINE_HEIGHT,
48
- SWAP_MS,
49
- resolveChatComposerPalette,
50
- } from './shared';
51
3
  import { SuggestionList } from './SuggestionList';
52
- import type { ChatComposerProps } from './types';
53
- import { dataHook, IS_WEB, useChatComposerWebCss } from './web-hooks';
54
- import { useMessages } from '../locale/messages';
55
- import { CHAT_COMPOSER_MESSAGES } from './messages';
56
- import { useCommonMessages } from '../locale/common-messages';
57
-
58
- const EASE_OUT = Easing.bezier(0, 0, 0.2, 1);
59
-
60
- /**
61
- * One half of the mic ↔ send crossfade.
62
- *
63
- * Two things the fade must not break, neither of which the animation expresses:
64
- *
65
- * `pointerEvents` is a PROP, not a style entry — react-native-web drops it from
66
- * a style object silently, and a hidden layer that still takes the press is a
67
- * send button that fires when the field is empty.
68
- *
69
- * The hidden half leaves the ACCESSIBILITY TREE too. Both halves stay mounted so
70
- * they can cross-fade, so without this every composer announces "Send" and
71
- * "Record a voice message" side by side and only one of them does anything.
72
- * `aria-hidden` is what react-native-web reads and
73
- * `importantForAccessibility` is what React Native reads; a surface that sets
74
- * one of the two is hidden on one platform only.
75
- */
76
- function SwapLayer({ shown, children }: { shown: boolean; children: React.ReactNode }) {
77
- const reducedMotion = useReducedMotion();
78
- const progress = useSharedValue(shown ? 1 : 0);
79
- React.useEffect(() => {
80
- progress.value = reducedMotion
81
- ? shown
82
- ? 1
83
- : 0
84
- : withTiming(shown ? 1 : 0, { duration: SWAP_MS, easing: EASE_OUT });
85
- }, [shown, reducedMotion, progress]);
86
- const animated = useAnimatedStyle(() => ({ opacity: progress.value }), [progress]);
87
- return (
88
- <Animated.View
89
- pointerEvents={shown ? 'auto' : 'none'}
90
- aria-hidden={!shown}
91
- accessibilityElementsHidden={!shown}
92
- importantForAccessibility={shown ? 'auto' : 'no-hide-descendants'}
93
- style={[{ position: 'absolute', top: 0, left: 0 }, animated]}>
94
- {children}
95
- </Animated.View>
96
- );
97
- }
98
-
99
- /** A DOM keyboard event as react-native-web hands it to `onKeyPress`. */
100
- type WebKeyEvent = TextInputKeyPressEventData & {
101
- shiftKey?: boolean;
102
- metaKey?: boolean;
103
- ctrlKey?: boolean;
104
- altKey?: boolean;
105
- isComposing?: boolean;
106
- };
107
-
108
- export function ChatComposer({
109
- value,
110
- defaultValue = '',
111
- onValueChange,
112
- placeholder: placeholderProp,
113
- onSend,
114
- sendOn = 'enter',
115
- maxLines = DEFAULT_MAX_LINES,
116
- minLines = 1,
117
- disabled = false,
118
- notice,
119
- noticeIcon,
120
- banner,
121
- attachments,
122
- onRemoveAttachment,
123
- leading,
124
- onAttachPress,
125
- emojiSlot,
126
- onEmojiPress,
127
- onCameraPress,
128
- onMicPress,
129
- onMicPressIn,
130
- onMicPressOut,
131
- canSend,
132
- recorder,
133
- suggestions,
134
- suggestionKind = 'mention',
135
- activeIndex = -1,
136
- onActiveIndexChange,
137
- onSelectSuggestion,
138
- onEscape,
139
- onEditLast,
140
- showKeyboardHint = false,
141
- inputRef,
142
- onFocus,
143
- onBlur,
144
- labels: labelOverrides,
145
- style,
146
- testID,
147
- accessibilityLabel,
148
- }: ChatComposerProps) {
149
- const theme = useTheme();
150
- const { messages } = useMessages(CHAT_COMPOSER_MESSAGES);
151
- const common = useCommonMessages();
152
- const palette = resolveChatComposerPalette(theme);
153
- useChatComposerWebCss();
154
- const labels = useMemo(
155
- () => ({ ...chatComposerLabels(messages, common.send), ...labelOverrides }),
156
- [common.send, labelOverrides, messages],
157
- );
158
- const placeholder = placeholderProp ?? messages.message;
159
-
160
- const [text, setText] = useControllableState<string>({
161
- value,
162
- defaultValue,
163
- onChange: onValueChange,
164
- });
165
-
166
- const localRef = useRef<TextInput | null>(null);
167
- const setFieldRef = useCallback(
168
- (node: TextInput | null) => {
169
- localRef.current = node;
170
- if (inputRef) inputRef.current = node;
171
- },
172
- [inputRef],
173
- );
174
-
175
- const minHeight = Math.max(1, minLines) * LINE_HEIGHT;
176
- const maxHeight = Math.max(minLines, maxLines) * LINE_HEIGHT;
177
- const [contentHeight, setContentHeight] = useState(minHeight);
178
- const height = Math.min(maxHeight, Math.max(minHeight, contentHeight));
179
-
180
- /**
181
- * Web autosize measures the node, native reads `onContentSizeChange`.
182
- *
183
- * They are not interchangeable: react-native-web reports `scrollHeight`,
184
- * which never falls below the height already applied, so a field grown to six
185
- * lines and then emptied would stay six lines tall. `useTextareaAutosize`
186
- * collapses the node to measure it only when the draft may have got SHORTER —
187
- * collapsing on every keystroke re-laid-out the whole page three times a key.
188
- */
189
- useTextareaAutosize(localRef, text, {
190
- enabled: IS_WEB,
191
- height,
192
- minHeight,
193
- onMeasure: setContentHeight,
194
- });
195
-
196
- const onContentSizeChange = useCallback(
197
- (event: NativeSyntheticEvent<TextInputContentSizeChangeEventData>) => {
198
- if (IS_WEB) return;
199
- setContentHeight(event.nativeEvent.contentSize.height);
200
- },
201
- [],
202
- );
203
-
204
- const trimmed = text.trim();
205
- const hasAttachments = !!attachments && attachments.length > 0;
206
- const showSend = canSend ?? (trimmed.length > 0 || hasAttachments);
207
-
208
- const submit = useCallback(() => {
209
- if (disabled || !showSend) return;
210
- onSend?.(text);
211
- if (value === undefined) setText('');
212
- }, [disabled, showSend, onSend, text, value, setText]);
213
-
214
- const openSuggestions = !!suggestions && suggestions.length > 0;
215
-
216
- const onKeyPress = useCallback(
217
- (event: NativeSyntheticEvent<TextInputKeyPressEventData>) => {
218
- if (!IS_WEB) return;
219
- const native = event.nativeEvent as WebKeyEvent;
220
- // An IME candidate window is using the same keys; committing a
221
- // composition must never send the half-written word behind it.
222
- if (native.isComposing) return;
223
- const mod = native.metaKey === true || native.ctrlKey === true;
224
-
225
- if (openSuggestions && (native.key === 'ArrowDown' || native.key === 'ArrowUp')) {
226
- event.preventDefault();
227
- const count = suggestions?.length ?? 0;
228
- const step = native.key === 'ArrowDown' ? 1 : -1;
229
- const from = activeIndex < 0 ? (step > 0 ? -1 : 0) : activeIndex;
230
- onActiveIndexChange?.((from + step + count) % count);
231
- return;
232
- }
233
- if (native.key === 'Escape') {
234
- event.preventDefault();
235
- onEscape?.();
236
- return;
237
- }
238
- if (native.key === 'ArrowUp' && text.length === 0) {
239
- event.preventDefault();
240
- onEditLast?.();
241
- return;
242
- }
243
- if (native.key !== 'Enter') return;
244
-
245
- if (openSuggestions && activeIndex >= 0) {
246
- const picked = suggestions?.[activeIndex];
247
- if (picked && !picked.disabled) {
248
- event.preventDefault();
249
- onSelectSuggestion?.(picked, activeIndex);
250
- return;
251
- }
252
- }
253
- if (sendOn === 'enter' ? native.shiftKey !== true && !mod : mod) {
254
- event.preventDefault();
255
- submit();
256
- }
257
- },
258
- [
259
- activeIndex,
260
- onActiveIndexChange,
261
- onEditLast,
262
- onEscape,
263
- onSelectSuggestion,
264
- openSuggestions,
265
- sendOn,
266
- submit,
267
- suggestions,
268
- text.length,
269
- ],
270
- );
271
-
272
- const bar: WebCssStyle = {
273
- flexDirection: 'row',
274
- alignItems: 'flex-end',
275
- gap: 2,
276
- minHeight: CONTROL_SIZE + BAR_PADDING * 2,
277
- borderRadius: BAR_RADIUS,
278
- borderWidth: 1,
279
- borderColor: palette.border,
280
- // A disabled bar changes its FILL rather than its opacity. Dimming the
281
- // container compounds with each control's own disabled opacity — 0.55 × 0.4
282
- // put the send disc at 0.22, which reads as a rendering fault rather than a
283
- // state.
284
- backgroundColor: disabled ? palette.inset : palette.surface,
285
- paddingLeft: BAR_PADDING,
286
- paddingRight: BAR_PADDING,
287
- paddingTop: BAR_PADDING,
288
- paddingBottom: BAR_PADDING,
289
- '--bloom-chat-composer-ring': palette.focusRing,
290
- };
291
-
292
- const NoticeIcon = noticeIcon ?? RiForbidLine;
293
-
294
- return (
295
- <View
296
- accessibilityLabel={accessibilityLabel}
297
- style={[{ width: '100%', flexDirection: 'column', gap: 6 }, style]}
298
- testID={testID}>
299
- {openSuggestions ? (
300
- <SuggestionList
301
- kind={suggestionKind}
302
- suggestions={suggestions ?? []}
303
- activeIndex={activeIndex}
304
- onActiveIndexChange={onActiveIndexChange}
305
- onSelectSuggestion={onSelectSuggestion}
306
- testID={testID ? `${testID}-suggestions` : undefined}
307
- />
308
- ) : null}
309
-
310
- {banner}
311
-
312
- {hasAttachments ? (
313
- <ComposerAttachmentStrip
314
- attachments={attachments ?? []}
315
- onRemove={onRemoveAttachment}
316
- testID={testID ? `${testID}-attachments` : undefined}
317
- />
318
- ) : null}
319
-
320
- {recorder ?? (
321
- <View style={bar} testID={testID ? `${testID}-bar` : undefined}>
322
- {notice !== undefined ? (
323
- <View
324
- style={{
325
- flexDirection: 'row',
326
- alignItems: 'center',
327
- justifyContent: 'center',
328
- gap: 8,
329
- flexGrow: 1,
330
- minHeight: CONTROL_SIZE,
331
- paddingLeft: 12,
332
- paddingRight: 12,
333
- }}
334
- testID={testID ? `${testID}-notice` : undefined}>
335
- {typeof notice === 'string' ? (
336
- <>
337
- <NoticeIcon width={16} height={16} fill={palette.iconSecondary} />
338
- <Text
339
- variant="body-2-regular"
340
- numberOfLines={2}
341
- style={{ color: palette.textSecondary, textAlign: 'center' }}>
342
- {notice}
343
- </Text>
344
- </>
345
- ) : (
346
- notice
347
- )}
348
- </View>
349
- ) : (
350
- <>
351
- {leading ??
352
- (onAttachPress ? (
353
- <ComposerIconButton
354
- icon={RiAddLine}
355
- accessibilityLabel={labels.attach}
356
- onPress={onAttachPress}
357
- disabled={disabled}
358
- iconSize={22}
359
- testID={testID ? `${testID}-attach` : undefined}
360
- />
361
- ) : null)}
362
-
363
- <View
364
- style={{
365
- flexGrow: 1,
366
- flexShrink: 1,
367
- justifyContent: 'center',
368
- minHeight: CONTROL_SIZE,
369
- paddingLeft: 6,
370
- paddingRight: 6,
371
- }}>
372
- <TextInput
373
- ref={setFieldRef}
374
- {...dataHook('bloomChatComposerInput')}
375
- accessibilityLabel={labels.input}
376
- multiline
377
- editable={!disabled}
378
- value={text}
379
- onChangeText={setText}
380
- onKeyPress={onKeyPress}
381
- onContentSizeChange={onContentSizeChange}
382
- onFocus={onFocus}
383
- onBlur={onBlur}
384
- placeholder={placeholder}
385
- placeholderTextColor={palette.textPlaceholder}
386
- selectionColor={palette.accent}
387
- cursorColor={palette.accent}
388
- scrollEnabled={height >= maxHeight}
389
- style={{
390
- width: '100%',
391
- height,
392
- maxHeight,
393
- padding: 0,
394
- margin: 0,
395
- ...TYPE_SCALE['body-regular'],
396
- fontFamily: IS_WEB ? 'var(--bloom-font-sans)' : 'Inter',
397
- color: disabled ? palette.textSecondary : palette.text,
398
- backgroundColor: 'transparent',
399
- }}
400
- testID={testID ? `${testID}-input` : undefined}
401
- />
402
- </View>
403
-
404
- {onCameraPress ? (
405
- <ComposerIconButton
406
- icon={RiCameraLine}
407
- accessibilityLabel={labels.camera}
408
- onPress={onCameraPress}
409
- disabled={disabled}
410
- testID={testID ? `${testID}-camera` : undefined}
411
- />
412
- ) : null}
413
-
414
- {emojiSlot ??
415
- (onEmojiPress ? (
416
- <ComposerIconButton
417
- icon={RiEmotionLine}
418
- accessibilityLabel={labels.emoji}
419
- onPress={onEmojiPress}
420
- disabled={disabled}
421
- testID={testID ? `${testID}-emoji` : undefined}
422
- />
423
- ) : null)}
424
-
425
- <View style={{ width: CONTROL_SIZE, height: CONTROL_SIZE, marginLeft: 2 }}>
426
- <SwapLayer shown={showSend}>
427
- <ComposerIconButton
428
- icon={RiSendPlaneLine}
429
- tone="accent"
430
- accessibilityLabel={labels.send}
431
- onPress={submit}
432
- disabled={disabled}
433
- iconSize={18}
434
- testID={testID ? `${testID}-send` : undefined}
435
- />
436
- </SwapLayer>
437
- <SwapLayer shown={!showSend}>
438
- <ComposerIconButton
439
- icon={RiMic2Line}
440
- accessibilityLabel={labels.mic}
441
- onPress={onMicPress}
442
- onPressIn={onMicPressIn}
443
- onPressOut={onMicPressOut}
444
- disabled={disabled}
445
- testID={testID ? `${testID}-mic` : undefined}
446
- />
447
- </SwapLayer>
448
- </View>
449
- </>
450
- )}
451
- </View>
452
- )}
4
+ import { createChatComposer } from './create-chat-composer';
453
5
 
454
- {showKeyboardHint && IS_WEB && notice === undefined ? (
455
- <Text
456
- variant="caption-2-regular"
457
- style={{ color: palette.textPlaceholder, paddingLeft: 14 }}>
458
- {sendOn === 'enter' ? labels.enterHint : labels.modEnterHint}
459
- </Text>
460
- ) : null}
461
- </View>
462
- );
463
- }
6
+ export const ChatComposer = createChatComposer({ ComposerAttachmentStrip, ComposerIconButton, SuggestionList });
@@ -0,0 +1,6 @@
1
+ import { ComposerAttachmentStrip } from './ComposerAttachmentStrip.web';
2
+ import { ComposerIconButton } from './ComposerIconButton.web';
3
+ import { SuggestionList } from './SuggestionList.web';
4
+ import { createChatComposer } from './create-chat-composer';
5
+
6
+ export const ChatComposer = createChatComposer({ ComposerAttachmentStrip, ComposerIconButton, SuggestionList });