tempest-react-sdk 0.62.0 → 0.64.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 (808) hide show
  1. package/README.md +10 -7
  2. package/dist/br/BrazilMap.module.cjs +1 -0
  3. package/dist/br/BrazilMap.module.cjs.map +1 -1
  4. package/dist/br/BrazilMap.module.js +1 -0
  5. package/dist/br/BrazilMap.module.js.map +1 -1
  6. package/dist/br/MapLegend.module.cjs +1 -0
  7. package/dist/br/MapLegend.module.cjs.map +1 -1
  8. package/dist/br/MapLegend.module.js +1 -0
  9. package/dist/br/MapLegend.module.js.map +1 -1
  10. package/dist/br/MunicipalitySearch.module.cjs +1 -0
  11. package/dist/br/MunicipalitySearch.module.cjs.map +1 -1
  12. package/dist/br/MunicipalitySearch.module.js +1 -0
  13. package/dist/br/MunicipalitySearch.module.js.map +1 -1
  14. package/dist/br/PixQRCode.module.cjs +1 -0
  15. package/dist/br/PixQRCode.module.cjs.map +1 -1
  16. package/dist/br/PixQRCode.module.js +1 -0
  17. package/dist/br/PixQRCode.module.js.map +1 -1
  18. package/dist/components/AIChat/AIChat.module.cjs +1 -0
  19. package/dist/components/AIChat/AIChat.module.cjs.map +1 -1
  20. package/dist/components/AIChat/AIChat.module.js +1 -0
  21. package/dist/components/AIChat/AIChat.module.js.map +1 -1
  22. package/dist/components/Accordion/Accordion.module.cjs +1 -0
  23. package/dist/components/Accordion/Accordion.module.cjs.map +1 -1
  24. package/dist/components/Accordion/Accordion.module.js +1 -0
  25. package/dist/components/Accordion/Accordion.module.js.map +1 -1
  26. package/dist/components/Alert/Alert.module.cjs +1 -0
  27. package/dist/components/Alert/Alert.module.cjs.map +1 -1
  28. package/dist/components/Alert/Alert.module.js +1 -0
  29. package/dist/components/Alert/Alert.module.js.map +1 -1
  30. package/dist/components/AppBar/AppBar.module.cjs +1 -0
  31. package/dist/components/AppBar/AppBar.module.cjs.map +1 -1
  32. package/dist/components/AppBar/AppBar.module.js +1 -0
  33. package/dist/components/AppBar/AppBar.module.js.map +1 -1
  34. package/dist/components/AppShell/AppShell.module.cjs +1 -0
  35. package/dist/components/AppShell/AppShell.module.cjs.map +1 -1
  36. package/dist/components/AppShell/AppShell.module.js +1 -0
  37. package/dist/components/AppShell/AppShell.module.js.map +1 -1
  38. package/dist/components/AspectRatio/AspectRatio.module.cjs +1 -0
  39. package/dist/components/AspectRatio/AspectRatio.module.cjs.map +1 -1
  40. package/dist/components/AspectRatio/AspectRatio.module.js +1 -0
  41. package/dist/components/AspectRatio/AspectRatio.module.js.map +1 -1
  42. package/dist/components/AudioPlayer/AudioPlayer.module.cjs +1 -0
  43. package/dist/components/AudioPlayer/AudioPlayer.module.cjs.map +1 -1
  44. package/dist/components/AudioPlayer/AudioPlayer.module.js +1 -0
  45. package/dist/components/AudioPlayer/AudioPlayer.module.js.map +1 -1
  46. package/dist/components/AudioRecorder/AudioRecorder.module.cjs +1 -0
  47. package/dist/components/AudioRecorder/AudioRecorder.module.cjs.map +1 -1
  48. package/dist/components/AudioRecorder/AudioRecorder.module.js +1 -0
  49. package/dist/components/AudioRecorder/AudioRecorder.module.js.map +1 -1
  50. package/dist/components/Avatar/Avatar.module.cjs +1 -0
  51. package/dist/components/Avatar/Avatar.module.cjs.map +1 -1
  52. package/dist/components/Avatar/Avatar.module.js +1 -0
  53. package/dist/components/Avatar/Avatar.module.js.map +1 -1
  54. package/dist/components/AvatarGroup/AvatarGroup.module.cjs +1 -0
  55. package/dist/components/AvatarGroup/AvatarGroup.module.cjs.map +1 -1
  56. package/dist/components/AvatarGroup/AvatarGroup.module.js +1 -0
  57. package/dist/components/AvatarGroup/AvatarGroup.module.js.map +1 -1
  58. package/dist/components/Badge/Badge.module.cjs +1 -0
  59. package/dist/components/Badge/Badge.module.cjs.map +1 -1
  60. package/dist/components/Badge/Badge.module.js +1 -0
  61. package/dist/components/Badge/Badge.module.js.map +1 -1
  62. package/dist/components/Banner/Banner.module.cjs +1 -0
  63. package/dist/components/Banner/Banner.module.cjs.map +1 -1
  64. package/dist/components/Banner/Banner.module.js +1 -0
  65. package/dist/components/Banner/Banner.module.js.map +1 -1
  66. package/dist/components/BarList/BarList.module.cjs +1 -0
  67. package/dist/components/BarList/BarList.module.cjs.map +1 -1
  68. package/dist/components/BarList/BarList.module.js +1 -0
  69. package/dist/components/BarList/BarList.module.js.map +1 -1
  70. package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs +1 -0
  71. package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs.map +1 -1
  72. package/dist/components/BarcodeScanner/BarcodeScanner.module.js +1 -0
  73. package/dist/components/BarcodeScanner/BarcodeScanner.module.js.map +1 -1
  74. package/dist/components/BottomNavigation/BottomNavigation.module.cjs +1 -0
  75. package/dist/components/BottomNavigation/BottomNavigation.module.cjs.map +1 -1
  76. package/dist/components/BottomNavigation/BottomNavigation.module.js +1 -0
  77. package/dist/components/BottomNavigation/BottomNavigation.module.js.map +1 -1
  78. package/dist/components/BottomSheet/BottomSheet.module.cjs +1 -0
  79. package/dist/components/BottomSheet/BottomSheet.module.cjs.map +1 -1
  80. package/dist/components/BottomSheet/BottomSheet.module.js +1 -0
  81. package/dist/components/BottomSheet/BottomSheet.module.js.map +1 -1
  82. package/dist/components/Breadcrumbs/Breadcrumbs.module.cjs +1 -0
  83. package/dist/components/Breadcrumbs/Breadcrumbs.module.cjs.map +1 -1
  84. package/dist/components/Breadcrumbs/Breadcrumbs.module.js +1 -0
  85. package/dist/components/Breadcrumbs/Breadcrumbs.module.js.map +1 -1
  86. package/dist/components/Button/Button.module.cjs +1 -0
  87. package/dist/components/Button/Button.module.cjs.map +1 -1
  88. package/dist/components/Button/Button.module.js +1 -0
  89. package/dist/components/Button/Button.module.js.map +1 -1
  90. package/dist/components/Calendar/Calendar.module.cjs +1 -0
  91. package/dist/components/Calendar/Calendar.module.cjs.map +1 -1
  92. package/dist/components/Calendar/Calendar.module.js +1 -0
  93. package/dist/components/Calendar/Calendar.module.js.map +1 -1
  94. package/dist/components/Card/Card.module.cjs +1 -0
  95. package/dist/components/Card/Card.module.cjs.map +1 -1
  96. package/dist/components/Card/Card.module.js +1 -0
  97. package/dist/components/Card/Card.module.js.map +1 -1
  98. package/dist/components/Carousel/Carousel.module.cjs +1 -0
  99. package/dist/components/Carousel/Carousel.module.cjs.map +1 -1
  100. package/dist/components/Carousel/Carousel.module.js +1 -0
  101. package/dist/components/Carousel/Carousel.module.js.map +1 -1
  102. package/dist/components/Center/Center.module.cjs +1 -0
  103. package/dist/components/Center/Center.module.cjs.map +1 -1
  104. package/dist/components/Center/Center.module.js +1 -0
  105. package/dist/components/Center/Center.module.js.map +1 -1
  106. package/dist/components/Chat/Chat.cjs +1 -1
  107. package/dist/components/Chat/Chat.cjs.map +1 -1
  108. package/dist/components/Chat/Chat.js +71 -96
  109. package/dist/components/Chat/Chat.js.map +1 -1
  110. package/dist/components/Chat/Chat.module.cjs +2 -1
  111. package/dist/components/Chat/Chat.module.cjs.map +1 -1
  112. package/dist/components/Chat/Chat.module.js +31 -8
  113. package/dist/components/Chat/Chat.module.js.map +1 -1
  114. package/dist/components/Chat/ChatActionsMenu.cjs +2 -0
  115. package/dist/components/Chat/ChatActionsMenu.cjs.map +1 -0
  116. package/dist/components/Chat/ChatActionsMenu.js +14 -0
  117. package/dist/components/Chat/ChatActionsMenu.js.map +1 -0
  118. package/dist/components/Chat/ChatAttachments.cjs +2 -0
  119. package/dist/components/Chat/ChatAttachments.cjs.map +1 -0
  120. package/dist/components/Chat/ChatAttachments.js +80 -0
  121. package/dist/components/Chat/ChatAttachments.js.map +1 -0
  122. package/dist/components/Chat/ChatBubble.cjs +2 -0
  123. package/dist/components/Chat/ChatBubble.cjs.map +1 -0
  124. package/dist/components/Chat/ChatBubble.js +155 -0
  125. package/dist/components/Chat/ChatBubble.js.map +1 -0
  126. package/dist/components/Chat/chat-groups.cjs +1 -1
  127. package/dist/components/Chat/chat-groups.cjs.map +1 -1
  128. package/dist/components/Chat/chat-groups.js +42 -2
  129. package/dist/components/Chat/chat-groups.js.map +1 -1
  130. package/dist/components/Chat/chat-receipt.cjs +2 -0
  131. package/dist/components/Chat/chat-receipt.cjs.map +1 -0
  132. package/dist/components/Chat/chat-receipt.js +14 -0
  133. package/dist/components/Chat/chat-receipt.js.map +1 -0
  134. package/dist/components/Checkbox/Checkbox.module.cjs +1 -0
  135. package/dist/components/Checkbox/Checkbox.module.cjs.map +1 -1
  136. package/dist/components/Checkbox/Checkbox.module.js +1 -0
  137. package/dist/components/Checkbox/Checkbox.module.js.map +1 -1
  138. package/dist/components/ChipInput/ChipInput.module.cjs +1 -0
  139. package/dist/components/ChipInput/ChipInput.module.cjs.map +1 -1
  140. package/dist/components/ChipInput/ChipInput.module.js +1 -0
  141. package/dist/components/ChipInput/ChipInput.module.js.map +1 -1
  142. package/dist/components/CodeBlock/CodeBlock.module.cjs +1 -0
  143. package/dist/components/CodeBlock/CodeBlock.module.cjs.map +1 -1
  144. package/dist/components/CodeBlock/CodeBlock.module.js +1 -0
  145. package/dist/components/CodeBlock/CodeBlock.module.js.map +1 -1
  146. package/dist/components/Collapsible/Collapsible.module.cjs +1 -0
  147. package/dist/components/Collapsible/Collapsible.module.cjs.map +1 -1
  148. package/dist/components/Collapsible/Collapsible.module.js +1 -0
  149. package/dist/components/Collapsible/Collapsible.module.js.map +1 -1
  150. package/dist/components/Combobox/Combobox.module.cjs +1 -0
  151. package/dist/components/Combobox/Combobox.module.cjs.map +1 -1
  152. package/dist/components/Combobox/Combobox.module.js +1 -0
  153. package/dist/components/Combobox/Combobox.module.js.map +1 -1
  154. package/dist/components/Command/Command.module.cjs +1 -0
  155. package/dist/components/Command/Command.module.cjs.map +1 -1
  156. package/dist/components/Command/Command.module.js +1 -0
  157. package/dist/components/Command/Command.module.js.map +1 -1
  158. package/dist/components/ContextMenu/ContextMenu.cjs +1 -1
  159. package/dist/components/ContextMenu/ContextMenu.cjs.map +1 -1
  160. package/dist/components/ContextMenu/ContextMenu.js +100 -48
  161. package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
  162. package/dist/components/ContextMenu/ContextMenu.module.cjs +1 -0
  163. package/dist/components/ContextMenu/ContextMenu.module.cjs.map +1 -1
  164. package/dist/components/ContextMenu/ContextMenu.module.js +1 -0
  165. package/dist/components/ContextMenu/ContextMenu.module.js.map +1 -1
  166. package/dist/components/CopyButton/CopyButton.module.cjs +1 -0
  167. package/dist/components/CopyButton/CopyButton.module.cjs.map +1 -1
  168. package/dist/components/CopyButton/CopyButton.module.js +1 -0
  169. package/dist/components/CopyButton/CopyButton.module.js.map +1 -1
  170. package/dist/components/DataList/DataList.module.cjs +1 -0
  171. package/dist/components/DataList/DataList.module.cjs.map +1 -1
  172. package/dist/components/DataList/DataList.module.js +1 -0
  173. package/dist/components/DataList/DataList.module.js.map +1 -1
  174. package/dist/components/DataTable/DataTable.module.cjs +1 -0
  175. package/dist/components/DataTable/DataTable.module.cjs.map +1 -1
  176. package/dist/components/DataTable/DataTable.module.js +1 -0
  177. package/dist/components/DataTable/DataTable.module.js.map +1 -1
  178. package/dist/components/DateRangePicker/DateRangePicker.module.cjs +1 -0
  179. package/dist/components/DateRangePicker/DateRangePicker.module.cjs.map +1 -1
  180. package/dist/components/DateRangePicker/DateRangePicker.module.js +1 -0
  181. package/dist/components/DateRangePicker/DateRangePicker.module.js.map +1 -1
  182. package/dist/components/DescriptionList/DescriptionList.module.cjs +1 -0
  183. package/dist/components/DescriptionList/DescriptionList.module.cjs.map +1 -1
  184. package/dist/components/DescriptionList/DescriptionList.module.js +1 -0
  185. package/dist/components/DescriptionList/DescriptionList.module.js.map +1 -1
  186. package/dist/components/Divider/Divider.module.cjs +1 -0
  187. package/dist/components/Divider/Divider.module.cjs.map +1 -1
  188. package/dist/components/Divider/Divider.module.js +1 -0
  189. package/dist/components/Divider/Divider.module.js.map +1 -1
  190. package/dist/components/Drawer/Drawer.module.cjs +1 -0
  191. package/dist/components/Drawer/Drawer.module.cjs.map +1 -1
  192. package/dist/components/Drawer/Drawer.module.js +1 -0
  193. package/dist/components/Drawer/Drawer.module.js.map +1 -1
  194. package/dist/components/DropdownMenu/DropdownMenu.module.cjs +1 -0
  195. package/dist/components/DropdownMenu/DropdownMenu.module.cjs.map +1 -1
  196. package/dist/components/DropdownMenu/DropdownMenu.module.js +1 -0
  197. package/dist/components/DropdownMenu/DropdownMenu.module.js.map +1 -1
  198. package/dist/components/Dropzone/Dropzone.module.cjs +1 -0
  199. package/dist/components/Dropzone/Dropzone.module.cjs.map +1 -1
  200. package/dist/components/Dropzone/Dropzone.module.js +1 -0
  201. package/dist/components/Dropzone/Dropzone.module.js.map +1 -1
  202. package/dist/components/EmptyState/EmptyState.module.cjs +1 -0
  203. package/dist/components/EmptyState/EmptyState.module.cjs.map +1 -1
  204. package/dist/components/EmptyState/EmptyState.module.js +1 -0
  205. package/dist/components/EmptyState/EmptyState.module.js.map +1 -1
  206. package/dist/components/ErrorState/ErrorState.module.cjs +1 -0
  207. package/dist/components/ErrorState/ErrorState.module.cjs.map +1 -1
  208. package/dist/components/ErrorState/ErrorState.module.js +1 -0
  209. package/dist/components/ErrorState/ErrorState.module.js.map +1 -1
  210. package/dist/components/ErrorText/ErrorText.module.cjs +1 -0
  211. package/dist/components/ErrorText/ErrorText.module.cjs.map +1 -1
  212. package/dist/components/ErrorText/ErrorText.module.js +1 -0
  213. package/dist/components/ErrorText/ErrorText.module.js.map +1 -1
  214. package/dist/components/FileUpload/FileUpload.module.cjs +1 -0
  215. package/dist/components/FileUpload/FileUpload.module.cjs.map +1 -1
  216. package/dist/components/FileUpload/FileUpload.module.js +1 -0
  217. package/dist/components/FileUpload/FileUpload.module.js.map +1 -1
  218. package/dist/components/FilterBar/FilterBar.module.cjs +1 -0
  219. package/dist/components/FilterBar/FilterBar.module.cjs.map +1 -1
  220. package/dist/components/FilterBar/FilterBar.module.js +1 -0
  221. package/dist/components/FilterBar/FilterBar.module.js.map +1 -1
  222. package/dist/components/FloatingActionButton/FloatingActionButton.module.cjs +1 -0
  223. package/dist/components/FloatingActionButton/FloatingActionButton.module.cjs.map +1 -1
  224. package/dist/components/FloatingActionButton/FloatingActionButton.module.js +1 -0
  225. package/dist/components/FloatingActionButton/FloatingActionButton.module.js.map +1 -1
  226. package/dist/components/Form/Form.module.cjs +1 -0
  227. package/dist/components/Form/Form.module.cjs.map +1 -1
  228. package/dist/components/Form/Form.module.js +1 -0
  229. package/dist/components/Form/Form.module.js.map +1 -1
  230. package/dist/components/HoverCard/HoverCard.module.cjs +1 -0
  231. package/dist/components/HoverCard/HoverCard.module.cjs.map +1 -1
  232. package/dist/components/HoverCard/HoverCard.module.js +1 -0
  233. package/dist/components/HoverCard/HoverCard.module.js.map +1 -1
  234. package/dist/components/Image/Image.module.cjs +1 -0
  235. package/dist/components/Image/Image.module.cjs.map +1 -1
  236. package/dist/components/Image/Image.module.js +1 -0
  237. package/dist/components/Image/Image.module.js.map +1 -1
  238. package/dist/components/ImageCropper/ImageCropper.module.cjs +1 -0
  239. package/dist/components/ImageCropper/ImageCropper.module.cjs.map +1 -1
  240. package/dist/components/ImageCropper/ImageCropper.module.js +1 -0
  241. package/dist/components/ImageCropper/ImageCropper.module.js.map +1 -1
  242. package/dist/components/Input/Input.module.cjs +1 -0
  243. package/dist/components/Input/Input.module.cjs.map +1 -1
  244. package/dist/components/Input/Input.module.js +1 -0
  245. package/dist/components/Input/Input.module.js.map +1 -1
  246. package/dist/components/InstallBanner/InstallBanner.module.cjs +1 -0
  247. package/dist/components/InstallBanner/InstallBanner.module.cjs.map +1 -1
  248. package/dist/components/InstallBanner/InstallBanner.module.js +1 -0
  249. package/dist/components/InstallBanner/InstallBanner.module.js.map +1 -1
  250. package/dist/components/Kanban/Kanban.module.cjs +1 -0
  251. package/dist/components/Kanban/Kanban.module.cjs.map +1 -1
  252. package/dist/components/Kanban/Kanban.module.js +1 -0
  253. package/dist/components/Kanban/Kanban.module.js.map +1 -1
  254. package/dist/components/Kbd/Kbd.module.cjs +1 -0
  255. package/dist/components/Kbd/Kbd.module.cjs.map +1 -1
  256. package/dist/components/Kbd/Kbd.module.js +1 -0
  257. package/dist/components/Kbd/Kbd.module.js.map +1 -1
  258. package/dist/components/Label/Label.module.cjs +1 -0
  259. package/dist/components/Label/Label.module.cjs.map +1 -1
  260. package/dist/components/Label/Label.module.js +1 -0
  261. package/dist/components/Label/Label.module.js.map +1 -1
  262. package/dist/components/Layout/Layout.module.cjs +1 -0
  263. package/dist/components/Layout/Layout.module.cjs.map +1 -1
  264. package/dist/components/Layout/Layout.module.js +1 -0
  265. package/dist/components/Layout/Layout.module.js.map +1 -1
  266. package/dist/components/Lightbox/Lightbox.module.cjs +1 -0
  267. package/dist/components/Lightbox/Lightbox.module.cjs.map +1 -1
  268. package/dist/components/Lightbox/Lightbox.module.js +1 -0
  269. package/dist/components/Lightbox/Lightbox.module.js.map +1 -1
  270. package/dist/components/ListTile/ListTile.module.cjs +1 -0
  271. package/dist/components/ListTile/ListTile.module.cjs.map +1 -1
  272. package/dist/components/ListTile/ListTile.module.js +1 -0
  273. package/dist/components/ListTile/ListTile.module.js.map +1 -1
  274. package/dist/components/Markdown/Markdown.module.cjs +1 -0
  275. package/dist/components/Markdown/Markdown.module.cjs.map +1 -1
  276. package/dist/components/Markdown/Markdown.module.js +1 -0
  277. package/dist/components/Markdown/Markdown.module.js.map +1 -1
  278. package/dist/components/Masonry/Masonry.module.cjs +1 -0
  279. package/dist/components/Masonry/Masonry.module.cjs.map +1 -1
  280. package/dist/components/Masonry/Masonry.module.js +1 -0
  281. package/dist/components/Masonry/Masonry.module.js.map +1 -1
  282. package/dist/components/Menubar/Menubar.module.cjs +1 -0
  283. package/dist/components/Menubar/Menubar.module.cjs.map +1 -1
  284. package/dist/components/Menubar/Menubar.module.js +1 -0
  285. package/dist/components/Menubar/Menubar.module.js.map +1 -1
  286. package/dist/components/Modal/Modal.module.cjs +1 -0
  287. package/dist/components/Modal/Modal.module.cjs.map +1 -1
  288. package/dist/components/Modal/Modal.module.js +1 -0
  289. package/dist/components/Modal/Modal.module.js.map +1 -1
  290. package/dist/components/ModalsManager/ModalsManager.module.cjs +1 -0
  291. package/dist/components/ModalsManager/ModalsManager.module.cjs.map +1 -1
  292. package/dist/components/ModalsManager/ModalsManager.module.js +1 -0
  293. package/dist/components/ModalsManager/ModalsManager.module.js.map +1 -1
  294. package/dist/components/MultiSelect/MultiSelect.module.cjs +1 -0
  295. package/dist/components/MultiSelect/MultiSelect.module.cjs.map +1 -1
  296. package/dist/components/MultiSelect/MultiSelect.module.js +1 -0
  297. package/dist/components/MultiSelect/MultiSelect.module.js.map +1 -1
  298. package/dist/components/NProgress/NProgress.module.cjs +1 -0
  299. package/dist/components/NProgress/NProgress.module.cjs.map +1 -1
  300. package/dist/components/NProgress/NProgress.module.js +1 -0
  301. package/dist/components/NProgress/NProgress.module.js.map +1 -1
  302. package/dist/components/Navbar/Navbar.module.cjs +1 -0
  303. package/dist/components/Navbar/Navbar.module.cjs.map +1 -1
  304. package/dist/components/Navbar/Navbar.module.js +1 -0
  305. package/dist/components/Navbar/Navbar.module.js.map +1 -1
  306. package/dist/components/NavigationMenu/NavigationMenu.module.cjs +1 -0
  307. package/dist/components/NavigationMenu/NavigationMenu.module.cjs.map +1 -1
  308. package/dist/components/NavigationMenu/NavigationMenu.module.js +1 -0
  309. package/dist/components/NavigationMenu/NavigationMenu.module.js.map +1 -1
  310. package/dist/components/NavigationRail/NavigationRail.module.cjs +1 -0
  311. package/dist/components/NavigationRail/NavigationRail.module.cjs.map +1 -1
  312. package/dist/components/NavigationRail/NavigationRail.module.js +1 -0
  313. package/dist/components/NavigationRail/NavigationRail.module.js.map +1 -1
  314. package/dist/components/NotificationCenter/NotificationCenter.module.cjs +1 -0
  315. package/dist/components/NotificationCenter/NotificationCenter.module.cjs.map +1 -1
  316. package/dist/components/NotificationCenter/NotificationCenter.module.js +1 -0
  317. package/dist/components/NotificationCenter/NotificationCenter.module.js.map +1 -1
  318. package/dist/components/OfflineIndicator/OfflineIndicator.module.cjs +1 -0
  319. package/dist/components/OfflineIndicator/OfflineIndicator.module.cjs.map +1 -1
  320. package/dist/components/OfflineIndicator/OfflineIndicator.module.js +1 -0
  321. package/dist/components/OfflineIndicator/OfflineIndicator.module.js.map +1 -1
  322. package/dist/components/Page/Page.module.cjs +1 -0
  323. package/dist/components/Page/Page.module.cjs.map +1 -1
  324. package/dist/components/Page/Page.module.js +1 -0
  325. package/dist/components/Page/Page.module.js.map +1 -1
  326. package/dist/components/Pagination/Pagination.module.cjs +1 -0
  327. package/dist/components/Pagination/Pagination.module.cjs.map +1 -1
  328. package/dist/components/Pagination/Pagination.module.js +1 -0
  329. package/dist/components/Pagination/Pagination.module.js.map +1 -1
  330. package/dist/components/PasswordInput/PasswordInput.module.cjs +1 -0
  331. package/dist/components/PasswordInput/PasswordInput.module.cjs.map +1 -1
  332. package/dist/components/PasswordInput/PasswordInput.module.js +1 -0
  333. package/dist/components/PasswordInput/PasswordInput.module.js.map +1 -1
  334. package/dist/components/PinInput/PinInput.module.cjs +1 -0
  335. package/dist/components/PinInput/PinInput.module.cjs.map +1 -1
  336. package/dist/components/PinInput/PinInput.module.js +1 -0
  337. package/dist/components/PinInput/PinInput.module.js.map +1 -1
  338. package/dist/components/Popover/Popover.module.cjs +1 -0
  339. package/dist/components/Popover/Popover.module.cjs.map +1 -1
  340. package/dist/components/Popover/Popover.module.js +1 -0
  341. package/dist/components/Popover/Popover.module.js.map +1 -1
  342. package/dist/components/Progress/Progress.module.cjs +1 -0
  343. package/dist/components/Progress/Progress.module.cjs.map +1 -1
  344. package/dist/components/Progress/Progress.module.js +1 -0
  345. package/dist/components/Progress/Progress.module.js.map +1 -1
  346. package/dist/components/QRCode/QRCode.module.cjs +1 -0
  347. package/dist/components/QRCode/QRCode.module.cjs.map +1 -1
  348. package/dist/components/QRCode/QRCode.module.js +1 -0
  349. package/dist/components/QRCode/QRCode.module.js.map +1 -1
  350. package/dist/components/Radio/Radio.module.cjs +1 -0
  351. package/dist/components/Radio/Radio.module.cjs.map +1 -1
  352. package/dist/components/Radio/Radio.module.js +1 -0
  353. package/dist/components/Radio/Radio.module.js.map +1 -1
  354. package/dist/components/RangeSlider/RangeSlider.module.cjs +1 -0
  355. package/dist/components/RangeSlider/RangeSlider.module.cjs.map +1 -1
  356. package/dist/components/RangeSlider/RangeSlider.module.js +1 -0
  357. package/dist/components/RangeSlider/RangeSlider.module.js.map +1 -1
  358. package/dist/components/RatingStars/RatingStars.module.cjs +1 -0
  359. package/dist/components/RatingStars/RatingStars.module.cjs.map +1 -1
  360. package/dist/components/RatingStars/RatingStars.module.js +1 -0
  361. package/dist/components/RatingStars/RatingStars.module.js.map +1 -1
  362. package/dist/components/RefreshIndicator/RefreshIndicator.module.cjs +1 -0
  363. package/dist/components/RefreshIndicator/RefreshIndicator.module.cjs.map +1 -1
  364. package/dist/components/RefreshIndicator/RefreshIndicator.module.js +1 -0
  365. package/dist/components/RefreshIndicator/RefreshIndicator.module.js.map +1 -1
  366. package/dist/components/Resizable/Resizable.module.cjs +1 -0
  367. package/dist/components/Resizable/Resizable.module.cjs.map +1 -1
  368. package/dist/components/Resizable/Resizable.module.js +1 -0
  369. package/dist/components/Resizable/Resizable.module.js.map +1 -1
  370. package/dist/components/SafeArea/SafeArea.module.cjs +1 -0
  371. package/dist/components/SafeArea/SafeArea.module.cjs.map +1 -1
  372. package/dist/components/SafeArea/SafeArea.module.js +1 -0
  373. package/dist/components/SafeArea/SafeArea.module.js.map +1 -1
  374. package/dist/components/Scheduler/Scheduler.module.cjs +1 -0
  375. package/dist/components/Scheduler/Scheduler.module.cjs.map +1 -1
  376. package/dist/components/Scheduler/Scheduler.module.js +1 -0
  377. package/dist/components/Scheduler/Scheduler.module.js.map +1 -1
  378. package/dist/components/ScrollArea/ScrollArea.module.cjs +1 -0
  379. package/dist/components/ScrollArea/ScrollArea.module.cjs.map +1 -1
  380. package/dist/components/ScrollArea/ScrollArea.module.js +1 -0
  381. package/dist/components/ScrollArea/ScrollArea.module.js.map +1 -1
  382. package/dist/components/SearchBar/SearchBar.module.cjs +1 -0
  383. package/dist/components/SearchBar/SearchBar.module.cjs.map +1 -1
  384. package/dist/components/SearchBar/SearchBar.module.js +1 -0
  385. package/dist/components/SearchBar/SearchBar.module.js.map +1 -1
  386. package/dist/components/SegmentedControl/SegmentedControl.module.cjs +1 -0
  387. package/dist/components/SegmentedControl/SegmentedControl.module.cjs.map +1 -1
  388. package/dist/components/SegmentedControl/SegmentedControl.module.js +1 -0
  389. package/dist/components/SegmentedControl/SegmentedControl.module.js.map +1 -1
  390. package/dist/components/Select/Select.module.cjs +1 -0
  391. package/dist/components/Select/Select.module.cjs.map +1 -1
  392. package/dist/components/Select/Select.module.js +1 -0
  393. package/dist/components/Select/Select.module.js.map +1 -1
  394. package/dist/components/Sidebar/Sidebar.module.cjs +1 -0
  395. package/dist/components/Sidebar/Sidebar.module.cjs.map +1 -1
  396. package/dist/components/Sidebar/Sidebar.module.js +1 -0
  397. package/dist/components/Sidebar/Sidebar.module.js.map +1 -1
  398. package/dist/components/SignaturePad/SignaturePad.module.cjs +1 -0
  399. package/dist/components/SignaturePad/SignaturePad.module.cjs.map +1 -1
  400. package/dist/components/SignaturePad/SignaturePad.module.js +1 -0
  401. package/dist/components/SignaturePad/SignaturePad.module.js.map +1 -1
  402. package/dist/components/Skeleton/Skeleton.module.cjs +1 -0
  403. package/dist/components/Skeleton/Skeleton.module.cjs.map +1 -1
  404. package/dist/components/Skeleton/Skeleton.module.js +1 -0
  405. package/dist/components/Skeleton/Skeleton.module.js.map +1 -1
  406. package/dist/components/Slider/Slider.module.cjs +1 -0
  407. package/dist/components/Slider/Slider.module.cjs.map +1 -1
  408. package/dist/components/Slider/Slider.module.js +1 -0
  409. package/dist/components/Slider/Slider.module.js.map +1 -1
  410. package/dist/components/Spacer/Spacer.module.cjs +1 -0
  411. package/dist/components/Spacer/Spacer.module.cjs.map +1 -1
  412. package/dist/components/Spacer/Spacer.module.js +1 -0
  413. package/dist/components/Spacer/Spacer.module.js.map +1 -1
  414. package/dist/components/Sparkline/Sparkline.module.cjs +1 -0
  415. package/dist/components/Sparkline/Sparkline.module.cjs.map +1 -1
  416. package/dist/components/Sparkline/Sparkline.module.js +1 -0
  417. package/dist/components/Sparkline/Sparkline.module.js.map +1 -1
  418. package/dist/components/Spinner/Spinner.module.cjs +1 -0
  419. package/dist/components/Spinner/Spinner.module.cjs.map +1 -1
  420. package/dist/components/Spinner/Spinner.module.js +1 -0
  421. package/dist/components/Spinner/Spinner.module.js.map +1 -1
  422. package/dist/components/Stat/Stat.module.cjs +1 -0
  423. package/dist/components/Stat/Stat.module.cjs.map +1 -1
  424. package/dist/components/Stat/Stat.module.js +1 -0
  425. package/dist/components/Stat/Stat.module.js.map +1 -1
  426. package/dist/components/Stepper/Stepper.module.cjs +1 -0
  427. package/dist/components/Stepper/Stepper.module.cjs.map +1 -1
  428. package/dist/components/Stepper/Stepper.module.js +1 -0
  429. package/dist/components/Stepper/Stepper.module.js.map +1 -1
  430. package/dist/components/StepperInput/StepperInput.module.cjs +1 -0
  431. package/dist/components/StepperInput/StepperInput.module.cjs.map +1 -1
  432. package/dist/components/StepperInput/StepperInput.module.js +1 -0
  433. package/dist/components/StepperInput/StepperInput.module.js.map +1 -1
  434. package/dist/components/Switch/Switch.module.cjs +1 -0
  435. package/dist/components/Switch/Switch.module.cjs.map +1 -1
  436. package/dist/components/Switch/Switch.module.js +1 -0
  437. package/dist/components/Switch/Switch.module.js.map +1 -1
  438. package/dist/components/SyncStatusBadge/SyncStatusBadge.module.cjs +1 -0
  439. package/dist/components/SyncStatusBadge/SyncStatusBadge.module.cjs.map +1 -1
  440. package/dist/components/SyncStatusBadge/SyncStatusBadge.module.js +1 -0
  441. package/dist/components/SyncStatusBadge/SyncStatusBadge.module.js.map +1 -1
  442. package/dist/components/Table/Table.module.cjs +1 -0
  443. package/dist/components/Table/Table.module.cjs.map +1 -1
  444. package/dist/components/Table/Table.module.js +1 -0
  445. package/dist/components/Table/Table.module.js.map +1 -1
  446. package/dist/components/Tabs/Tabs.module.cjs +1 -0
  447. package/dist/components/Tabs/Tabs.module.cjs.map +1 -1
  448. package/dist/components/Tabs/Tabs.module.js +1 -0
  449. package/dist/components/Tabs/Tabs.module.js.map +1 -1
  450. package/dist/components/Tag/Tag.module.cjs +1 -0
  451. package/dist/components/Tag/Tag.module.cjs.map +1 -1
  452. package/dist/components/Tag/Tag.module.js +1 -0
  453. package/dist/components/Tag/Tag.module.js.map +1 -1
  454. package/dist/components/Textarea/Textarea.module.cjs +1 -0
  455. package/dist/components/Textarea/Textarea.module.cjs.map +1 -1
  456. package/dist/components/Textarea/Textarea.module.js +1 -0
  457. package/dist/components/Textarea/Textarea.module.js.map +1 -1
  458. package/dist/components/TimePicker/TimePicker.module.cjs +1 -0
  459. package/dist/components/TimePicker/TimePicker.module.cjs.map +1 -1
  460. package/dist/components/TimePicker/TimePicker.module.js +1 -0
  461. package/dist/components/TimePicker/TimePicker.module.js.map +1 -1
  462. package/dist/components/Timeline/Timeline.module.cjs +1 -0
  463. package/dist/components/Timeline/Timeline.module.cjs.map +1 -1
  464. package/dist/components/Timeline/Timeline.module.js +1 -0
  465. package/dist/components/Timeline/Timeline.module.js.map +1 -1
  466. package/dist/components/Toast/Toast.module.cjs +1 -0
  467. package/dist/components/Toast/Toast.module.cjs.map +1 -1
  468. package/dist/components/Toast/Toast.module.js +1 -0
  469. package/dist/components/Toast/Toast.module.js.map +1 -1
  470. package/dist/components/Toggle/Toggle.module.cjs +1 -0
  471. package/dist/components/Toggle/Toggle.module.cjs.map +1 -1
  472. package/dist/components/Toggle/Toggle.module.js +1 -0
  473. package/dist/components/Toggle/Toggle.module.js.map +1 -1
  474. package/dist/components/ToggleGroup/ToggleGroup.module.cjs +1 -0
  475. package/dist/components/ToggleGroup/ToggleGroup.module.cjs.map +1 -1
  476. package/dist/components/ToggleGroup/ToggleGroup.module.js +1 -0
  477. package/dist/components/ToggleGroup/ToggleGroup.module.js.map +1 -1
  478. package/dist/components/Tooltip/Tooltip.module.cjs +1 -0
  479. package/dist/components/Tooltip/Tooltip.module.cjs.map +1 -1
  480. package/dist/components/Tooltip/Tooltip.module.js +1 -0
  481. package/dist/components/Tooltip/Tooltip.module.js.map +1 -1
  482. package/dist/components/Tour/Tour.module.cjs +1 -0
  483. package/dist/components/Tour/Tour.module.cjs.map +1 -1
  484. package/dist/components/Tour/Tour.module.js +1 -0
  485. package/dist/components/Tour/Tour.module.js.map +1 -1
  486. package/dist/components/Transfer/Transfer.module.cjs +1 -0
  487. package/dist/components/Transfer/Transfer.module.cjs.map +1 -1
  488. package/dist/components/Transfer/Transfer.module.js +1 -0
  489. package/dist/components/Transfer/Transfer.module.js.map +1 -1
  490. package/dist/components/TreeView/TreeView.module.cjs +1 -0
  491. package/dist/components/TreeView/TreeView.module.cjs.map +1 -1
  492. package/dist/components/TreeView/TreeView.module.js +1 -0
  493. package/dist/components/TreeView/TreeView.module.js.map +1 -1
  494. package/dist/components/TruncateText/TruncateText.module.cjs +1 -0
  495. package/dist/components/TruncateText/TruncateText.module.cjs.map +1 -1
  496. package/dist/components/TruncateText/TruncateText.module.js +1 -0
  497. package/dist/components/TruncateText/TruncateText.module.js.map +1 -1
  498. package/dist/components/UpdatePrompt/UpdatePrompt.module.cjs +1 -0
  499. package/dist/components/UpdatePrompt/UpdatePrompt.module.cjs.map +1 -1
  500. package/dist/components/UpdatePrompt/UpdatePrompt.module.js +1 -0
  501. package/dist/components/UpdatePrompt/UpdatePrompt.module.js.map +1 -1
  502. package/dist/components/VideoPlayer/VideoPlayer.module.cjs +1 -0
  503. package/dist/components/VideoPlayer/VideoPlayer.module.cjs.map +1 -1
  504. package/dist/components/VideoPlayer/VideoPlayer.module.js +1 -0
  505. package/dist/components/VideoPlayer/VideoPlayer.module.js.map +1 -1
  506. package/dist/components/VirtualList/VirtualList.module.cjs +1 -0
  507. package/dist/components/VirtualList/VirtualList.module.cjs.map +1 -1
  508. package/dist/components/VirtualList/VirtualList.module.js +1 -0
  509. package/dist/components/VirtualList/VirtualList.module.js.map +1 -1
  510. package/dist/components/VirtualTable/VirtualTable.module.cjs +1 -0
  511. package/dist/components/VirtualTable/VirtualTable.module.cjs.map +1 -1
  512. package/dist/components/VirtualTable/VirtualTable.module.js +1 -0
  513. package/dist/components/VirtualTable/VirtualTable.module.js.map +1 -1
  514. package/dist/components/VisuallyHidden/VisuallyHidden.module.cjs +1 -0
  515. package/dist/components/VisuallyHidden/VisuallyHidden.module.cjs.map +1 -1
  516. package/dist/components/VisuallyHidden/VisuallyHidden.module.js +1 -0
  517. package/dist/components/VisuallyHidden/VisuallyHidden.module.js.map +1 -1
  518. package/dist/components/Wizard/Wizard.module.cjs +1 -0
  519. package/dist/components/Wizard/Wizard.module.cjs.map +1 -1
  520. package/dist/components/Wizard/Wizard.module.js +1 -0
  521. package/dist/components/Wizard/Wizard.module.js.map +1 -1
  522. package/dist/editor/RichTextEditor.module.cjs +1 -0
  523. package/dist/editor/RichTextEditor.module.cjs.map +1 -1
  524. package/dist/editor/RichTextEditor.module.js +1 -0
  525. package/dist/editor/RichTextEditor.module.js.map +1 -1
  526. package/dist/geo/TrajectoryMap.module.cjs +1 -0
  527. package/dist/geo/TrajectoryMap.module.cjs.map +1 -1
  528. package/dist/geo/TrajectoryMap.module.js +1 -0
  529. package/dist/geo/TrajectoryMap.module.js.map +1 -1
  530. package/dist/icons/IconPicker.module.cjs +1 -0
  531. package/dist/icons/IconPicker.module.cjs.map +1 -1
  532. package/dist/icons/IconPicker.module.js +1 -0
  533. package/dist/icons/IconPicker.module.js.map +1 -1
  534. package/dist/styles/AIChat.css +1 -78
  535. package/dist/styles/Accordion.css +1 -11
  536. package/dist/styles/Alert.css +1 -31
  537. package/dist/styles/AppBar.css +1 -16
  538. package/dist/styles/AppShell.css +1 -7
  539. package/dist/styles/AspectRatio.css +1 -2
  540. package/dist/styles/AudioPlayer.css +1 -12
  541. package/dist/styles/AudioRecorder.css +1 -19
  542. package/dist/styles/Avatar.css +1 -12
  543. package/dist/styles/AvatarGroup.css +1 -17
  544. package/dist/styles/Badge.css +1 -24
  545. package/dist/styles/Banner.css +1 -12
  546. package/dist/styles/BarList.css +1 -9
  547. package/dist/styles/BarcodeScanner.css +1 -20
  548. package/dist/styles/BottomNavigation.css +1 -9
  549. package/dist/styles/BottomSheet.css +1 -10
  550. package/dist/styles/BrazilMap.css +1 -19
  551. package/dist/styles/Breadcrumbs.css +1 -7
  552. package/dist/styles/Button.css +1 -41
  553. package/dist/styles/Calendar.css +1 -15
  554. package/dist/styles/Card.css +1 -14
  555. package/dist/styles/Carousel.css +1 -16
  556. package/dist/styles/Center.css +1 -4
  557. package/dist/styles/Chat.css +1 -34
  558. package/dist/styles/Checkbox.css +1 -10
  559. package/dist/styles/ChipInput.css +1 -12
  560. package/dist/styles/CodeBlock.css +1 -24
  561. package/dist/styles/Collapsible.css +1 -5
  562. package/dist/styles/Combobox.css +1 -17
  563. package/dist/styles/Command.css +1 -19
  564. package/dist/styles/ContextMenu.css +1 -10
  565. package/dist/styles/CopyButton.css +1 -3
  566. package/dist/styles/DataList.css +1 -2
  567. package/dist/styles/DataTable.css +1 -18
  568. package/dist/styles/DateRangePicker.css +1 -21
  569. package/dist/styles/DescriptionList.css +1 -3
  570. package/dist/styles/Divider.css +1 -10
  571. package/dist/styles/Drawer.css +1 -21
  572. package/dist/styles/DropdownMenu.css +1 -15
  573. package/dist/styles/Dropzone.css +1 -6
  574. package/dist/styles/EmptyState.css +1 -5
  575. package/dist/styles/ErrorState.css +1 -5
  576. package/dist/styles/ErrorText.css +1 -1
  577. package/dist/styles/FileUpload.css +1 -16
  578. package/dist/styles/FilterBar.css +1 -18
  579. package/dist/styles/FloatingActionButton.css +1 -22
  580. package/dist/styles/Form.css +1 -20
  581. package/dist/styles/HoverCard.css +1 -10
  582. package/dist/styles/IconPicker.css +1 -5
  583. package/dist/styles/Image.css +1 -1
  584. package/dist/styles/ImageCropper.css +1 -15
  585. package/dist/styles/Input.css +1 -23
  586. package/dist/styles/InstallBanner.css +1 -7
  587. package/dist/styles/Kanban.css +1 -14
  588. package/dist/styles/Kbd.css +1 -4
  589. package/dist/styles/Label.css +1 -2
  590. package/dist/styles/Layout.css +1 -21
  591. package/dist/styles/Lightbox.css +1 -20
  592. package/dist/styles/ListTile.css +1 -13
  593. package/dist/styles/MapLegend.css +1 -8
  594. package/dist/styles/Markdown.css +1 -23
  595. package/dist/styles/Masonry.css +1 -3
  596. package/dist/styles/Menubar.css +1 -16
  597. package/dist/styles/Modal.css +1 -20
  598. package/dist/styles/ModalsManager.css +1 -1
  599. package/dist/styles/MultiSelect.css +1 -20
  600. package/dist/styles/MunicipalitySearch.css +1 -5
  601. package/dist/styles/NProgress.css +1 -1
  602. package/dist/styles/Navbar.css +1 -9
  603. package/dist/styles/NavigationMenu.css +1 -11
  604. package/dist/styles/NavigationRail.css +1 -13
  605. package/dist/styles/NotificationCenter.css +1 -20
  606. package/dist/styles/OfflineIndicator.css +1 -6
  607. package/dist/styles/Page.css +1 -12
  608. package/dist/styles/Pagination.css +1 -11
  609. package/dist/styles/PasswordInput.css +1 -20
  610. package/dist/styles/PinInput.css +1 -12
  611. package/dist/styles/PixQRCode.css +1 -8
  612. package/dist/styles/Popover.css +1 -9
  613. package/dist/styles/Progress.css +1 -10
  614. package/dist/styles/QRCode.css +1 -2
  615. package/dist/styles/Radio.css +1 -13
  616. package/dist/styles/RangeSlider.css +1 -14
  617. package/dist/styles/RatingStars.css +1 -10
  618. package/dist/styles/RefreshIndicator.css +1 -4
  619. package/dist/styles/Resizable.css +1 -12
  620. package/dist/styles/RichTextEditor.css +1 -18
  621. package/dist/styles/SafeArea.css +1 -6
  622. package/dist/styles/Scheduler.css +1 -23
  623. package/dist/styles/ScrollArea.css +1 -6
  624. package/dist/styles/SearchBar.css +1 -10
  625. package/dist/styles/SegmentedControl.css +1 -11
  626. package/dist/styles/Select.css +1 -13
  627. package/dist/styles/Sidebar.css +1 -18
  628. package/dist/styles/SignaturePad.css +1 -5
  629. package/dist/styles/Skeleton.css +1 -6
  630. package/dist/styles/Slider.css +1 -14
  631. package/dist/styles/Spacer.css +1 -3
  632. package/dist/styles/Sparkline.css +1 -3
  633. package/dist/styles/Spinner.css +1 -11
  634. package/dist/styles/Stat.css +1 -11
  635. package/dist/styles/Stepper.css +1 -16
  636. package/dist/styles/StepperInput.css +1 -14
  637. package/dist/styles/Switch.css +1 -10
  638. package/dist/styles/SyncStatusBadge.css +1 -12
  639. package/dist/styles/Table.css +1 -15
  640. package/dist/styles/Tabs.css +1 -13
  641. package/dist/styles/Tag.css +1 -13
  642. package/dist/styles/Textarea.css +1 -12
  643. package/dist/styles/TimePicker.css +1 -13
  644. package/dist/styles/Timeline.css +1 -16
  645. package/dist/styles/Toast.css +1 -20
  646. package/dist/styles/Toggle.css +1 -11
  647. package/dist/styles/ToggleGroup.css +1 -8
  648. package/dist/styles/Tooltip.css +1 -9
  649. package/dist/styles/Tour.css +1 -19
  650. package/dist/styles/TrajectoryMap.css +1 -15
  651. package/dist/styles/Transfer.css +1 -20
  652. package/dist/styles/TreeView.css +1 -16
  653. package/dist/styles/TruncateText.css +1 -1
  654. package/dist/styles/UpdatePrompt.css +1 -9
  655. package/dist/styles/VideoPlayer.css +1 -22
  656. package/dist/styles/VirtualList.css +1 -4
  657. package/dist/styles/VirtualTable.css +1 -16
  658. package/dist/styles/VisuallyHidden.css +1 -1
  659. package/dist/styles/Wizard.css +1 -3
  660. package/dist/styles/advanced.css +2 -0
  661. package/dist/styles/chat.css +28 -0
  662. package/dist/styles/component/AIChat.css +79 -0
  663. package/dist/styles/component/Accordion.css +12 -0
  664. package/dist/styles/component/Alert.css +32 -0
  665. package/dist/styles/component/AppBar.css +17 -0
  666. package/dist/styles/component/AppShell.css +8 -0
  667. package/dist/styles/component/AspectRatio.css +3 -0
  668. package/dist/styles/component/AudioPlayer.css +13 -0
  669. package/dist/styles/component/AudioRecorder.css +20 -0
  670. package/dist/styles/component/Avatar.css +13 -0
  671. package/dist/styles/component/AvatarGroup.css +18 -0
  672. package/dist/styles/component/Badge.css +25 -0
  673. package/dist/styles/component/Banner.css +13 -0
  674. package/dist/styles/component/BarList.css +10 -0
  675. package/dist/styles/component/BarcodeScanner.css +21 -0
  676. package/dist/styles/component/BottomNavigation.css +10 -0
  677. package/dist/styles/component/BottomSheet.css +11 -0
  678. package/dist/styles/component/BrazilMap.css +20 -0
  679. package/dist/styles/component/Breadcrumbs.css +8 -0
  680. package/dist/styles/component/Button.css +42 -0
  681. package/dist/styles/component/Calendar.css +16 -0
  682. package/dist/styles/component/Card.css +15 -0
  683. package/dist/styles/component/Carousel.css +17 -0
  684. package/dist/styles/component/Center.css +5 -0
  685. package/dist/styles/component/Chat.css +63 -0
  686. package/dist/styles/component/Checkbox.css +11 -0
  687. package/dist/styles/component/ChipInput.css +13 -0
  688. package/dist/styles/component/CodeBlock.css +25 -0
  689. package/dist/styles/component/Collapsible.css +6 -0
  690. package/dist/styles/component/Combobox.css +18 -0
  691. package/dist/styles/component/Command.css +20 -0
  692. package/dist/styles/component/ContextMenu.css +13 -0
  693. package/dist/styles/component/CopyButton.css +4 -0
  694. package/dist/styles/component/DataList.css +3 -0
  695. package/dist/styles/component/DataTable.css +19 -0
  696. package/dist/styles/component/DateRangePicker.css +22 -0
  697. package/dist/styles/component/DescriptionList.css +4 -0
  698. package/dist/styles/component/Divider.css +11 -0
  699. package/dist/styles/component/Drawer.css +22 -0
  700. package/dist/styles/component/DropdownMenu.css +16 -0
  701. package/dist/styles/component/Dropzone.css +7 -0
  702. package/dist/styles/component/EmptyState.css +6 -0
  703. package/dist/styles/component/ErrorState.css +6 -0
  704. package/dist/styles/component/ErrorText.css +2 -0
  705. package/dist/styles/component/FileUpload.css +17 -0
  706. package/dist/styles/component/FilterBar.css +19 -0
  707. package/dist/styles/component/FloatingActionButton.css +23 -0
  708. package/dist/styles/component/Form.css +21 -0
  709. package/dist/styles/component/HoverCard.css +11 -0
  710. package/dist/styles/component/IconPicker.css +6 -0
  711. package/dist/styles/component/Image.css +2 -0
  712. package/dist/styles/component/ImageCropper.css +16 -0
  713. package/dist/styles/component/Input.css +24 -0
  714. package/dist/styles/component/InstallBanner.css +8 -0
  715. package/dist/styles/component/Kanban.css +15 -0
  716. package/dist/styles/component/Kbd.css +5 -0
  717. package/dist/styles/component/Label.css +3 -0
  718. package/dist/styles/component/Layout.css +22 -0
  719. package/dist/styles/component/Lightbox.css +21 -0
  720. package/dist/styles/component/ListTile.css +14 -0
  721. package/dist/styles/component/MapLegend.css +9 -0
  722. package/dist/styles/component/Markdown.css +24 -0
  723. package/dist/styles/component/Masonry.css +4 -0
  724. package/dist/styles/component/Menubar.css +17 -0
  725. package/dist/styles/component/Modal.css +21 -0
  726. package/dist/styles/component/ModalsManager.css +2 -0
  727. package/dist/styles/component/MultiSelect.css +21 -0
  728. package/dist/styles/component/MunicipalitySearch.css +6 -0
  729. package/dist/styles/component/NProgress.css +2 -0
  730. package/dist/styles/component/Navbar.css +10 -0
  731. package/dist/styles/component/NavigationMenu.css +12 -0
  732. package/dist/styles/component/NavigationRail.css +14 -0
  733. package/dist/styles/component/NotificationCenter.css +21 -0
  734. package/dist/styles/component/OfflineIndicator.css +7 -0
  735. package/dist/styles/component/Page.css +13 -0
  736. package/dist/styles/component/Pagination.css +12 -0
  737. package/dist/styles/component/PasswordInput.css +21 -0
  738. package/dist/styles/component/PinInput.css +13 -0
  739. package/dist/styles/component/PixQRCode.css +9 -0
  740. package/dist/styles/component/Popover.css +10 -0
  741. package/dist/styles/component/Progress.css +11 -0
  742. package/dist/styles/component/QRCode.css +3 -0
  743. package/dist/styles/component/Radio.css +14 -0
  744. package/dist/styles/component/RangeSlider.css +15 -0
  745. package/dist/styles/component/RatingStars.css +11 -0
  746. package/dist/styles/component/RefreshIndicator.css +5 -0
  747. package/dist/styles/component/Resizable.css +13 -0
  748. package/dist/styles/component/RichTextEditor.css +19 -0
  749. package/dist/styles/component/SafeArea.css +7 -0
  750. package/dist/styles/component/Scheduler.css +24 -0
  751. package/dist/styles/component/ScrollArea.css +7 -0
  752. package/dist/styles/component/SearchBar.css +11 -0
  753. package/dist/styles/component/SegmentedControl.css +12 -0
  754. package/dist/styles/component/Select.css +14 -0
  755. package/dist/styles/component/Sidebar.css +19 -0
  756. package/dist/styles/component/SignaturePad.css +6 -0
  757. package/dist/styles/component/Skeleton.css +7 -0
  758. package/dist/styles/component/Slider.css +15 -0
  759. package/dist/styles/component/Spacer.css +4 -0
  760. package/dist/styles/component/Sparkline.css +4 -0
  761. package/dist/styles/component/Spinner.css +12 -0
  762. package/dist/styles/component/Stat.css +12 -0
  763. package/dist/styles/component/Stepper.css +17 -0
  764. package/dist/styles/component/StepperInput.css +15 -0
  765. package/dist/styles/component/Switch.css +11 -0
  766. package/dist/styles/component/SyncStatusBadge.css +13 -0
  767. package/dist/styles/component/Table.css +16 -0
  768. package/dist/styles/component/Tabs.css +14 -0
  769. package/dist/styles/component/Tag.css +14 -0
  770. package/dist/styles/component/Textarea.css +13 -0
  771. package/dist/styles/component/TimePicker.css +14 -0
  772. package/dist/styles/component/Timeline.css +17 -0
  773. package/dist/styles/component/Toast.css +21 -0
  774. package/dist/styles/component/Toggle.css +12 -0
  775. package/dist/styles/component/ToggleGroup.css +9 -0
  776. package/dist/styles/component/Tooltip.css +10 -0
  777. package/dist/styles/component/Tour.css +20 -0
  778. package/dist/styles/component/TrajectoryMap.css +16 -0
  779. package/dist/styles/component/Transfer.css +21 -0
  780. package/dist/styles/component/TreeView.css +17 -0
  781. package/dist/styles/component/TruncateText.css +2 -0
  782. package/dist/styles/component/UpdatePrompt.css +10 -0
  783. package/dist/styles/component/VideoPlayer.css +23 -0
  784. package/dist/styles/component/VirtualList.css +5 -0
  785. package/dist/styles/component/VirtualTable.css +17 -0
  786. package/dist/styles/component/VisuallyHidden.css +2 -0
  787. package/dist/styles/component/Wizard.css +4 -0
  788. package/dist/styles/manifest.json +202 -190
  789. package/dist/styles.css +1 -1
  790. package/dist/tempest-react-sdk.cjs +1 -1
  791. package/dist/tempest-react-sdk.d.ts +253 -10
  792. package/dist/tempest-react-sdk.js +169 -167
  793. package/dist/theme/create-theme.cjs +3 -3
  794. package/dist/theme/create-theme.cjs.map +1 -1
  795. package/dist/theme/create-theme.js +109 -57
  796. package/dist/theme/create-theme.js.map +1 -1
  797. package/dist/vite/narrow-tokens.cjs +3 -0
  798. package/dist/vite/narrow-tokens.cjs.map +1 -0
  799. package/dist/vite/narrow-tokens.js +50 -0
  800. package/dist/vite/narrow-tokens.js.map +1 -0
  801. package/dist/vite/tempest-styles.cjs +6 -4
  802. package/dist/vite/tempest-styles.cjs.map +1 -1
  803. package/dist/vite/tempest-styles.js +73 -47
  804. package/dist/vite/tempest-styles.js.map +1 -1
  805. package/dist/vite.d.ts +19 -0
  806. package/loader/css-loader-hooks.mjs +37 -0
  807. package/loader/css-loader.mjs +46 -0
  808. package/package.json +4 -2
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.js","names":[],"sources":["../../../src/components/Chat/Chat.tsx"],"sourcesContent":["/**\n * @tempest-limits file-lines, props-count, function-lines — message grouping needs\n * more context than a list does: currentUserId to decide sides, groupWindowMs and\n * now to decide where a bubble group breaks, typing for the indicator. The remaining\n * props are the composer's (placeholder, composerActions, composerDisabled, onSend,\n * onSendError) and the slots (renderAvatar, header, emptyState).\n */\nimport { useEffect, useLayoutEffect, useRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nimport { EmptyState } from \"../EmptyState\";\nimport { VisuallyHidden } from \"../VisuallyHidden\";\nimport { ChatComposer, type ChatComposerHandle } from \"./ChatComposer\";\nimport {\n chatStrings,\n dayLabel,\n groupMessages,\n timeLabel,\n typingLabel,\n type ChatMessage,\n} from \"./chat-groups\";\nimport styles from \"./Chat.module.css\";\n\n/** DOM attributes this component redefines. */\ntype OverriddenDomProps = \"children\" | \"onSubmit\";\n\nexport interface ChatProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps> {\n /** The thread, **oldest first**. Never reordered by the component. */\n messages: readonly ChatMessage[];\n /** Author id treated as \"own\" — decides side, colour and status ticks. */\n currentUserId?: string;\n /** Renders the composer when given. Receives the trimmed text. */\n onSend?: (text: string) => void | Promise<void>;\n /** Enables the retry control on a `\"failed\"` message. */\n onRetry?: (message: ChatMessage) => void;\n /** Names currently typing. One, two or a count is phrased for you. */\n typing?: readonly string[];\n /** Avatar for the first message of a run — an `<Avatar>`, an `<Icon>`. */\n renderAvatar?: (message: ChatMessage) => ReactNode;\n /** Rendered above the thread, inside the panel. */\n header?: ReactNode;\n /** Shown when there are no messages. */\n emptyState?: ReactNode;\n /** Gap that still keeps consecutive messages in one run. Default 5 min. */\n groupWindowMs?: number;\n /** Locale for labels. Default `\"pt-BR\"`. */\n locale?: \"pt-BR\" | \"en\";\n /** Reference instant for \"Hoje\"/\"Ontem\". Default: now, at render time. */\n now?: number;\n /** Placeholder for the composer. */\n placeholder?: string;\n /** Extra controls inside the composer, before the send button. */\n composerActions?: ReactNode;\n /** Disable the composer — no permission, thread archived, offline. */\n composerDisabled?: boolean;\n /** Called when `onSend` rejects. The draft stays in the field either way. */\n onSendError?: (error: unknown) => void;\n}\n\n/** Status glyph and label for an outgoing message. */\nconst STATUS_GLYPH: Record<NonNullable<ChatMessage[\"status\"]>, string> = {\n sending: \"◌\",\n sent: \"✓\",\n read: \"✓✓\",\n failed: \"!\",\n};\n\n/**\n * A message thread: grouped by author and by day, own messages on one side, with\n * delivery state, a typing indicator and an optional composer.\n *\n * Presentational and controlled, like the rest of the SDK: it takes a list and\n * emits intent (`onSend`, `onRetry`). Where messages come from — REST, the SDK's\n * `createWebSocket`, an SSE stream — and how an optimistic insert is done stay with\n * the app, because those differ per backend and a component that assumed one would\n * be wrong for most.\n *\n * It works as a comment thread too: that is the same component with\n * `currentUserId` set and no `typing`.\n *\n * @example\n * <Chat\n * messages={messages}\n * currentUserId={me.id}\n * typing={typingNames}\n * onSend={(text) => send({ text })}\n * onRetry={(message) => resend(message.id)}\n * />\n */\nexport function Chat({\n messages,\n currentUserId,\n onSend,\n onRetry,\n typing = [],\n renderAvatar,\n header,\n emptyState,\n groupWindowMs,\n locale = \"pt-BR\",\n now,\n placeholder,\n composerActions,\n composerDisabled,\n onSendError,\n className,\n ...rest\n}: ChatProps) {\n const strings = chatStrings(locale);\n const sections = groupMessages({ messages, currentUserId, windowMs: groupWindowMs });\n const composer = useRef<ChatComposerHandle | null>(null);\n const thread = useRef<HTMLDivElement | null>(null);\n const stuckToBottom = useRef(true);\n\n /**\n * Remember whether the reader is at the bottom, before the next batch lands.\n *\n * A thread that always scrolls to the newest message yanks somebody out of the\n * history they were reading, every time anyone types. So the jump only happens\n * when they were already at the bottom — the same rule every chat app converges\n * on. The 48px slack covers a partially visible last row.\n */\n const trackPosition = (): void => {\n const node = thread.current;\n if (!node) return;\n const distance = node.scrollHeight - node.scrollTop - node.clientHeight;\n stuckToBottom.current = distance < 48;\n };\n\n useLayoutEffect(() => {\n const node = thread.current;\n if (!node || !stuckToBottom.current) return;\n node.scrollTop = node.scrollHeight;\n }, [messages, typing]);\n\n useEffect(() => {\n const node = thread.current;\n if (!node) return;\n node.scrollTop = node.scrollHeight;\n // Mount lands on the newest message; from then on `trackPosition` decides.\n }, []);\n\n const typingText = typingLabel(typing, locale);\n\n return (\n <div className={cn(styles.panel, className)} {...rest}>\n {header && <header className={styles.header}>{header}</header>}\n\n <div\n ref={thread}\n className={styles.thread}\n onScroll={trackPosition}\n role=\"log\"\n aria-live=\"polite\"\n aria-relevant=\"additions text\"\n tabIndex={0}\n aria-label={strings.thread}\n >\n {messages.length === 0\n ? (emptyState ?? <EmptyState title={strings.empty} />)\n : sections.map((section) =>\n section.kind === \"day\" ? (\n <div key={section.key} className={styles.day}>\n <span className={styles.dayLabel}>\n {dayLabel(section.date, { locale, now })}\n </span>\n </div>\n ) : (\n <div\n key={section.key}\n className={cn(styles.run, section.own && styles.ownRun)}\n >\n {renderAvatar && (\n <div className={styles.avatar} aria-hidden=\"true\">\n {renderAvatar(section.messages[0])}\n </div>\n )}\n <div className={styles.runBody}>\n <span className={styles.author}>\n {section.own\n ? strings.you\n : (section.authorName ?? section.authorId)}\n </span>\n <ul className={styles.bubbles}>\n {section.messages.map((message) => (\n <li key={message.id} className={styles.bubbleRow}>\n <div\n className={cn(\n styles.bubble,\n section.own && styles.ownBubble,\n message.status === \"failed\" &&\n styles.failedBubble,\n )}\n >\n <div className={styles.body}>\n {message.body}\n </div>\n <div className={styles.meta}>\n <time\n dateTime={new Date(\n message.sentAt,\n ).toISOString()}\n >\n {timeLabel(message.sentAt, locale)}\n </time>\n {section.own && message.status && (\n <span\n className={cn(\n styles.status,\n message.status === \"failed\" &&\n styles.statusFailed,\n )}\n title={strings[message.status]}\n >\n <span aria-hidden=\"true\">\n {STATUS_GLYPH[message.status]}\n </span>\n <VisuallyHidden>\n {strings[message.status]}\n </VisuallyHidden>\n </span>\n )}\n </div>\n </div>\n {message.status === \"failed\" && onRetry && (\n <button\n type=\"button\"\n className={styles.retry}\n onClick={() => onRetry(message)}\n >\n {strings.retry}\n </button>\n )}\n </li>\n ))}\n </ul>\n </div>\n </div>\n ),\n )}\n </div>\n\n {typingText && (\n <p className={styles.typing} aria-live=\"polite\">\n {typingText}\n </p>\n )}\n\n {onSend && (\n <ChatComposer\n ref={composer}\n onSend={onSend}\n locale={locale}\n placeholder={placeholder}\n actions={composerActions}\n disabled={composerDisabled}\n onError={onSendError}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"Chat.js","names":[],"sources":["../../../src/components/Chat/Chat.tsx"],"sourcesContent":["/**\n * @tempest-limits file-lines, props-count, function-lines — message grouping needs\n * more context than a list does: currentUserId to decide sides, groupWindowMs and\n * now to decide where a bubble group breaks, typing for the indicator. The remaining\n * props are the composer's (placeholder, composerActions, composerDisabled, onSend,\n * onSendError) and the slots (renderAvatar, header, emptyState).\n */\nimport { useEffect, useLayoutEffect, useRef, type HTMLAttributes, type ReactNode } from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nimport type { ContextMenuItem } from \"../ContextMenu\";\nimport { EmptyState } from \"../EmptyState\";\nimport { ChatBubble } from \"./ChatBubble\";\nimport { ChatComposer, type ChatComposerHandle } from \"./ChatComposer\";\nimport { chatStrings, dayLabel, groupMessages, typingLabel, type ChatMessage } from \"./chat-groups\";\nimport styles from \"./Chat.module.css\";\n\n/** DOM attributes this component redefines. */\ntype OverriddenDomProps = \"children\" | \"onSubmit\";\n\nexport interface ChatProps extends Omit<HTMLAttributes<HTMLDivElement>, OverriddenDomProps> {\n /** The thread, **oldest first**. Never reordered by the component. */\n messages: readonly ChatMessage[];\n /** Author id treated as \"own\" — decides side, colour and status ticks. */\n currentUserId?: string;\n /** Renders the composer when given. Receives the trimmed text. */\n onSend?: (text: string) => void | Promise<void>;\n /** Enables the retry control on a `\"failed\"` message. */\n onRetry?: (message: ChatMessage) => void;\n /** Names currently typing. One, two or a count is phrased for you. */\n typing?: readonly string[];\n /** Avatar for the first message of a run — an `<Avatar>`, an `<Icon>`. */\n renderAvatar?: (message: ChatMessage) => ReactNode;\n /** Rendered above the thread, inside the panel. */\n header?: ReactNode;\n /** Shown when there are no messages. */\n emptyState?: ReactNode;\n /** Gap that still keeps consecutive messages in one run. Default 5 min. */\n groupWindowMs?: number;\n /** Locale for labels. Default `\"pt-BR\"`. */\n locale?: \"pt-BR\" | \"en\";\n /** Reference instant for \"Hoje\"/\"Ontem\". Default: now, at render time. */\n now?: number;\n /** Placeholder for the composer. */\n placeholder?: string;\n /** Extra controls inside the composer, before the send button. */\n composerActions?: ReactNode;\n /** Disable the composer — no permission, thread archived, offline. */\n composerDisabled?: boolean;\n /** Called when `onSend` rejects. The draft stays in the field either way. */\n onSendError?: (error: unknown) => void;\n /**\n * Toggles a reaction on a message. Enables the reaction chips.\n *\n * Called with the emoji that was pressed, including one the user already\n * reacted with: reacting again clears it, rather than stacking a second copy.\n * The app owns that rule — the component only reports the press.\n */\n onReact?: (message: ChatMessage, emoji: string) => void;\n /**\n * Per-message actions: reply, forward, star, edit, delete.\n *\n * Returns the items for one message, opened by right click, by long press on\n * touch, and by a `⋮` button on the bubble. Buttons painted on every bubble\n * turn a conversation into a toolbar, which is why this is a menu.\n */\n messageActions?: (message: ChatMessage) => ContextMenuItem[];\n /** Called when a reply stub is activated — scroll to the quoted message. */\n onQuoteClick?: (message: ChatMessage) => void;\n}\n\n/**\n * A message thread: grouped by author and by day, own messages on one side, with\n * delivery state, a typing indicator and an optional composer.\n *\n * Presentational and controlled, like the rest of the SDK: it takes a list and\n * emits intent (`onSend`, `onRetry`). Where messages come from — REST, the SDK's\n * `createWebSocket`, an SSE stream — and how an optimistic insert is done stay with\n * the app, because those differ per backend and a component that assumed one would\n * be wrong for most.\n *\n * It works as a comment thread too: that is the same component with\n * `currentUserId` set and no `typing`.\n *\n * @example\n * <Chat\n * messages={messages}\n * currentUserId={me.id}\n * typing={typingNames}\n * onSend={(text) => send({ text })}\n * onRetry={(message) => resend(message.id)}\n * />\n */\nexport function Chat({\n messages,\n currentUserId,\n onSend,\n onRetry,\n typing = [],\n renderAvatar,\n header,\n emptyState,\n groupWindowMs,\n locale = \"pt-BR\",\n now,\n placeholder,\n composerActions,\n composerDisabled,\n onSendError,\n onReact,\n messageActions,\n onQuoteClick,\n className,\n ...rest\n}: ChatProps) {\n const strings = chatStrings(locale);\n const sections = groupMessages({ messages, currentUserId, windowMs: groupWindowMs });\n const composer = useRef<ChatComposerHandle | null>(null);\n const thread = useRef<HTMLDivElement | null>(null);\n const stuckToBottom = useRef(true);\n\n /**\n * Remember whether the reader is at the bottom, before the next batch lands.\n *\n * A thread that always scrolls to the newest message yanks somebody out of the\n * history they were reading, every time anyone types. So the jump only happens\n * when they were already at the bottom — the same rule every chat app converges\n * on. The 48px slack covers a partially visible last row.\n */\n const trackPosition = (): void => {\n const node = thread.current;\n if (!node) return;\n const distance = node.scrollHeight - node.scrollTop - node.clientHeight;\n stuckToBottom.current = distance < 48;\n };\n\n useLayoutEffect(() => {\n const node = thread.current;\n if (!node || !stuckToBottom.current) return;\n node.scrollTop = node.scrollHeight;\n }, [messages, typing]);\n\n useEffect(() => {\n const node = thread.current;\n if (!node) return;\n node.scrollTop = node.scrollHeight;\n // Mount lands on the newest message; from then on `trackPosition` decides.\n }, []);\n\n const typingText = typingLabel(typing, locale);\n\n return (\n <div className={cn(styles.panel, className)} {...rest}>\n {header && <header className={styles.header}>{header}</header>}\n\n <div\n ref={thread}\n className={styles.thread}\n onScroll={trackPosition}\n role=\"log\"\n aria-live=\"polite\"\n aria-relevant=\"additions text\"\n tabIndex={0}\n aria-label={strings.thread}\n >\n {messages.length === 0\n ? (emptyState ?? <EmptyState title={strings.empty} />)\n : sections.map((section) =>\n section.kind === \"day\" ? (\n <div key={section.key} className={styles.day}>\n <span className={styles.dayLabel}>\n {dayLabel(section.date, { locale, now })}\n </span>\n </div>\n ) : (\n <div\n key={section.key}\n className={cn(styles.run, section.own && styles.ownRun)}\n >\n {renderAvatar && (\n <div className={styles.avatar} aria-hidden=\"true\">\n {renderAvatar(section.messages[0])}\n </div>\n )}\n <div className={styles.runBody}>\n <span className={styles.author}>\n {section.own\n ? strings.you\n : (section.authorName ?? section.authorId)}\n </span>\n <ul className={styles.bubbles}>\n {section.messages.map((message) => (\n <ChatBubble\n key={message.id}\n message={message}\n own={section.own}\n locale={locale}\n onRetry={onRetry}\n onReact={onReact}\n messageActions={messageActions}\n onQuoteClick={onQuoteClick}\n />\n ))}\n </ul>\n </div>\n </div>\n ),\n )}\n </div>\n\n {typingText && (\n <p className={styles.typing} aria-live=\"polite\">\n {typingText}\n </p>\n )}\n\n {onSend && (\n <ChatComposer\n ref={composer}\n onSend={onSend}\n locale={locale}\n placeholder={placeholder}\n actions={composerActions}\n disabled={composerDisabled}\n onError={onSendError}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AA8FA,SAAgB,EAAK,EACjB,aACA,kBACA,WACA,YACA,YAAS,CAAC,GACV,iBACA,WACA,eACA,kBACA,YAAS,SACT,QACA,gBACA,oBACA,qBACA,gBACA,YACA,mBACA,iBACA,cACA,GAAG,KACO;CACV,IAAM,IAAU,EAAY,CAAM,GAC5B,IAAW,EAAc;EAAE;EAAU;EAAe,UAAU;CAAc,CAAC,GAC7E,IAAW,EAAkC,IAAI,GACjD,IAAS,EAA8B,IAAI,GAC3C,IAAgB,EAAO,EAAI,GAU3B,UAA4B;EAC9B,IAAM,IAAO,EAAO;EACpB,IAAI,CAAC,GAAM;EACX,IAAM,IAAW,EAAK,eAAe,EAAK,YAAY,EAAK;EAC3D,EAAc,UAAU,IAAW;CACvC;CAQA,AANA,QAAsB;EAClB,IAAM,IAAO,EAAO;EAChB,AAAC,KAAS,EAAc,YAC5B,EAAK,YAAY,EAAK;CAC1B,GAAG,CAAC,GAAU,CAAM,CAAC,GAErB,QAAgB;EACZ,IAAM,IAAO,EAAO;EACf,MACL,EAAK,YAAY,EAAK;CAE1B,GAAG,CAAC,CAAC;CAEL,IAAM,IAAa,EAAY,GAAQ,CAAM;CAE7C,OACI,kBAAC,OAAD;EAAK,WAAW,EAAG,EAAO,OAAO,CAAS;EAAG,GAAI;EAAjD,UAAA;GACK,KAAU,kBAAC,UAAD;IAAQ,WAAW,EAAO;IAAS,UAAA;GAAe,CAAA;GAE7D,kBAAC,OAAD;IACI,KAAK;IACL,WAAW,EAAO;IAClB,UAAU;IACV,MAAK;IACL,aAAU;IACV,iBAAc;IACd,UAAU;IACV,cAAY,EAAQ;IAEnB,UAAA,EAAS,WAAW,IACd,KAAc,kBAAC,GAAD,EAAY,OAAO,EAAQ,MAAQ,CAAA,IAClD,EAAS,KAAK,MACV,EAAQ,SAAS,QACb,kBAAC,OAAD;KAAuB,WAAW,EAAO;KACrC,UAAA,kBAAC,QAAD;MAAM,WAAW,EAAO;MACnB,UAAA,EAAS,EAAQ,MAAM;OAAE;OAAQ;MAAI,CAAC;KACrC,CAAA;IACL,GAJK,EAAQ,GAIb,IAEL,kBAAC,OAAD;KAEI,WAAW,EAAG,EAAO,KAAK,EAAQ,OAAO,EAAO,MAAM;KAF1D,UAAA,CAIK,KACG,kBAAC,OAAD;MAAK,WAAW,EAAO;MAAQ,eAAY;MACtC,UAAA,EAAa,EAAQ,SAAS,EAAE;KAChC,CAAA,GAET,kBAAC,OAAD;MAAK,WAAW,EAAO;MAAvB,UAAA,CACI,kBAAC,QAAD;OAAM,WAAW,EAAO;OACnB,UAAA,EAAQ,MACH,EAAQ,MACP,EAAQ,cAAc,EAAQ;MACnC,CAAA,GACN,kBAAC,MAAD;OAAI,WAAW,EAAO;OACjB,UAAA,EAAQ,SAAS,KAAK,MACnB,kBAAC,GAAD;QAEa;QACT,KAAK,EAAQ;QACL;QACC;QACA;QACO;QACF;OACjB,GARQ,EAAQ,EAQhB,CACJ;MACD,CAAA,CACH;KACJ,CAAA,CAAA;IA7BI,GAAA,EAAQ,GA6BZ,CAEb;GACL,CAAA;GAEJ,KACG,kBAAC,KAAD;IAAG,WAAW,EAAO;IAAQ,aAAU;IAClC,UAAA;GACF,CAAA;GAGN,KACG,kBAAC,GAAD;IACI,KAAK;IACG;IACA;IACK;IACb,SAAS;IACT,UAAU;IACV,SAAS;GACZ,CAAA;EAEJ;;AAEb"}
@@ -1,2 +1,3 @@
1
- var e=`tempest_panel_xUVw0`,t=`tempest_header_muoPu`,n=`tempest_thread_-j8yS`,r=`tempest_day_uLsWA`,i=`tempest_dayLabel_m8rDy`,a=`tempest_run_jOUv7`,o=`tempest_ownRun_3XTG5`,s=`tempest_avatar_d9SYT`,c=`tempest_runBody_nHQC3`,l=`tempest_author_4MRkd`,u=`tempest_bubbles_VYaQ0`,d=`tempest_bubbleRow_QSc41`,f=`tempest_bubble_GGFcU`,p=`tempest_ownBubble_agOMW`,m=`tempest_failedBubble_kT3F5`,h=`tempest_body_1aH2F`,g=`tempest_meta_3fNx8`,_=`tempest_status_EeiUt`,v=`tempest_statusFailed_Bfro1`,y=`tempest_retry_DAbIj`,b=`tempest_typing_zdp3O`,x=`tempest_composer_krOGl`,S=`tempest_field_fBY-q`,C=`tempest_composerActions_MYwQx`,w=`tempest_send_NwcaR`,T={panel:e,header:t,thread:n,day:r,dayLabel:i,run:a,ownRun:o,avatar:s,runBody:c,author:l,bubbles:u,bubbleRow:d,bubble:f,ownBubble:p,failedBubble:m,body:h,meta:g,status:_,statusFailed:v,retry:y,typing:b,composer:x,field:S,composerActions:C,send:w};exports.author=l,exports.avatar=s,exports.body=h,exports.bubble=f,exports.bubbleRow=d,exports.bubbles=u,exports.composer=x,exports.composerActions=C,exports.day=r,exports.dayLabel=i,exports.default=T,exports.failedBubble=m,exports.field=S,exports.header=t,exports.meta=g,exports.ownBubble=p,exports.ownRun=o,exports.panel=e,exports.retry=y,exports.run=a,exports.runBody=c,exports.send=w,exports.status=_,exports.statusFailed=v,exports.thread=n,exports.typing=b;
1
+ require("../../styles/component/Chat.css");
2
+ var e=`tempest_panel_xUVw0`,t=`tempest_header_muoPu`,n=`tempest_thread_-j8yS`,r=`tempest_day_uLsWA`,i=`tempest_dayLabel_m8rDy`,a=`tempest_run_jOUv7`,o=`tempest_ownRun_3XTG5`,s=`tempest_avatar_d9SYT`,c=`tempest_runBody_nHQC3`,l=`tempest_author_4MRkd`,u=`tempest_bubbles_VYaQ0`,d=`tempest_bubbleRow_QSc41`,f=`tempest_bubble_GGFcU`,p=`tempest_ownBubble_agOMW`,m=`tempest_failedBubble_kT3F5`,h=`tempest_body_1aH2F`,g=`tempest_meta_3fNx8`,_=`tempest_status_EeiUt`,v=`tempest_statusFailed_Bfro1`,y=`tempest_reactions_D4iGE`,b=`tempest_reaction_WkkNQ`,x=`tempest_reactionMine_81mXj`,S=`tempest_actionsButton_v8oqH`,C=`tempest_quote_1muxm`,w=`tempest_quoteButton_eD0Dx`,T=`tempest_quoteAuthor_Jpx15`,E=`tempest_quoteText_9KI-m`,D=`tempest_quoteRevoked_RQ-5u`,O=`tempest_tombstone_7Iiw-`,k=`tempest_deletedBubble_dZQFE`,A=`tempest_edited_kTire`,j=`tempest_statusRead_Wj77L`,M=`tempest_attachments_h8wIJ`,N=`tempest_attachmentsFallback_YT9RT`,P=`tempest_imageAttachment_PggzU`,F=`tempest_videoAttachment_0TsUC`,I=`tempest_voiceAttachment_1EUcu`,L=`tempest_waveform_5K-qs`,R=`tempest_fileAttachment_H803b`,z=`tempest_fileName_2Fwix`,B=`tempest_fileMeta_T1fdS`,V=`tempest_retry_DAbIj`,H=`tempest_typing_zdp3O`,U=`tempest_composer_krOGl`,W=`tempest_field_fBY-q`,G=`tempest_composerActions_MYwQx`,K=`tempest_send_NwcaR`,q={panel:e,header:t,thread:n,day:r,dayLabel:i,run:a,ownRun:o,avatar:s,runBody:c,author:l,bubbles:u,bubbleRow:d,bubble:f,ownBubble:p,failedBubble:m,body:h,meta:g,status:_,statusFailed:v,reactions:y,reaction:b,reactionMine:x,actionsButton:S,quote:C,quoteButton:w,quoteAuthor:T,quoteText:E,quoteRevoked:D,tombstone:O,deletedBubble:k,edited:A,statusRead:j,attachments:M,attachmentsFallback:N,imageAttachment:P,videoAttachment:F,voiceAttachment:I,waveform:L,fileAttachment:R,fileName:z,fileMeta:B,retry:V,typing:H,composer:U,field:W,composerActions:G,send:K};exports.actionsButton=S,exports.attachments=M,exports.attachmentsFallback=N,exports.author=l,exports.avatar=s,exports.body=h,exports.bubble=f,exports.bubbleRow=d,exports.bubbles=u,exports.composer=U,exports.composerActions=G,exports.day=r,exports.dayLabel=i,exports.default=q,exports.deletedBubble=k,exports.edited=A,exports.failedBubble=m,exports.field=W,exports.fileAttachment=R,exports.fileMeta=B,exports.fileName=z,exports.header=t,exports.imageAttachment=P,exports.meta=g,exports.ownBubble=p,exports.ownRun=o,exports.panel=e,exports.quote=C,exports.quoteAuthor=T,exports.quoteButton=w,exports.quoteRevoked=D,exports.quoteText=E,exports.reaction=b,exports.reactionMine=x,exports.reactions=y,exports.retry=V,exports.run=a,exports.runBody=c,exports.send=K,exports.status=_,exports.statusFailed=v,exports.statusRead=j,exports.thread=n,exports.tombstone=O,exports.typing=H,exports.videoAttachment=F,exports.voiceAttachment=I,exports.waveform=L;
2
3
  //# sourceMappingURL=Chat.module.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.module.cjs","names":[],"sources":["../../../src/components/Chat/Chat.module.css"],"sourcesContent":[".panel {\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n height: var(--tempest-chat-height, 100%);\n background-color: var(--tempest-bg);\n color: var(--tempest-text);\n font-family: var(--tempest-font-sans);\n}\n\n.header {\n flex: 0 0 auto;\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.thread {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: var(--tempest-space-3);\n min-height: 0;\n padding: var(--tempest-space-4);\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n.thread:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: -2px;\n}\n\n.day {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-3);\n}\n\n.day::before,\n.day::after {\n flex: 1 1 auto;\n height: 1px;\n background-color: var(--tempest-border);\n content: \"\";\n}\n\n.dayLabel {\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-text-xs);\n text-transform: capitalize;\n}\n\n.run {\n display: flex;\n gap: var(--tempest-space-3);\n align-items: flex-start;\n max-width: 100%;\n}\n\n/*\n * Own messages mirror the row instead of moving to a second column: the avatar,\n * the name and the bubbles keep the same source order, so a screen reader still\n * reads \"who, then what\" while the eye reads it from the other side.\n */\n.ownRun {\n flex-direction: row-reverse;\n}\n\n.avatar {\n flex: 0 0 auto;\n}\n\n.runBody {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n min-width: 0;\n max-width: min(78%, 42rem);\n}\n\n.ownRun .runBody {\n align-items: flex-end;\n}\n\n.author {\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-medium);\n}\n\n.bubbles {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.bubbleRow {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n}\n\n.ownRun .bubbleRow {\n flex-direction: row-reverse;\n}\n\n.bubble {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n min-width: 0;\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-lg);\n background-color: var(--tempest-surface);\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-normal);\n}\n\n.ownBubble {\n border-color: transparent;\n background-color: var(--tempest-primary-soft);\n color: var(--tempest-primary-on-soft);\n}\n\n/*\n * A failed message keeps its text readable and states the failure at the border\n * and in the meta row. Tinting the whole bubble danger-red would make the message\n * itself hard to read — and re-reading it is exactly what somebody does before\n * deciding to retry.\n */\n.failedBubble {\n border-color: var(--tempest-danger);\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-text);\n}\n\n.body {\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n\n/*\n * The timestamp uses the muted token, not the subtle one, and switches to the\n * bubble's own foreground when the bubble is tinted.\n *\n * `--tempest-text-subtle` is solved against the page and surface backgrounds. On\n * `--tempest-primary-soft` it is a different composite, and the real browser\n * measured it below the 4.5:1 text floor — the same trap the syntax tokens hit.\n * Size is what de-emphasises the meta row here; colour still has to pass.\n */\n.meta {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--tempest-space-2);\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-2xs);\n font-variant-numeric: tabular-nums;\n}\n\n.ownBubble .meta {\n color: var(--tempest-primary-on-soft);\n}\n\n.status {\n display: inline-flex;\n align-items: center;\n}\n\n.statusFailed {\n color: var(--tempest-danger);\n font-weight: var(--tempest-weight-bold);\n}\n\n.retry {\n padding: 0;\n border: none;\n background: none;\n color: var(--tempest-danger);\n font: inherit;\n font-size: var(--tempest-text-xs);\n text-decoration: underline;\n cursor: pointer;\n}\n\n.typing {\n flex: 0 0 auto;\n margin: 0;\n padding: 0 var(--tempest-space-4) var(--tempest-space-2);\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-text-xs);\n}\n\n.composer {\n display: flex;\n flex: 0 0 auto;\n align-items: flex-end;\n gap: var(--tempest-space-2);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border-top: 1px solid var(--tempest-border);\n}\n\n.field {\n flex: 1 1 auto;\n min-width: 0;\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-md);\n background-color: var(--tempest-bg);\n color: inherit;\n font: inherit;\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-normal);\n resize: none;\n}\n\n.field:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: -1px;\n}\n\n.field:disabled {\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text-subtle);\n cursor: not-allowed;\n}\n\n.composerActions {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n}\n\n.send {\n padding: var(--tempest-space-2) var(--tempest-space-4);\n border: none;\n border-radius: var(--tempest-radius-md);\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n font: inherit;\n font-size: var(--tempest-text-sm);\n font-weight: var(--tempest-weight-medium);\n cursor: pointer;\n}\n\n.send:disabled {\n background-color: var(--tempest-surface-3);\n color: var(--tempest-text-subtle);\n cursor: not-allowed;\n}\n\n@media (max-width: 480px) {\n .runBody {\n max-width: 88%;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Chat.module.cjs","names":[],"sources":["../../../src/components/Chat/Chat.module.css"],"sourcesContent":[".panel {\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n height: var(--tempest-chat-height, 100%);\n background-color: var(--tempest-bg);\n color: var(--tempest-text);\n font-family: var(--tempest-font-sans);\n}\n\n.header {\n flex: 0 0 auto;\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.thread {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: var(--tempest-space-3);\n min-height: 0;\n padding: var(--tempest-space-4);\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n.thread:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: -2px;\n}\n\n.day {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-3);\n}\n\n.day::before,\n.day::after {\n flex: 1 1 auto;\n height: 1px;\n background-color: var(--tempest-border);\n content: \"\";\n}\n\n.dayLabel {\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-text-xs);\n text-transform: capitalize;\n}\n\n.run {\n display: flex;\n gap: var(--tempest-space-3);\n align-items: flex-start;\n max-width: 100%;\n}\n\n/*\n * Own messages mirror the row instead of moving to a second column: the avatar,\n * the name and the bubbles keep the same source order, so a screen reader still\n * reads \"who, then what\" while the eye reads it from the other side.\n */\n.ownRun {\n flex-direction: row-reverse;\n}\n\n.avatar {\n flex: 0 0 auto;\n}\n\n.runBody {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n min-width: 0;\n max-width: min(78%, 42rem);\n}\n\n.ownRun .runBody {\n align-items: flex-end;\n}\n\n.author {\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-medium);\n}\n\n.bubbles {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.bubbleRow {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n}\n\n.ownRun .bubbleRow {\n flex-direction: row-reverse;\n}\n\n.bubble {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n min-width: 0;\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-lg);\n background-color: var(--tempest-surface);\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-normal);\n}\n\n.ownBubble {\n border-color: transparent;\n background-color: var(--tempest-primary-soft);\n color: var(--tempest-primary-on-soft);\n}\n\n/*\n * A failed message keeps its text readable and states the failure at the border\n * and in the meta row. Tinting the whole bubble danger-red would make the message\n * itself hard to read — and re-reading it is exactly what somebody does before\n * deciding to retry.\n */\n.failedBubble {\n border-color: var(--tempest-danger);\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-text);\n}\n\n.body {\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n\n/*\n * The timestamp uses the muted token, not the subtle one, and switches to the\n * bubble's own foreground when the bubble is tinted.\n *\n * `--tempest-text-subtle` is solved against the page and surface backgrounds. On\n * `--tempest-primary-soft` it is a different composite, and the real browser\n * measured it below the 4.5:1 text floor — the same trap the syntax tokens hit.\n * Size is what de-emphasises the meta row here; colour still has to pass.\n */\n.meta {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--tempest-space-2);\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-2xs);\n font-variant-numeric: tabular-nums;\n}\n\n.ownBubble .meta {\n color: var(--tempest-primary-on-soft);\n}\n\n.status {\n display: inline-flex;\n align-items: center;\n}\n\n.statusFailed {\n color: var(--tempest-danger);\n font-weight: var(--tempest-weight-bold);\n}\n\n/*\n * A bubble row carries more than a bubble now: the actions button sits beside it\n * and the reaction chips hang under it, so the row wraps and the chips are given\n * the whole width to fall onto.\n */\n.bubbleRow {\n flex-wrap: wrap;\n}\n\n.reactions {\n display: flex;\n flex-basis: 100%;\n flex-wrap: wrap;\n gap: var(--tempest-space-1);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.ownRun .reactions {\n justify-content: flex-end;\n}\n\n.reaction {\n display: inline-flex;\n align-items: center;\n gap: var(--tempest-space-1);\n padding: 0 var(--tempest-space-2);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-full, 999px);\n background-color: var(--tempest-surface);\n color: var(--tempest-text);\n font: inherit;\n font-size: var(--tempest-text-xs);\n line-height: 1.8;\n cursor: pointer;\n}\n\n.reaction:disabled {\n cursor: default;\n}\n\n/*\n * Your own reaction is marked by a tinted chip and its own foreground, never by\n * `--tempest-text-subtle` over the tint: that token is solved against the page\n * background and fails the text floor on a tinted surface.\n */\n.reactionMine {\n border-color: transparent;\n background-color: var(--tempest-primary-soft);\n color: var(--tempest-primary-on-soft);\n font-weight: var(--tempest-weight-medium);\n}\n\n/*\n * The ⋮ button is always in the DOM — on touch there is no hover to reveal it,\n * and a control that only appears on hover is a control a phone does not have.\n * A fine pointer gets it faded until the row is hovered or it is focused.\n */\n.actionsButton {\n flex: 0 0 auto;\n padding: 0 var(--tempest-space-1);\n border: none;\n background: none;\n color: var(--tempest-text-muted);\n font: inherit;\n line-height: 1;\n cursor: pointer;\n}\n\n@media (hover: hover) and (pointer: fine) {\n .actionsButton {\n opacity: 0;\n transition: var(--tempest-transition-opacity, opacity 120ms ease);\n }\n\n .bubbleRow:hover .actionsButton,\n .actionsButton:focus-visible {\n opacity: 1;\n }\n}\n\n/* The reply stub: a tinted strip with a bar on the side it is anchored to. */\n.quote {\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: 100%;\n padding: var(--tempest-space-1) var(--tempest-space-2);\n border-left: 3px solid var(--tempest-primary);\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text);\n font-size: var(--tempest-text-xs);\n text-align: left;\n}\n\n.quoteButton {\n border-top: none;\n border-right: none;\n border-bottom: none;\n font: inherit;\n font-size: var(--tempest-text-xs);\n cursor: pointer;\n}\n\n/*\n * The author of a quote is text, so it is coloured like text.\n *\n * `--tempest-primary` here measured **4.35:1** against `--tempest-surface-2` in a\n * real browser — below the 4.5:1 floor for a 12px label, and invisible to the\n * jsdom axe sweep, which disables `color-contrast` because nothing is painted.\n * The brand still marks the quote: it is the bar down the side, which is a\n * non-text indicator and only owes 3:1.\n */\n.quoteAuthor {\n color: var(--tempest-text);\n font-weight: var(--tempest-weight-medium);\n}\n\n.quoteText {\n overflow: hidden;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n overflow-wrap: anywhere;\n}\n\n/*\n * A revoked quote reads as absent, which is the point: the text of a deleted\n * message must not survive inside the reply to it.\n */\n.quoteRevoked {\n color: var(--tempest-text-muted);\n font-style: italic;\n}\n\n.tombstone {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-1);\n color: var(--tempest-text-muted);\n font-style: italic;\n}\n\n.deletedBubble {\n border-style: dashed;\n background-color: transparent;\n}\n\n.edited {\n font-style: italic;\n}\n\n/* Read by everyone is the only state that turns the ticks. */\n.statusRead {\n color: var(--tempest-info, var(--tempest-primary));\n}\n\n.attachments {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n max-width: 320px;\n}\n\n/* Holds the row's height while the attachments chunk is still loading. */\n.attachmentsFallback {\n min-height: var(--tempest-space-8, 2rem);\n}\n\n.imageAttachment {\n padding: 0;\n border: none;\n border-radius: var(--tempest-radius-md);\n background: none;\n line-height: 0;\n cursor: pointer;\n}\n\n.imageAttachment img {\n max-width: 100%;\n max-height: 260px;\n border-radius: var(--tempest-radius-md);\n object-fit: cover;\n}\n\n.videoAttachment {\n max-width: 100%;\n border-radius: var(--tempest-radius-md);\n}\n\n.voiceAttachment {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n}\n\n/*\n * The waveform is the difference between a voice note and a grey rectangle: it\n * is what tells somebody whether this is a word or a two-minute monologue.\n */\n.waveform {\n display: flex;\n align-items: flex-end;\n gap: 2px;\n height: 28px;\n}\n\n.waveform span {\n flex: 1 1 auto;\n min-width: 2px;\n border-radius: 1px;\n background-color: var(--tempest-primary);\n opacity: 0.7;\n}\n\n.fileAttachment {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: var(--tempest-space-2);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-md);\n color: var(--tempest-text);\n text-decoration: none;\n}\n\n.fileName {\n overflow-wrap: anywhere;\n font-weight: var(--tempest-weight-medium);\n}\n\n.fileMeta {\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-2xs);\n font-variant-numeric: tabular-nums;\n}\n\n.retry {\n padding: 0;\n border: none;\n background: none;\n color: var(--tempest-danger);\n font: inherit;\n font-size: var(--tempest-text-xs);\n text-decoration: underline;\n cursor: pointer;\n}\n\n.typing {\n flex: 0 0 auto;\n margin: 0;\n padding: 0 var(--tempest-space-4) var(--tempest-space-2);\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-text-xs);\n}\n\n.composer {\n display: flex;\n flex: 0 0 auto;\n align-items: flex-end;\n gap: var(--tempest-space-2);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border-top: 1px solid var(--tempest-border);\n}\n\n.field {\n flex: 1 1 auto;\n min-width: 0;\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-md);\n background-color: var(--tempest-bg);\n color: inherit;\n font: inherit;\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-normal);\n resize: none;\n}\n\n.field:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: -1px;\n}\n\n.field:disabled {\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text-subtle);\n cursor: not-allowed;\n}\n\n.composerActions {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n}\n\n.send {\n padding: var(--tempest-space-2) var(--tempest-space-4);\n border: none;\n border-radius: var(--tempest-radius-md);\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n font: inherit;\n font-size: var(--tempest-text-sm);\n font-weight: var(--tempest-weight-medium);\n cursor: pointer;\n}\n\n.send:disabled {\n background-color: var(--tempest-surface-3);\n color: var(--tempest-text-subtle);\n cursor: not-allowed;\n}\n\n@media (max-width: 480px) {\n .runBody {\n max-width: 88%;\n }\n}\n"],"mappings":";"}
@@ -1,5 +1,6 @@
1
+ import "../../styles/component/Chat.css";
1
2
  //#region src/components/Chat/Chat.module.css
2
- var e = "tempest_panel_xUVw0", t = "tempest_header_muoPu", n = "tempest_thread_-j8yS", r = "tempest_day_uLsWA", i = "tempest_dayLabel_m8rDy", a = "tempest_run_jOUv7", o = "tempest_ownRun_3XTG5", s = "tempest_avatar_d9SYT", c = "tempest_runBody_nHQC3", l = "tempest_author_4MRkd", u = "tempest_bubbles_VYaQ0", d = "tempest_bubbleRow_QSc41", f = "tempest_bubble_GGFcU", p = "tempest_ownBubble_agOMW", m = "tempest_failedBubble_kT3F5", h = "tempest_body_1aH2F", g = "tempest_meta_3fNx8", _ = "tempest_status_EeiUt", v = "tempest_statusFailed_Bfro1", y = "tempest_retry_DAbIj", b = "tempest_typing_zdp3O", x = "tempest_composer_krOGl", S = "tempest_field_fBY-q", C = "tempest_composerActions_MYwQx", w = "tempest_send_NwcaR", T = {
3
+ var e = "tempest_panel_xUVw0", t = "tempest_header_muoPu", n = "tempest_thread_-j8yS", r = "tempest_day_uLsWA", i = "tempest_dayLabel_m8rDy", a = "tempest_run_jOUv7", o = "tempest_ownRun_3XTG5", s = "tempest_avatar_d9SYT", c = "tempest_runBody_nHQC3", l = "tempest_author_4MRkd", u = "tempest_bubbles_VYaQ0", d = "tempest_bubbleRow_QSc41", f = "tempest_bubble_GGFcU", p = "tempest_ownBubble_agOMW", m = "tempest_failedBubble_kT3F5", h = "tempest_body_1aH2F", g = "tempest_meta_3fNx8", _ = "tempest_status_EeiUt", v = "tempest_statusFailed_Bfro1", y = "tempest_reactions_D4iGE", b = "tempest_reaction_WkkNQ", x = "tempest_reactionMine_81mXj", S = "tempest_actionsButton_v8oqH", C = "tempest_quote_1muxm", w = "tempest_quoteButton_eD0Dx", T = "tempest_quoteAuthor_Jpx15", E = "tempest_quoteText_9KI-m", D = "tempest_quoteRevoked_RQ-5u", O = "tempest_tombstone_7Iiw-", k = "tempest_deletedBubble_dZQFE", A = "tempest_edited_kTire", j = "tempest_statusRead_Wj77L", M = "tempest_attachments_h8wIJ", N = "tempest_attachmentsFallback_YT9RT", P = "tempest_imageAttachment_PggzU", F = "tempest_videoAttachment_0TsUC", I = "tempest_voiceAttachment_1EUcu", L = "tempest_waveform_5K-qs", R = "tempest_fileAttachment_H803b", z = "tempest_fileName_2Fwix", B = "tempest_fileMeta_T1fdS", V = "tempest_retry_DAbIj", H = "tempest_typing_zdp3O", U = "tempest_composer_krOGl", W = "tempest_field_fBY-q", G = "tempest_composerActions_MYwQx", K = "tempest_send_NwcaR", q = {
3
4
  panel: e,
4
5
  header: t,
5
6
  thread: n,
@@ -19,14 +20,36 @@ var e = "tempest_panel_xUVw0", t = "tempest_header_muoPu", n = "tempest_thread_-
19
20
  meta: g,
20
21
  status: _,
21
22
  statusFailed: v,
22
- retry: y,
23
- typing: b,
24
- composer: x,
25
- field: S,
26
- composerActions: C,
27
- send: w
23
+ reactions: y,
24
+ reaction: b,
25
+ reactionMine: x,
26
+ actionsButton: S,
27
+ quote: C,
28
+ quoteButton: w,
29
+ quoteAuthor: T,
30
+ quoteText: E,
31
+ quoteRevoked: D,
32
+ tombstone: O,
33
+ deletedBubble: k,
34
+ edited: A,
35
+ statusRead: j,
36
+ attachments: M,
37
+ attachmentsFallback: N,
38
+ imageAttachment: P,
39
+ videoAttachment: F,
40
+ voiceAttachment: I,
41
+ waveform: L,
42
+ fileAttachment: R,
43
+ fileName: z,
44
+ fileMeta: B,
45
+ retry: V,
46
+ typing: H,
47
+ composer: U,
48
+ field: W,
49
+ composerActions: G,
50
+ send: K
28
51
  };
29
52
  //#endregion
30
- export { l as author, s as avatar, h as body, f as bubble, d as bubbleRow, u as bubbles, x as composer, C as composerActions, r as day, i as dayLabel, T as default, m as failedBubble, S as field, t as header, g as meta, p as ownBubble, o as ownRun, e as panel, y as retry, a as run, c as runBody, w as send, _ as status, v as statusFailed, n as thread, b as typing };
53
+ export { S as actionsButton, M as attachments, N as attachmentsFallback, l as author, s as avatar, h as body, f as bubble, d as bubbleRow, u as bubbles, U as composer, G as composerActions, r as day, i as dayLabel, q as default, k as deletedBubble, A as edited, m as failedBubble, W as field, R as fileAttachment, B as fileMeta, z as fileName, t as header, P as imageAttachment, g as meta, p as ownBubble, o as ownRun, e as panel, C as quote, T as quoteAuthor, w as quoteButton, D as quoteRevoked, E as quoteText, b as reaction, x as reactionMine, y as reactions, V as retry, a as run, c as runBody, K as send, _ as status, v as statusFailed, j as statusRead, n as thread, O as tombstone, H as typing, F as videoAttachment, I as voiceAttachment, L as waveform };
31
54
 
32
55
  //# sourceMappingURL=Chat.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.module.js","names":[],"sources":["../../../src/components/Chat/Chat.module.css"],"sourcesContent":[".panel {\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n height: var(--tempest-chat-height, 100%);\n background-color: var(--tempest-bg);\n color: var(--tempest-text);\n font-family: var(--tempest-font-sans);\n}\n\n.header {\n flex: 0 0 auto;\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.thread {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: var(--tempest-space-3);\n min-height: 0;\n padding: var(--tempest-space-4);\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n.thread:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: -2px;\n}\n\n.day {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-3);\n}\n\n.day::before,\n.day::after {\n flex: 1 1 auto;\n height: 1px;\n background-color: var(--tempest-border);\n content: \"\";\n}\n\n.dayLabel {\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-text-xs);\n text-transform: capitalize;\n}\n\n.run {\n display: flex;\n gap: var(--tempest-space-3);\n align-items: flex-start;\n max-width: 100%;\n}\n\n/*\n * Own messages mirror the row instead of moving to a second column: the avatar,\n * the name and the bubbles keep the same source order, so a screen reader still\n * reads \"who, then what\" while the eye reads it from the other side.\n */\n.ownRun {\n flex-direction: row-reverse;\n}\n\n.avatar {\n flex: 0 0 auto;\n}\n\n.runBody {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n min-width: 0;\n max-width: min(78%, 42rem);\n}\n\n.ownRun .runBody {\n align-items: flex-end;\n}\n\n.author {\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-medium);\n}\n\n.bubbles {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.bubbleRow {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n}\n\n.ownRun .bubbleRow {\n flex-direction: row-reverse;\n}\n\n.bubble {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n min-width: 0;\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-lg);\n background-color: var(--tempest-surface);\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-normal);\n}\n\n.ownBubble {\n border-color: transparent;\n background-color: var(--tempest-primary-soft);\n color: var(--tempest-primary-on-soft);\n}\n\n/*\n * A failed message keeps its text readable and states the failure at the border\n * and in the meta row. Tinting the whole bubble danger-red would make the message\n * itself hard to read — and re-reading it is exactly what somebody does before\n * deciding to retry.\n */\n.failedBubble {\n border-color: var(--tempest-danger);\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-text);\n}\n\n.body {\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n\n/*\n * The timestamp uses the muted token, not the subtle one, and switches to the\n * bubble's own foreground when the bubble is tinted.\n *\n * `--tempest-text-subtle` is solved against the page and surface backgrounds. On\n * `--tempest-primary-soft` it is a different composite, and the real browser\n * measured it below the 4.5:1 text floor — the same trap the syntax tokens hit.\n * Size is what de-emphasises the meta row here; colour still has to pass.\n */\n.meta {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--tempest-space-2);\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-2xs);\n font-variant-numeric: tabular-nums;\n}\n\n.ownBubble .meta {\n color: var(--tempest-primary-on-soft);\n}\n\n.status {\n display: inline-flex;\n align-items: center;\n}\n\n.statusFailed {\n color: var(--tempest-danger);\n font-weight: var(--tempest-weight-bold);\n}\n\n.retry {\n padding: 0;\n border: none;\n background: none;\n color: var(--tempest-danger);\n font: inherit;\n font-size: var(--tempest-text-xs);\n text-decoration: underline;\n cursor: pointer;\n}\n\n.typing {\n flex: 0 0 auto;\n margin: 0;\n padding: 0 var(--tempest-space-4) var(--tempest-space-2);\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-text-xs);\n}\n\n.composer {\n display: flex;\n flex: 0 0 auto;\n align-items: flex-end;\n gap: var(--tempest-space-2);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border-top: 1px solid var(--tempest-border);\n}\n\n.field {\n flex: 1 1 auto;\n min-width: 0;\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-md);\n background-color: var(--tempest-bg);\n color: inherit;\n font: inherit;\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-normal);\n resize: none;\n}\n\n.field:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: -1px;\n}\n\n.field:disabled {\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text-subtle);\n cursor: not-allowed;\n}\n\n.composerActions {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n}\n\n.send {\n padding: var(--tempest-space-2) var(--tempest-space-4);\n border: none;\n border-radius: var(--tempest-radius-md);\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n font: inherit;\n font-size: var(--tempest-text-sm);\n font-weight: var(--tempest-weight-medium);\n cursor: pointer;\n}\n\n.send:disabled {\n background-color: var(--tempest-surface-3);\n color: var(--tempest-text-subtle);\n cursor: not-allowed;\n}\n\n@media (max-width: 480px) {\n .runBody {\n max-width: 88%;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Chat.module.js","names":[],"sources":["../../../src/components/Chat/Chat.module.css"],"sourcesContent":[".panel {\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n height: var(--tempest-chat-height, 100%);\n background-color: var(--tempest-bg);\n color: var(--tempest-text);\n font-family: var(--tempest-font-sans);\n}\n\n.header {\n flex: 0 0 auto;\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.thread {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: var(--tempest-space-3);\n min-height: 0;\n padding: var(--tempest-space-4);\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n.thread:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: -2px;\n}\n\n.day {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-3);\n}\n\n.day::before,\n.day::after {\n flex: 1 1 auto;\n height: 1px;\n background-color: var(--tempest-border);\n content: \"\";\n}\n\n.dayLabel {\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-text-xs);\n text-transform: capitalize;\n}\n\n.run {\n display: flex;\n gap: var(--tempest-space-3);\n align-items: flex-start;\n max-width: 100%;\n}\n\n/*\n * Own messages mirror the row instead of moving to a second column: the avatar,\n * the name and the bubbles keep the same source order, so a screen reader still\n * reads \"who, then what\" while the eye reads it from the other side.\n */\n.ownRun {\n flex-direction: row-reverse;\n}\n\n.avatar {\n flex: 0 0 auto;\n}\n\n.runBody {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n min-width: 0;\n max-width: min(78%, 42rem);\n}\n\n.ownRun .runBody {\n align-items: flex-end;\n}\n\n.author {\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-medium);\n}\n\n.bubbles {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.bubbleRow {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n}\n\n.ownRun .bubbleRow {\n flex-direction: row-reverse;\n}\n\n.bubble {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n min-width: 0;\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-lg);\n background-color: var(--tempest-surface);\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-normal);\n}\n\n.ownBubble {\n border-color: transparent;\n background-color: var(--tempest-primary-soft);\n color: var(--tempest-primary-on-soft);\n}\n\n/*\n * A failed message keeps its text readable and states the failure at the border\n * and in the meta row. Tinting the whole bubble danger-red would make the message\n * itself hard to read — and re-reading it is exactly what somebody does before\n * deciding to retry.\n */\n.failedBubble {\n border-color: var(--tempest-danger);\n background-color: var(--tempest-danger-bg);\n color: var(--tempest-text);\n}\n\n.body {\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n\n/*\n * The timestamp uses the muted token, not the subtle one, and switches to the\n * bubble's own foreground when the bubble is tinted.\n *\n * `--tempest-text-subtle` is solved against the page and surface backgrounds. On\n * `--tempest-primary-soft` it is a different composite, and the real browser\n * measured it below the 4.5:1 text floor — the same trap the syntax tokens hit.\n * Size is what de-emphasises the meta row here; colour still has to pass.\n */\n.meta {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--tempest-space-2);\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-2xs);\n font-variant-numeric: tabular-nums;\n}\n\n.ownBubble .meta {\n color: var(--tempest-primary-on-soft);\n}\n\n.status {\n display: inline-flex;\n align-items: center;\n}\n\n.statusFailed {\n color: var(--tempest-danger);\n font-weight: var(--tempest-weight-bold);\n}\n\n/*\n * A bubble row carries more than a bubble now: the actions button sits beside it\n * and the reaction chips hang under it, so the row wraps and the chips are given\n * the whole width to fall onto.\n */\n.bubbleRow {\n flex-wrap: wrap;\n}\n\n.reactions {\n display: flex;\n flex-basis: 100%;\n flex-wrap: wrap;\n gap: var(--tempest-space-1);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.ownRun .reactions {\n justify-content: flex-end;\n}\n\n.reaction {\n display: inline-flex;\n align-items: center;\n gap: var(--tempest-space-1);\n padding: 0 var(--tempest-space-2);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-full, 999px);\n background-color: var(--tempest-surface);\n color: var(--tempest-text);\n font: inherit;\n font-size: var(--tempest-text-xs);\n line-height: 1.8;\n cursor: pointer;\n}\n\n.reaction:disabled {\n cursor: default;\n}\n\n/*\n * Your own reaction is marked by a tinted chip and its own foreground, never by\n * `--tempest-text-subtle` over the tint: that token is solved against the page\n * background and fails the text floor on a tinted surface.\n */\n.reactionMine {\n border-color: transparent;\n background-color: var(--tempest-primary-soft);\n color: var(--tempest-primary-on-soft);\n font-weight: var(--tempest-weight-medium);\n}\n\n/*\n * The ⋮ button is always in the DOM — on touch there is no hover to reveal it,\n * and a control that only appears on hover is a control a phone does not have.\n * A fine pointer gets it faded until the row is hovered or it is focused.\n */\n.actionsButton {\n flex: 0 0 auto;\n padding: 0 var(--tempest-space-1);\n border: none;\n background: none;\n color: var(--tempest-text-muted);\n font: inherit;\n line-height: 1;\n cursor: pointer;\n}\n\n@media (hover: hover) and (pointer: fine) {\n .actionsButton {\n opacity: 0;\n transition: var(--tempest-transition-opacity, opacity 120ms ease);\n }\n\n .bubbleRow:hover .actionsButton,\n .actionsButton:focus-visible {\n opacity: 1;\n }\n}\n\n/* The reply stub: a tinted strip with a bar on the side it is anchored to. */\n.quote {\n display: flex;\n flex-direction: column;\n gap: 2px;\n width: 100%;\n padding: var(--tempest-space-1) var(--tempest-space-2);\n border-left: 3px solid var(--tempest-primary);\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text);\n font-size: var(--tempest-text-xs);\n text-align: left;\n}\n\n.quoteButton {\n border-top: none;\n border-right: none;\n border-bottom: none;\n font: inherit;\n font-size: var(--tempest-text-xs);\n cursor: pointer;\n}\n\n/*\n * The author of a quote is text, so it is coloured like text.\n *\n * `--tempest-primary` here measured **4.35:1** against `--tempest-surface-2` in a\n * real browser — below the 4.5:1 floor for a 12px label, and invisible to the\n * jsdom axe sweep, which disables `color-contrast` because nothing is painted.\n * The brand still marks the quote: it is the bar down the side, which is a\n * non-text indicator and only owes 3:1.\n */\n.quoteAuthor {\n color: var(--tempest-text);\n font-weight: var(--tempest-weight-medium);\n}\n\n.quoteText {\n overflow: hidden;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n overflow-wrap: anywhere;\n}\n\n/*\n * A revoked quote reads as absent, which is the point: the text of a deleted\n * message must not survive inside the reply to it.\n */\n.quoteRevoked {\n color: var(--tempest-text-muted);\n font-style: italic;\n}\n\n.tombstone {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-1);\n color: var(--tempest-text-muted);\n font-style: italic;\n}\n\n.deletedBubble {\n border-style: dashed;\n background-color: transparent;\n}\n\n.edited {\n font-style: italic;\n}\n\n/* Read by everyone is the only state that turns the ticks. */\n.statusRead {\n color: var(--tempest-info, var(--tempest-primary));\n}\n\n.attachments {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n max-width: 320px;\n}\n\n/* Holds the row's height while the attachments chunk is still loading. */\n.attachmentsFallback {\n min-height: var(--tempest-space-8, 2rem);\n}\n\n.imageAttachment {\n padding: 0;\n border: none;\n border-radius: var(--tempest-radius-md);\n background: none;\n line-height: 0;\n cursor: pointer;\n}\n\n.imageAttachment img {\n max-width: 100%;\n max-height: 260px;\n border-radius: var(--tempest-radius-md);\n object-fit: cover;\n}\n\n.videoAttachment {\n max-width: 100%;\n border-radius: var(--tempest-radius-md);\n}\n\n.voiceAttachment {\n display: flex;\n flex-direction: column;\n gap: var(--tempest-space-1);\n}\n\n/*\n * The waveform is the difference between a voice note and a grey rectangle: it\n * is what tells somebody whether this is a word or a two-minute monologue.\n */\n.waveform {\n display: flex;\n align-items: flex-end;\n gap: 2px;\n height: 28px;\n}\n\n.waveform span {\n flex: 1 1 auto;\n min-width: 2px;\n border-radius: 1px;\n background-color: var(--tempest-primary);\n opacity: 0.7;\n}\n\n.fileAttachment {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: var(--tempest-space-2);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-md);\n color: var(--tempest-text);\n text-decoration: none;\n}\n\n.fileName {\n overflow-wrap: anywhere;\n font-weight: var(--tempest-weight-medium);\n}\n\n.fileMeta {\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-2xs);\n font-variant-numeric: tabular-nums;\n}\n\n.retry {\n padding: 0;\n border: none;\n background: none;\n color: var(--tempest-danger);\n font: inherit;\n font-size: var(--tempest-text-xs);\n text-decoration: underline;\n cursor: pointer;\n}\n\n.typing {\n flex: 0 0 auto;\n margin: 0;\n padding: 0 var(--tempest-space-4) var(--tempest-space-2);\n color: var(--tempest-text-subtle);\n font-size: var(--tempest-text-xs);\n}\n\n.composer {\n display: flex;\n flex: 0 0 auto;\n align-items: flex-end;\n gap: var(--tempest-space-2);\n padding: var(--tempest-space-3) var(--tempest-space-4);\n border-top: 1px solid var(--tempest-border);\n}\n\n.field {\n flex: 1 1 auto;\n min-width: 0;\n padding: var(--tempest-space-2) var(--tempest-space-3);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-md);\n background-color: var(--tempest-bg);\n color: inherit;\n font: inherit;\n font-size: var(--tempest-text-sm);\n line-height: var(--tempest-leading-normal);\n resize: none;\n}\n\n.field:focus-visible {\n outline: 2px solid var(--tempest-primary);\n outline-offset: -1px;\n}\n\n.field:disabled {\n background-color: var(--tempest-surface-2);\n color: var(--tempest-text-subtle);\n cursor: not-allowed;\n}\n\n.composerActions {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n}\n\n.send {\n padding: var(--tempest-space-2) var(--tempest-space-4);\n border: none;\n border-radius: var(--tempest-radius-md);\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n font: inherit;\n font-size: var(--tempest-text-sm);\n font-weight: var(--tempest-weight-medium);\n cursor: pointer;\n}\n\n.send:disabled {\n background-color: var(--tempest-surface-3);\n color: var(--tempest-text-subtle);\n cursor: not-allowed;\n}\n\n@media (max-width: 480px) {\n .runBody {\n max-width: 88%;\n }\n}\n"],"mappings":";"}
@@ -0,0 +1,2 @@
1
+ const e=require("../ContextMenu/ContextMenu.cjs");let t=require("react/jsx-runtime");function n({items:n,trigger:r,children:i}){return(0,t.jsx)(e.ContextMenu,{items:n,trigger:r,children:i})}exports.ChatActionsMenu=n;
2
+ //# sourceMappingURL=ChatActionsMenu.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatActionsMenu.cjs","names":[],"sources":["../../../src/components/Chat/ChatActionsMenu.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\n\nimport { ContextMenu, type ContextMenuItem } from \"../ContextMenu\";\n\nexport interface ChatActionsMenuProps {\n /** Actions for this message. */\n items: ContextMenuItem[];\n /** Which pointer gesture opens it — the bubble uses the right click, the ⋮ the left. */\n trigger: \"contextmenu\" | \"click\";\n /** The bubble, or the ⋮ button. */\n children: ReactNode;\n}\n\n/**\n * The bridge from a message to the SDK's context menu.\n *\n * A separate module, reached through `lazy()` from the bubble, because\n * `ContextMenu` pulls `Portal` and its own geometry — measured, that is 3.07 kB\n * brotli — and a support thread or a comment list passes no `messageActions` at\n * all. Keeping it behind the dynamic import is what lets a text-only thread stay\n * the size it was.\n *\n * @param props - The items, the gesture and the trigger content.\n * @returns The content wrapped in a context menu.\n */\nexport function ChatActionsMenu({ items, trigger, children }: ChatActionsMenuProps) {\n return (\n <ContextMenu items={items} trigger={trigger}>\n {children}\n </ContextMenu>\n );\n}\n"],"mappings":"qFAyBA,SAAgB,EAAgB,CAAE,QAAO,UAAS,YAAkC,CAChF,OACI,EAAA,EAAA,IAAA,CAAC,EAAA,YAAD,CAAoB,QAAgB,UAC/B,UACQ,CAAA,CAErB"}
@@ -0,0 +1,14 @@
1
+ import { ContextMenu as e } from "../ContextMenu/ContextMenu.js";
2
+ import { jsx as t } from "react/jsx-runtime";
3
+ //#region src/components/Chat/ChatActionsMenu.tsx
4
+ function n({ items: n, trigger: r, children: i }) {
5
+ return /* @__PURE__ */ t(e, {
6
+ items: n,
7
+ trigger: r,
8
+ children: i
9
+ });
10
+ }
11
+ //#endregion
12
+ export { n as ChatActionsMenu };
13
+
14
+ //# sourceMappingURL=ChatActionsMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatActionsMenu.js","names":[],"sources":["../../../src/components/Chat/ChatActionsMenu.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\n\nimport { ContextMenu, type ContextMenuItem } from \"../ContextMenu\";\n\nexport interface ChatActionsMenuProps {\n /** Actions for this message. */\n items: ContextMenuItem[];\n /** Which pointer gesture opens it — the bubble uses the right click, the ⋮ the left. */\n trigger: \"contextmenu\" | \"click\";\n /** The bubble, or the ⋮ button. */\n children: ReactNode;\n}\n\n/**\n * The bridge from a message to the SDK's context menu.\n *\n * A separate module, reached through `lazy()` from the bubble, because\n * `ContextMenu` pulls `Portal` and its own geometry — measured, that is 3.07 kB\n * brotli — and a support thread or a comment list passes no `messageActions` at\n * all. Keeping it behind the dynamic import is what lets a text-only thread stay\n * the size it was.\n *\n * @param props - The items, the gesture and the trigger content.\n * @returns The content wrapped in a context menu.\n */\nexport function ChatActionsMenu({ items, trigger, children }: ChatActionsMenuProps) {\n return (\n <ContextMenu items={items} trigger={trigger}>\n {children}\n </ContextMenu>\n );\n}\n"],"mappings":";;;AAyBA,SAAgB,EAAgB,EAAE,UAAO,YAAS,eAAkC;CAChF,OACI,kBAAC,GAAD;EAAoB;EAAgB;EAC/B;CACQ,CAAA;AAErB"}
@@ -0,0 +1,2 @@
1
+ const e=require("../../utils/numbers.cjs"),t=require("../VideoPlayer/VideoPlayer.cjs"),n=require("../Lightbox/Lightbox.cjs"),r=require("./Chat.module.cjs"),i=require("../AudioPlayer/AudioPlayer.cjs");let a=require("react"),o=require("react/jsx-runtime");var s=Array.from({length:28},()=>.25);function c(e){let t=Math.round(e/1e3),n=Math.floor(t/60),r=t%60;return`${n}:${String(r).padStart(2,`0`)}`}function l({attachments:l,strings:u}){let d=l.filter(e=>e.kind===`image`),[f,p]=(0,a.useState)(null);return(0,o.jsxs)(`div`,{className:r.default.attachments,children:[l.map((n,a)=>{let l=`${n.kind}-${n.url}-${a}`;if(n.kind===`image`){let e=d.indexOf(n);return(0,o.jsx)(`button`,{type:`button`,className:r.default.imageAttachment,onClick:()=>p(e),children:(0,o.jsx)(`img`,{src:n.thumbnailUrl??n.url,alt:n.alt??n.name??``,loading:`lazy`})},l)}return n.kind===`video`?(0,o.jsx)(t.VideoPlayer,{src:n.url,durationMs:n.durationMs,poster:n.thumbnailUrl,className:r.default.videoAttachment},l):n.kind===`voice`?(0,o.jsxs)(`div`,{className:r.default.voiceAttachment,children:[(0,o.jsx)(`div`,{className:r.default.waveform,"aria-hidden":`true`,children:(n.waveform??s).map((e,t)=>(0,o.jsx)(`span`,{style:{height:`${Math.max(8,Math.min(100,e*100))}%`}},t))}),(0,o.jsx)(i.AudioPlayer,{src:n.url,durationMs:n.durationMs,"aria-label":u.voiceNote})]},l):n.kind===`audio`?(0,o.jsx)(i.AudioPlayer,{src:n.url,durationMs:n.durationMs},l):(0,o.jsxs)(`a`,{className:r.default.fileAttachment,href:n.url,download:n.name??!0,children:[(0,o.jsx)(`span`,{className:r.default.fileName,children:n.name??u.download}),(0,o.jsx)(`span`,{className:r.default.fileMeta,children:[n.sizeBytes===void 0?null:e.formatBytes(n.sizeBytes),n.durationMs===void 0?null:c(n.durationMs)].filter(Boolean).join(` · `)})]},l)}),d.length>0&&(0,o.jsx)(n.Lightbox,{items:d.map(e=>({src:e.url,alt:e.alt??e.name??``,thumbnail:e.thumbnailUrl})),open:f!==null,index:f??0,onIndexChange:p,onClose:()=>p(null)})]})}exports.ChatAttachments=l;
2
+ //# sourceMappingURL=ChatAttachments.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatAttachments.cjs","names":[],"sources":["../../../src/components/Chat/ChatAttachments.tsx"],"sourcesContent":["import { useState } from \"react\";\n\nimport { formatBytes } from \"@/utils/numbers\";\n\nimport { AudioPlayer } from \"../AudioPlayer\";\nimport { Lightbox } from \"../Lightbox\";\nimport { VideoPlayer } from \"../VideoPlayer\";\nimport type { ChatAttachment } from \"./chat-groups\";\nimport styles from \"./Chat.module.css\";\n\n/** Strings this view needs, passed in so the locale table stays in one file. */\nexport interface ChatAttachmentStrings {\n voiceNote: string;\n download: string;\n}\n\nexport interface ChatAttachmentsProps {\n /** What this message carries. */\n attachments: readonly ChatAttachment[];\n /** Labels, from `chatStrings(locale)`. */\n strings: ChatAttachmentStrings;\n}\n\n/** Bars a voice note draws when the app gave no peaks. */\nconst FLAT_WAVEFORM = Array.from({ length: 28 }, () => 0.25);\n\n/** `1:04` from milliseconds — a duration, never a clock time. */\nfunction durationLabel(durationMs: number): string {\n const total = Math.round(durationMs / 1000);\n const minutes = Math.floor(total / 60);\n const seconds = total % 60;\n return `${minutes}:${String(seconds).padStart(2, \"0\")}`;\n}\n\n/**\n * The media half of a bubble.\n *\n * Kept in its own module, and reached through `lazy()` from the thread, because\n * it pulls three of the heaviest components in the SDK — `Lightbox`,\n * `VideoPlayer`, `AudioPlayer` — and a support thread of plain text should not\n * pay for a photo viewer it never opens. The thread renders it only for messages\n * that actually carry an attachment, so that chunk is requested the first time\n * one appears.\n *\n * Nothing here is new UI: an image opens the SDK's lightbox, a video and an audio\n * clip use the SDK's players, and a file is a download row. That composition is\n * the whole point — every app was writing it again, the same way.\n *\n * @param props - The attachments and the locale strings.\n * @returns The rendered attachment list.\n */\nexport function ChatAttachments({ attachments, strings }: ChatAttachmentsProps) {\n const images = attachments.filter((attachment) => attachment.kind === \"image\");\n const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);\n\n return (\n <div className={styles.attachments}>\n {attachments.map((attachment, index) => {\n const key = `${attachment.kind}-${attachment.url}-${index}`;\n if (attachment.kind === \"image\") {\n const position = images.indexOf(attachment);\n return (\n <button\n key={key}\n type=\"button\"\n className={styles.imageAttachment}\n onClick={() => setLightboxIndex(position)}\n >\n <img\n src={attachment.thumbnailUrl ?? attachment.url}\n alt={attachment.alt ?? attachment.name ?? \"\"}\n loading=\"lazy\"\n />\n </button>\n );\n }\n if (attachment.kind === \"video\") {\n return (\n <VideoPlayer\n key={key}\n src={attachment.url}\n durationMs={attachment.durationMs}\n poster={attachment.thumbnailUrl}\n className={styles.videoAttachment}\n />\n );\n }\n if (attachment.kind === \"voice\") {\n return (\n <div key={key} className={styles.voiceAttachment}>\n <div className={styles.waveform} aria-hidden=\"true\">\n {(attachment.waveform ?? FLAT_WAVEFORM).map((peak, bar) => (\n <span\n key={bar}\n style={{\n height: `${Math.max(8, Math.min(100, peak * 100))}%`,\n }}\n />\n ))}\n </div>\n <AudioPlayer\n src={attachment.url}\n durationMs={attachment.durationMs}\n aria-label={strings.voiceNote}\n />\n </div>\n );\n }\n if (attachment.kind === \"audio\") {\n return (\n <AudioPlayer\n key={key}\n src={attachment.url}\n durationMs={attachment.durationMs}\n />\n );\n }\n return (\n <a\n key={key}\n className={styles.fileAttachment}\n href={attachment.url}\n download={attachment.name ?? true}\n >\n <span className={styles.fileName}>\n {attachment.name ?? strings.download}\n </span>\n <span className={styles.fileMeta}>\n {[\n attachment.sizeBytes !== undefined\n ? formatBytes(attachment.sizeBytes)\n : null,\n attachment.durationMs !== undefined\n ? durationLabel(attachment.durationMs)\n : null,\n ]\n .filter(Boolean)\n .join(\" · \")}\n </span>\n </a>\n );\n })}\n\n {images.length > 0 && (\n <Lightbox\n items={images.map((image) => ({\n src: image.url,\n alt: image.alt ?? image.name ?? \"\",\n thumbnail: image.thumbnailUrl,\n }))}\n open={lightboxIndex !== null}\n index={lightboxIndex ?? 0}\n onIndexChange={setLightboxIndex}\n onClose={() => setLightboxIndex(null)}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import { formatBytes as e } from "../../utils/numbers.js";
2
+ import { VideoPlayer as t } from "../VideoPlayer/VideoPlayer.js";
3
+ import { Lightbox as n } from "../Lightbox/Lightbox.js";
4
+ import r from "./Chat.module.js";
5
+ import { AudioPlayer as i } from "../AudioPlayer/AudioPlayer.js";
6
+ import { useState as a } from "react";
7
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
8
+ //#region src/components/Chat/ChatAttachments.tsx
9
+ var c = Array.from({ length: 28 }, () => .25);
10
+ function l(e) {
11
+ let t = Math.round(e / 1e3), n = Math.floor(t / 60), r = t % 60;
12
+ return `${n}:${String(r).padStart(2, "0")}`;
13
+ }
14
+ function u({ attachments: u, strings: d }) {
15
+ let f = u.filter((e) => e.kind === "image"), [p, m] = a(null);
16
+ return /* @__PURE__ */ s("div", {
17
+ className: r.attachments,
18
+ children: [u.map((n, a) => {
19
+ let u = `${n.kind}-${n.url}-${a}`;
20
+ if (n.kind === "image") {
21
+ let e = f.indexOf(n);
22
+ return /* @__PURE__ */ o("button", {
23
+ type: "button",
24
+ className: r.imageAttachment,
25
+ onClick: () => m(e),
26
+ children: /* @__PURE__ */ o("img", {
27
+ src: n.thumbnailUrl ?? n.url,
28
+ alt: n.alt ?? n.name ?? "",
29
+ loading: "lazy"
30
+ })
31
+ }, u);
32
+ }
33
+ return n.kind === "video" ? /* @__PURE__ */ o(t, {
34
+ src: n.url,
35
+ durationMs: n.durationMs,
36
+ poster: n.thumbnailUrl,
37
+ className: r.videoAttachment
38
+ }, u) : n.kind === "voice" ? /* @__PURE__ */ s("div", {
39
+ className: r.voiceAttachment,
40
+ children: [/* @__PURE__ */ o("div", {
41
+ className: r.waveform,
42
+ "aria-hidden": "true",
43
+ children: (n.waveform ?? c).map((e, t) => /* @__PURE__ */ o("span", { style: { height: `${Math.max(8, Math.min(100, e * 100))}%` } }, t))
44
+ }), /* @__PURE__ */ o(i, {
45
+ src: n.url,
46
+ durationMs: n.durationMs,
47
+ "aria-label": d.voiceNote
48
+ })]
49
+ }, u) : n.kind === "audio" ? /* @__PURE__ */ o(i, {
50
+ src: n.url,
51
+ durationMs: n.durationMs
52
+ }, u) : /* @__PURE__ */ s("a", {
53
+ className: r.fileAttachment,
54
+ href: n.url,
55
+ download: n.name ?? !0,
56
+ children: [/* @__PURE__ */ o("span", {
57
+ className: r.fileName,
58
+ children: n.name ?? d.download
59
+ }), /* @__PURE__ */ o("span", {
60
+ className: r.fileMeta,
61
+ children: [n.sizeBytes === void 0 ? null : e(n.sizeBytes), n.durationMs === void 0 ? null : l(n.durationMs)].filter(Boolean).join(" · ")
62
+ })]
63
+ }, u);
64
+ }), f.length > 0 && /* @__PURE__ */ o(n, {
65
+ items: f.map((e) => ({
66
+ src: e.url,
67
+ alt: e.alt ?? e.name ?? "",
68
+ thumbnail: e.thumbnailUrl
69
+ })),
70
+ open: p !== null,
71
+ index: p ?? 0,
72
+ onIndexChange: m,
73
+ onClose: () => m(null)
74
+ })]
75
+ });
76
+ }
77
+ //#endregion
78
+ export { u as ChatAttachments };
79
+
80
+ //# sourceMappingURL=ChatAttachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatAttachments.js","names":[],"sources":["../../../src/components/Chat/ChatAttachments.tsx"],"sourcesContent":["import { useState } from \"react\";\n\nimport { formatBytes } from \"@/utils/numbers\";\n\nimport { AudioPlayer } from \"../AudioPlayer\";\nimport { Lightbox } from \"../Lightbox\";\nimport { VideoPlayer } from \"../VideoPlayer\";\nimport type { ChatAttachment } from \"./chat-groups\";\nimport styles from \"./Chat.module.css\";\n\n/** Strings this view needs, passed in so the locale table stays in one file. */\nexport interface ChatAttachmentStrings {\n voiceNote: string;\n download: string;\n}\n\nexport interface ChatAttachmentsProps {\n /** What this message carries. */\n attachments: readonly ChatAttachment[];\n /** Labels, from `chatStrings(locale)`. */\n strings: ChatAttachmentStrings;\n}\n\n/** Bars a voice note draws when the app gave no peaks. */\nconst FLAT_WAVEFORM = Array.from({ length: 28 }, () => 0.25);\n\n/** `1:04` from milliseconds — a duration, never a clock time. */\nfunction durationLabel(durationMs: number): string {\n const total = Math.round(durationMs / 1000);\n const minutes = Math.floor(total / 60);\n const seconds = total % 60;\n return `${minutes}:${String(seconds).padStart(2, \"0\")}`;\n}\n\n/**\n * The media half of a bubble.\n *\n * Kept in its own module, and reached through `lazy()` from the thread, because\n * it pulls three of the heaviest components in the SDK — `Lightbox`,\n * `VideoPlayer`, `AudioPlayer` — and a support thread of plain text should not\n * pay for a photo viewer it never opens. The thread renders it only for messages\n * that actually carry an attachment, so that chunk is requested the first time\n * one appears.\n *\n * Nothing here is new UI: an image opens the SDK's lightbox, a video and an audio\n * clip use the SDK's players, and a file is a download row. That composition is\n * the whole point — every app was writing it again, the same way.\n *\n * @param props - The attachments and the locale strings.\n * @returns The rendered attachment list.\n */\nexport function ChatAttachments({ attachments, strings }: ChatAttachmentsProps) {\n const images = attachments.filter((attachment) => attachment.kind === \"image\");\n const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);\n\n return (\n <div className={styles.attachments}>\n {attachments.map((attachment, index) => {\n const key = `${attachment.kind}-${attachment.url}-${index}`;\n if (attachment.kind === \"image\") {\n const position = images.indexOf(attachment);\n return (\n <button\n key={key}\n type=\"button\"\n className={styles.imageAttachment}\n onClick={() => setLightboxIndex(position)}\n >\n <img\n src={attachment.thumbnailUrl ?? attachment.url}\n alt={attachment.alt ?? attachment.name ?? \"\"}\n loading=\"lazy\"\n />\n </button>\n );\n }\n if (attachment.kind === \"video\") {\n return (\n <VideoPlayer\n key={key}\n src={attachment.url}\n durationMs={attachment.durationMs}\n poster={attachment.thumbnailUrl}\n className={styles.videoAttachment}\n />\n );\n }\n if (attachment.kind === \"voice\") {\n return (\n <div key={key} className={styles.voiceAttachment}>\n <div className={styles.waveform} aria-hidden=\"true\">\n {(attachment.waveform ?? FLAT_WAVEFORM).map((peak, bar) => (\n <span\n key={bar}\n style={{\n height: `${Math.max(8, Math.min(100, peak * 100))}%`,\n }}\n />\n ))}\n </div>\n <AudioPlayer\n src={attachment.url}\n durationMs={attachment.durationMs}\n aria-label={strings.voiceNote}\n />\n </div>\n );\n }\n if (attachment.kind === \"audio\") {\n return (\n <AudioPlayer\n key={key}\n src={attachment.url}\n durationMs={attachment.durationMs}\n />\n );\n }\n return (\n <a\n key={key}\n className={styles.fileAttachment}\n href={attachment.url}\n download={attachment.name ?? true}\n >\n <span className={styles.fileName}>\n {attachment.name ?? strings.download}\n </span>\n <span className={styles.fileMeta}>\n {[\n attachment.sizeBytes !== undefined\n ? formatBytes(attachment.sizeBytes)\n : null,\n attachment.durationMs !== undefined\n ? durationLabel(attachment.durationMs)\n : null,\n ]\n .filter(Boolean)\n .join(\" · \")}\n </span>\n </a>\n );\n })}\n\n {images.length > 0 && (\n <Lightbox\n items={images.map((image) => ({\n src: image.url,\n alt: image.alt ?? image.name ?? \"\",\n thumbnail: image.thumbnailUrl,\n }))}\n open={lightboxIndex !== null}\n index={lightboxIndex ?? 0}\n onIndexChange={setLightboxIndex}\n onClose={() => setLightboxIndex(null)}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAwBA,IAAM,IAAgB,MAAM,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAI;AAG3D,SAAS,EAAc,GAA4B;CAC/C,IAAM,IAAQ,KAAK,MAAM,IAAa,GAAI,GACpC,IAAU,KAAK,MAAM,IAAQ,EAAE,GAC/B,IAAU,IAAQ;CACxB,OAAO,GAAG,EAAQ,GAAG,OAAO,CAAO,CAAC,CAAC,SAAS,GAAG,GAAG;AACxD;AAmBA,SAAgB,EAAgB,EAAE,gBAAa,cAAiC;CAC5E,IAAM,IAAS,EAAY,QAAQ,MAAe,EAAW,SAAS,OAAO,GACvE,CAAC,GAAe,KAAoB,EAAwB,IAAI;CAEtE,OACI,kBAAC,OAAD;EAAK,WAAW,EAAO;EAAvB,UAAA,CACK,EAAY,KAAK,GAAY,MAAU;GACpC,IAAM,IAAM,GAAG,EAAW,KAAK,GAAG,EAAW,IAAI,GAAG;GACpD,IAAI,EAAW,SAAS,SAAS;IAC7B,IAAM,IAAW,EAAO,QAAQ,CAAU;IAC1C,OACI,kBAAC,UAAD;KAEI,MAAK;KACL,WAAW,EAAO;KAClB,eAAe,EAAiB,CAAQ;KAExC,UAAA,kBAAC,OAAD;MACI,KAAK,EAAW,gBAAgB,EAAW;MAC3C,KAAK,EAAW,OAAO,EAAW,QAAQ;MAC1C,SAAQ;KACX,CAAA;IACG,GAVC,CAUD;GAEhB;GA0CA,OAzCI,EAAW,SAAS,UAEhB,kBAAC,GAAD;IAEI,KAAK,EAAW;IAChB,YAAY,EAAW;IACvB,QAAQ,EAAW;IACnB,WAAW,EAAO;GACrB,GALQ,CAKR,IAGL,EAAW,SAAS,UAEhB,kBAAC,OAAD;IAAe,WAAW,EAAO;IAAjC,UAAA,CACI,kBAAC,OAAD;KAAK,WAAW,EAAO;KAAU,eAAY;KACvC,WAAA,EAAW,YAAY,EAAA,CAAe,KAAK,GAAM,MAC/C,kBAAC,QAAD,EAEI,OAAO,EACH,QAAQ,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAO,GAAG,CAAC,EAAE,GACtD,EACH,GAJQ,CAIR,CACJ;IACA,CAAA,GACL,kBAAC,GAAD;KACI,KAAK,EAAW;KAChB,YAAY,EAAW;KACvB,cAAY,EAAQ;IACvB,CAAA,CACA;GAhBK,GAAA,CAgBL,IAGT,EAAW,SAAS,UAEhB,kBAAC,GAAD;IAEI,KAAK,EAAW;IAChB,YAAY,EAAW;GAC1B,GAHQ,CAGR,IAIL,kBAAC,KAAD;IAEI,WAAW,EAAO;IAClB,MAAM,EAAW;IACjB,UAAU,EAAW,QAAQ;IAJjC,UAAA,CAMI,kBAAC,QAAD;KAAM,WAAW,EAAO;KACnB,UAAA,EAAW,QAAQ,EAAQ;IAC1B,CAAA,GACN,kBAAC,QAAD;KAAM,WAAW,EAAO;KACnB,UAAA,CACG,EAAW,cAAc,KAAA,IAEnB,OADA,EAAY,EAAW,SAAS,GAEtC,EAAW,eAAe,KAAA,IAEpB,OADA,EAAc,EAAW,UAAU,CAE7C,CAAC,CACI,OAAO,OAAO,CAAC,CACf,KAAK,KAAK;IACb,CAAA,CACP;GApBM,GAAA,CAoBN;EAEX,CAAC,GAEA,EAAO,SAAS,KACb,kBAAC,GAAD;GACI,OAAO,EAAO,KAAK,OAAW;IAC1B,KAAK,EAAM;IACX,KAAK,EAAM,OAAO,EAAM,QAAQ;IAChC,WAAW,EAAM;GACrB,EAAE;GACF,MAAM,MAAkB;GACxB,OAAO,KAAiB;GACxB,eAAe;GACf,eAAe,EAAiB,IAAI;EACvC,CAAA,CAEJ;;AAEb"}
@@ -0,0 +1,2 @@
1
+ const e=require("../../utils/cn.cjs"),t=require("../VisuallyHidden/VisuallyHidden.cjs"),n=require("./chat-groups.cjs"),r=require("./chat-receipt.cjs"),i=require("./Chat.module.cjs");let a=require("react"),o=require("react/jsx-runtime");var s=(0,a.lazy)(()=>Promise.resolve().then(()=>require("./ChatAttachments.cjs")).then(e=>({default:e.ChatAttachments}))),c=(0,a.lazy)(()=>Promise.resolve().then(()=>require("./ChatActionsMenu.cjs")).then(e=>({default:e.ChatActionsMenu}))),l={sending:`◌`,sent:`✓`,delivered:`✓✓`,read:`✓✓`,failed:`!`};function u({message:l,own:u,locale:p,onRetry:m,onReact:h,messageActions:g,onQuoteClick:_}){let v=n.chatStrings(p),y=u?r.resolveReceiptState(l):null,b=l.deleted?[]:g?.(l)??[],x=(0,o.jsxs)(`div`,{className:e.cn(i.default.bubble,u&&i.default.ownBubble,l.deleted&&i.default.deletedBubble,l.status===`failed`&&i.default.failedBubble),children:[l.quote&&!l.deleted&&(0,o.jsx)(d,{message:l,locale:p,onQuoteClick:_}),l.deleted?(0,o.jsxs)(`div`,{className:i.default.tombstone,children:[(0,o.jsx)(`span`,{"aria-hidden":`true`,children:`🚫`}),` `,v.deleted]}):(0,o.jsxs)(o.Fragment,{children:[l.attachments&&l.attachments.length>0&&(0,o.jsx)(a.Suspense,{fallback:(0,o.jsx)(`div`,{className:i.default.attachmentsFallback}),children:(0,o.jsx)(s,{attachments:l.attachments,strings:v})}),l.body!==void 0&&l.body!==null&&l.body!==``&&(0,o.jsx)(`div`,{className:i.default.body,children:l.body})]}),(0,o.jsxs)(`div`,{className:i.default.meta,children:[l.edited&&!l.deleted&&(0,o.jsx)(`span`,{className:i.default.edited,children:v.edited}),(0,o.jsx)(`time`,{dateTime:new Date(l.sentAt).toISOString(),children:n.timeLabel(l.sentAt,p)}),y&&(0,o.jsx)(f,{message:l,state:y,locale:p})]})]});return(0,o.jsxs)(`li`,{className:i.default.bubbleRow,children:[b.length>0?(0,o.jsx)(a.Suspense,{fallback:x,children:(0,o.jsx)(c,{items:b,trigger:`contextmenu`,children:x})}):x,b.length>0&&(0,o.jsx)(a.Suspense,{fallback:null,children:(0,o.jsx)(c,{items:b,trigger:`click`,children:(0,o.jsx)(`button`,{type:`button`,className:i.default.actionsButton,"aria-label":v.messageActions,children:(0,o.jsx)(`span`,{"aria-hidden":`true`,children:`⋮`})})})}),l.reactions&&l.reactions.length>0&&(0,o.jsx)(`ul`,{className:i.default.reactions,"aria-label":v.reactions,children:l.reactions.map(n=>(0,o.jsx)(`li`,{children:(0,o.jsxs)(`button`,{type:`button`,className:e.cn(i.default.reaction,n.reacted&&i.default.reactionMine),"aria-pressed":n.reacted??!1,title:n.names?.join(`, `),disabled:!h,onClick:()=>h?.(l,n.emoji),children:[(0,o.jsxs)(`span`,{"aria-hidden":`true`,children:[n.emoji,` `,n.count]}),(0,o.jsx)(t.VisuallyHidden,{children:v.react(n.emoji,n.count)})]})},n.emoji))}),l.status===`failed`&&m&&(0,o.jsx)(`button`,{type:`button`,className:i.default.retry,onClick:()=>m(l),children:v.retry})]})}function d({message:t,locale:r,onQuoteClick:a}){let s=n.chatStrings(r),c=t.quote;if(!c)return null;let l=c.revoked?s.quoteRevoked:c.excerpt??(c.kind&&c.kind!==`text`?s.quoteKind[c.kind]:``),u=(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(`span`,{className:i.default.quoteAuthor,children:c.senderName??s.replyingTo(c.messageId)}),(0,o.jsx)(`span`,{className:e.cn(i.default.quoteText,c.revoked&&i.default.quoteRevoked),children:l})]});return a?(0,o.jsx)(`button`,{type:`button`,className:e.cn(i.default.quote,i.default.quoteButton),onClick:()=>a(t),children:u}):(0,o.jsx)(`div`,{className:i.default.quote,children:u})}function f({message:a,state:s,locale:c}){let u=n.chatStrings(c),d=a.receipt&&a.receipt.totalRecipients>0&&s!==`failed`?r.receiptLabel(a.receipt,u):u[s===`delivered`?`sent`:s];return(0,o.jsxs)(`span`,{className:e.cn(i.default.status,s===`read`&&i.default.statusRead,s===`failed`&&i.default.statusFailed),title:d,children:[(0,o.jsx)(`span`,{"aria-hidden":`true`,children:l[s]}),(0,o.jsx)(t.VisuallyHidden,{children:d})]})}exports.ChatBubble=u;
2
+ //# sourceMappingURL=ChatBubble.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatBubble.cjs","names":[],"sources":["../../../src/components/Chat/ChatBubble.tsx"],"sourcesContent":["/**\n * @tempest-limits file-lines props-count function-lines — one bubble is one unit of\n * layout, and every part of it reads from the same message: the quote above the\n * body, the body or its tombstone, the attachments, the reactions under it, and the\n * timestamp with its ticks. Splitting them would pass the same message to six\n * components and put the bubble's geometry in none of them.\n */\nimport { Suspense, lazy, type ReactNode } from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nimport type { ContextMenuItem } from \"../ContextMenu\";\nimport { VisuallyHidden } from \"../VisuallyHidden\";\nimport { chatStrings, timeLabel, type ChatMessage } from \"./chat-groups\";\nimport { receiptLabel, resolveReceiptState } from \"./chat-receipt\";\nimport styles from \"./Chat.module.css\";\n\nconst ChatAttachments = lazy(() =>\n import(\"./ChatAttachments\").then((module) => ({ default: module.ChatAttachments })),\n);\n\nconst ChatActionsMenu = lazy(() =>\n import(\"./ChatActionsMenu\").then((module) => ({ default: module.ChatActionsMenu })),\n);\n\n/** Glyph per tick state. `delivered` is the one a boolean `status` cannot say. */\nconst RECEIPT_GLYPH = {\n sending: \"◌\",\n sent: \"✓\",\n delivered: \"✓✓\",\n read: \"✓✓\",\n failed: \"!\",\n} as const;\n\nexport interface ChatBubbleProps {\n /** The message this bubble renders. */\n message: ChatMessage;\n /** Whether it belongs to the current user — side, colour and ticks. */\n own: boolean;\n /** Locale for labels. */\n locale: \"pt-BR\" | \"en\";\n /** Retry handler for a `\"failed\"` message. */\n onRetry?: (message: ChatMessage) => void;\n /** Toggles a reaction. Receives the emoji that was pressed. */\n onReact?: (message: ChatMessage, emoji: string) => void;\n /** Per-message actions, opened by right click, long press or the ⋮ button. */\n messageActions?: (message: ChatMessage) => ContextMenuItem[];\n /** Called when the quote stub is activated — scroll to the quoted message. */\n onQuoteClick?: (message: ChatMessage) => void;\n}\n\n/**\n * One message bubble.\n *\n * Everything a messenger needs on a single message lives here, because every one\n * of these was a thing each app rebuilt on top of a text-only bubble: the reply\n * stub, attachments, reactions, per-recipient ticks, the actions menu, and the\n * tombstone of a deleted message.\n *\n * @param props - The message and its handlers.\n * @returns The bubble, wrapped in a context menu when actions are given.\n */\nexport function ChatBubble({\n message,\n own,\n locale,\n onRetry,\n onReact,\n messageActions,\n onQuoteClick,\n}: ChatBubbleProps) {\n const strings = chatStrings(locale);\n const receiptState = own ? resolveReceiptState(message) : null;\n const actions = message.deleted ? [] : (messageActions?.(message) ?? []);\n\n const bubble = (\n <div\n className={cn(\n styles.bubble,\n own && styles.ownBubble,\n message.deleted && styles.deletedBubble,\n message.status === \"failed\" && styles.failedBubble,\n )}\n >\n {message.quote && !message.deleted && (\n <QuoteStub message={message} locale={locale} onQuoteClick={onQuoteClick} />\n )}\n\n {message.deleted ? (\n <div className={styles.tombstone}>\n <span aria-hidden=\"true\">🚫</span> {strings.deleted}\n </div>\n ) : (\n <>\n {message.attachments && message.attachments.length > 0 && (\n <Suspense fallback={<div className={styles.attachmentsFallback} />}>\n <ChatAttachments attachments={message.attachments} strings={strings} />\n </Suspense>\n )}\n {message.body !== undefined && message.body !== null && message.body !== \"\" && (\n <div className={styles.body}>{message.body}</div>\n )}\n </>\n )}\n\n <div className={styles.meta}>\n {message.edited && !message.deleted && (\n <span className={styles.edited}>{strings.edited}</span>\n )}\n <time dateTime={new Date(message.sentAt).toISOString()}>\n {timeLabel(message.sentAt, locale)}\n </time>\n {receiptState && <Receipt message={message} state={receiptState} locale={locale} />}\n </div>\n </div>\n );\n\n return (\n <li className={styles.bubbleRow}>\n {actions.length > 0 ? (\n <Suspense fallback={bubble}>\n <ChatActionsMenu items={actions} trigger=\"contextmenu\">\n {bubble}\n </ChatActionsMenu>\n </Suspense>\n ) : (\n bubble\n )}\n\n {actions.length > 0 && (\n <Suspense fallback={null}>\n <ChatActionsMenu items={actions} trigger=\"click\">\n <button\n type=\"button\"\n className={styles.actionsButton}\n aria-label={strings.messageActions}\n >\n <span aria-hidden=\"true\">⋮</span>\n </button>\n </ChatActionsMenu>\n </Suspense>\n )}\n\n {message.reactions && message.reactions.length > 0 && (\n <ul className={styles.reactions} aria-label={strings.reactions}>\n {message.reactions.map((reaction) => (\n <li key={reaction.emoji}>\n <button\n type=\"button\"\n className={cn(\n styles.reaction,\n reaction.reacted && styles.reactionMine,\n )}\n aria-pressed={reaction.reacted ?? false}\n title={reaction.names?.join(\", \")}\n disabled={!onReact}\n onClick={() => onReact?.(message, reaction.emoji)}\n >\n <span aria-hidden=\"true\">\n {reaction.emoji} {reaction.count}\n </span>\n <VisuallyHidden>\n {strings.react(reaction.emoji, reaction.count)}\n </VisuallyHidden>\n </button>\n </li>\n ))}\n </ul>\n )}\n\n {message.status === \"failed\" && onRetry && (\n <button type=\"button\" className={styles.retry} onClick={() => onRetry(message)}>\n {strings.retry}\n </button>\n )}\n </li>\n );\n}\n\n/** The reply stub above a body, or its blanked form once the target is gone. */\nfunction QuoteStub({\n message,\n locale,\n onQuoteClick,\n}: {\n message: ChatMessage;\n locale: \"pt-BR\" | \"en\";\n onQuoteClick?: (message: ChatMessage) => void;\n}): ReactNode {\n const strings = chatStrings(locale);\n const quote = message.quote;\n if (!quote) return null;\n const label = quote.revoked\n ? strings.quoteRevoked\n : (quote.excerpt ??\n (quote.kind && quote.kind !== \"text\" ? strings.quoteKind[quote.kind] : \"\"));\n\n const content = (\n <>\n <span className={styles.quoteAuthor}>\n {quote.senderName ?? strings.replyingTo(quote.messageId)}\n </span>\n <span className={cn(styles.quoteText, quote.revoked && styles.quoteRevoked)}>\n {label}\n </span>\n </>\n );\n\n return onQuoteClick ? (\n <button\n type=\"button\"\n className={cn(styles.quote, styles.quoteButton)}\n onClick={() => onQuoteClick(message)}\n >\n {content}\n </button>\n ) : (\n <div className={styles.quote}>{content}</div>\n );\n}\n\n/** The ticks, and the sentence behind them. */\nfunction Receipt({\n message,\n state,\n locale,\n}: {\n message: ChatMessage;\n state: keyof typeof RECEIPT_GLYPH;\n locale: \"pt-BR\" | \"en\";\n}): ReactNode {\n const strings = chatStrings(locale);\n const label =\n message.receipt && message.receipt.totalRecipients > 0 && state !== \"failed\"\n ? receiptLabel(message.receipt, strings)\n : strings[state === \"delivered\" ? \"sent\" : state];\n\n return (\n <span\n className={cn(\n styles.status,\n state === \"read\" && styles.statusRead,\n state === \"failed\" && styles.statusFailed,\n )}\n title={label}\n >\n <span aria-hidden=\"true\">{RECEIPT_GLYPH[state]}</span>\n <VisuallyHidden>{label}</VisuallyHidden>\n </span>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,155 @@
1
+ import { cn as e } from "../../utils/cn.js";
2
+ import { VisuallyHidden as t } from "../VisuallyHidden/VisuallyHidden.js";
3
+ import { chatStrings as n, timeLabel as r } from "./chat-groups.js";
4
+ import { receiptLabel as i, resolveReceiptState as a } from "./chat-receipt.js";
5
+ import o from "./Chat.module.js";
6
+ import { Suspense as s, lazy as c } from "react";
7
+ import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
8
+ //#region src/components/Chat/ChatBubble.tsx
9
+ var f = c(() => import("./ChatAttachments.js").then((e) => ({ default: e.ChatAttachments }))), p = c(() => import("./ChatActionsMenu.js").then((e) => ({ default: e.ChatActionsMenu }))), m = {
10
+ sending: "◌",
11
+ sent: "✓",
12
+ delivered: "✓✓",
13
+ read: "✓✓",
14
+ failed: "!"
15
+ };
16
+ function h({ message: i, own: c, locale: m, onRetry: h, onReact: v, messageActions: y, onQuoteClick: b }) {
17
+ let x = n(m), S = c ? a(i) : null, C = i.deleted ? [] : y?.(i) ?? [], w = /* @__PURE__ */ d("div", {
18
+ className: e(o.bubble, c && o.ownBubble, i.deleted && o.deletedBubble, i.status === "failed" && o.failedBubble),
19
+ children: [
20
+ i.quote && !i.deleted && /* @__PURE__ */ u(g, {
21
+ message: i,
22
+ locale: m,
23
+ onQuoteClick: b
24
+ }),
25
+ i.deleted ? /* @__PURE__ */ d("div", {
26
+ className: o.tombstone,
27
+ children: [
28
+ /* @__PURE__ */ u("span", {
29
+ "aria-hidden": "true",
30
+ children: "🚫"
31
+ }),
32
+ " ",
33
+ x.deleted
34
+ ]
35
+ }) : /* @__PURE__ */ d(l, { children: [i.attachments && i.attachments.length > 0 && /* @__PURE__ */ u(s, {
36
+ fallback: /* @__PURE__ */ u("div", { className: o.attachmentsFallback }),
37
+ children: /* @__PURE__ */ u(f, {
38
+ attachments: i.attachments,
39
+ strings: x
40
+ })
41
+ }), i.body !== void 0 && i.body !== null && i.body !== "" && /* @__PURE__ */ u("div", {
42
+ className: o.body,
43
+ children: i.body
44
+ })] }),
45
+ /* @__PURE__ */ d("div", {
46
+ className: o.meta,
47
+ children: [
48
+ i.edited && !i.deleted && /* @__PURE__ */ u("span", {
49
+ className: o.edited,
50
+ children: x.edited
51
+ }),
52
+ /* @__PURE__ */ u("time", {
53
+ dateTime: new Date(i.sentAt).toISOString(),
54
+ children: r(i.sentAt, m)
55
+ }),
56
+ S && /* @__PURE__ */ u(_, {
57
+ message: i,
58
+ state: S,
59
+ locale: m
60
+ })
61
+ ]
62
+ })
63
+ ]
64
+ });
65
+ return /* @__PURE__ */ d("li", {
66
+ className: o.bubbleRow,
67
+ children: [
68
+ C.length > 0 ? /* @__PURE__ */ u(s, {
69
+ fallback: w,
70
+ children: /* @__PURE__ */ u(p, {
71
+ items: C,
72
+ trigger: "contextmenu",
73
+ children: w
74
+ })
75
+ }) : w,
76
+ C.length > 0 && /* @__PURE__ */ u(s, {
77
+ fallback: null,
78
+ children: /* @__PURE__ */ u(p, {
79
+ items: C,
80
+ trigger: "click",
81
+ children: /* @__PURE__ */ u("button", {
82
+ type: "button",
83
+ className: o.actionsButton,
84
+ "aria-label": x.messageActions,
85
+ children: /* @__PURE__ */ u("span", {
86
+ "aria-hidden": "true",
87
+ children: "⋮"
88
+ })
89
+ })
90
+ })
91
+ }),
92
+ i.reactions && i.reactions.length > 0 && /* @__PURE__ */ u("ul", {
93
+ className: o.reactions,
94
+ "aria-label": x.reactions,
95
+ children: i.reactions.map((n) => /* @__PURE__ */ u("li", { children: /* @__PURE__ */ d("button", {
96
+ type: "button",
97
+ className: e(o.reaction, n.reacted && o.reactionMine),
98
+ "aria-pressed": n.reacted ?? !1,
99
+ title: n.names?.join(", "),
100
+ disabled: !v,
101
+ onClick: () => v?.(i, n.emoji),
102
+ children: [/* @__PURE__ */ d("span", {
103
+ "aria-hidden": "true",
104
+ children: [
105
+ n.emoji,
106
+ " ",
107
+ n.count
108
+ ]
109
+ }), /* @__PURE__ */ u(t, { children: x.react(n.emoji, n.count) })]
110
+ }) }, n.emoji))
111
+ }),
112
+ i.status === "failed" && h && /* @__PURE__ */ u("button", {
113
+ type: "button",
114
+ className: o.retry,
115
+ onClick: () => h(i),
116
+ children: x.retry
117
+ })
118
+ ]
119
+ });
120
+ }
121
+ function g({ message: t, locale: r, onQuoteClick: i }) {
122
+ let a = n(r), s = t.quote;
123
+ if (!s) return null;
124
+ let c = s.revoked ? a.quoteRevoked : s.excerpt ?? (s.kind && s.kind !== "text" ? a.quoteKind[s.kind] : ""), f = /* @__PURE__ */ d(l, { children: [/* @__PURE__ */ u("span", {
125
+ className: o.quoteAuthor,
126
+ children: s.senderName ?? a.replyingTo(s.messageId)
127
+ }), /* @__PURE__ */ u("span", {
128
+ className: e(o.quoteText, s.revoked && o.quoteRevoked),
129
+ children: c
130
+ })] });
131
+ return i ? /* @__PURE__ */ u("button", {
132
+ type: "button",
133
+ className: e(o.quote, o.quoteButton),
134
+ onClick: () => i(t),
135
+ children: f
136
+ }) : /* @__PURE__ */ u("div", {
137
+ className: o.quote,
138
+ children: f
139
+ });
140
+ }
141
+ function _({ message: r, state: a, locale: s }) {
142
+ let c = n(s), l = r.receipt && r.receipt.totalRecipients > 0 && a !== "failed" ? i(r.receipt, c) : c[a === "delivered" ? "sent" : a];
143
+ return /* @__PURE__ */ d("span", {
144
+ className: e(o.status, a === "read" && o.statusRead, a === "failed" && o.statusFailed),
145
+ title: l,
146
+ children: [/* @__PURE__ */ u("span", {
147
+ "aria-hidden": "true",
148
+ children: m[a]
149
+ }), /* @__PURE__ */ u(t, { children: l })]
150
+ });
151
+ }
152
+ //#endregion
153
+ export { h as ChatBubble };
154
+
155
+ //# sourceMappingURL=ChatBubble.js.map