@rojaostudio/ds 1.0.1 → 2.0.0-next.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 (403) hide show
  1. package/README.md +75 -13
  2. package/dist/compat/generate.d.ts +0 -1
  3. package/dist/components/accordion.d.ts +30 -20
  4. package/dist/components/accordion.js +31 -87
  5. package/dist/components/action-bar.d.ts +24 -0
  6. package/dist/components/action-bar.js +55 -0
  7. package/dist/components/alert-dialog.d.ts +31 -0
  8. package/dist/components/alert-dialog.js +43 -0
  9. package/dist/components/alert.d.ts +31 -19
  10. package/dist/components/alert.js +74 -65
  11. package/dist/components/attachment.d.ts +37 -0
  12. package/dist/components/attachment.js +76 -0
  13. package/dist/components/avatar.d.ts +43 -36
  14. package/dist/components/avatar.js +59 -83
  15. package/dist/components/badge.d.ts +30 -41
  16. package/dist/components/badge.js +16 -106
  17. package/dist/components/banner.d.ts +27 -0
  18. package/dist/components/banner.js +66 -0
  19. package/dist/components/benefits.d.ts +30 -0
  20. package/dist/components/benefits.js +32 -0
  21. package/dist/components/breadcrumb.d.ts +25 -18
  22. package/dist/components/breadcrumb.js +40 -48
  23. package/dist/components/browser.d.ts +18 -0
  24. package/dist/components/browser.js +32 -0
  25. package/dist/components/bubble.d.ts +29 -0
  26. package/dist/components/bubble.js +33 -0
  27. package/dist/components/button-group.d.ts +19 -0
  28. package/dist/components/button-group.js +20 -0
  29. package/dist/components/button.d.ts +47 -20
  30. package/dist/components/button.js +51 -107
  31. package/dist/components/calendar.d.ts +29 -0
  32. package/dist/components/calendar.js +149 -0
  33. package/dist/components/card.d.ts +47 -19
  34. package/dist/components/card.js +38 -38
  35. package/dist/components/carousel.d.ts +28 -0
  36. package/dist/components/carousel.js +130 -0
  37. package/dist/components/chart.d.ts +49 -0
  38. package/dist/components/chart.js +258 -0
  39. package/dist/components/checkbox-group.d.ts +16 -0
  40. package/dist/components/checkbox-group.js +13 -0
  41. package/dist/components/checkbox.d.ts +25 -10
  42. package/dist/components/checkbox.js +86 -67
  43. package/dist/components/chip-input.d.ts +46 -20
  44. package/dist/components/chip-input.js +171 -158
  45. package/dist/components/chip.d.ts +28 -0
  46. package/dist/components/chip.js +73 -0
  47. package/dist/components/choice-card.d.ts +10 -13
  48. package/dist/components/choice-card.js +11 -56
  49. package/dist/components/choice-carousel.d.ts +9 -0
  50. package/dist/components/choice-carousel.js +67 -78
  51. package/dist/components/choice-preview-card.d.ts +10 -20
  52. package/dist/components/choice-preview-card.js +13 -30
  53. package/dist/components/color-input.d.ts +36 -11
  54. package/dist/components/color-input.js +139 -61
  55. package/dist/components/combobox.d.ts +60 -57
  56. package/dist/components/combobox.js +215 -196
  57. package/dist/components/command.d.ts +58 -0
  58. package/dist/components/command.js +177 -0
  59. package/dist/components/contact.d.ts +23 -0
  60. package/dist/components/contact.js +32 -0
  61. package/dist/components/context-menu.d.ts +34 -26
  62. package/dist/components/context-menu.js +43 -66
  63. package/dist/components/copy-field.d.ts +10 -5
  64. package/dist/components/copy-field.js +25 -27
  65. package/dist/components/currency-input.d.ts +25 -11
  66. package/dist/components/currency-input.js +39 -67
  67. package/dist/components/danger-zone.d.ts +10 -1
  68. package/dist/components/danger-zone.js +20 -14
  69. package/dist/components/data-table-header.d.ts +13 -2
  70. package/dist/components/data-table-header.js +143 -169
  71. package/dist/components/date-picker.d.ts +31 -32
  72. package/dist/components/date-picker.js +126 -242
  73. package/dist/components/delta.d.ts +26 -0
  74. package/dist/components/delta.js +24 -0
  75. package/dist/components/dialog.d.ts +21 -0
  76. package/dist/components/dialog.js +16 -0
  77. package/dist/components/drawer.d.ts +15 -23
  78. package/dist/components/drawer.js +56 -76
  79. package/dist/components/dropdown-menu.d.ts +63 -0
  80. package/dist/components/dropdown-menu.js +62 -0
  81. package/dist/components/dropzone.d.ts +10 -4
  82. package/dist/components/dropzone.js +30 -55
  83. package/dist/components/empty.d.ts +29 -0
  84. package/dist/components/empty.js +42 -0
  85. package/dist/components/fab.d.ts +29 -6
  86. package/dist/components/fab.js +51 -39
  87. package/dist/components/faq.d.ts +21 -0
  88. package/dist/components/faq.js +24 -0
  89. package/dist/components/file-input.d.ts +56 -0
  90. package/dist/components/file-input.js +244 -0
  91. package/dist/components/filter-chip.d.ts +34 -47
  92. package/dist/components/filter-chip.js +61 -57
  93. package/dist/components/floating-stepper.d.ts +7 -18
  94. package/dist/components/floating-stepper.js +17 -35
  95. package/dist/components/footer.d.ts +36 -0
  96. package/dist/components/footer.js +38 -0
  97. package/dist/components/form-actions.d.ts +28 -0
  98. package/dist/components/form-actions.js +24 -0
  99. package/dist/components/google-account-chooser.d.ts +25 -0
  100. package/dist/components/google-account-chooser.js +44 -0
  101. package/dist/components/google-button.d.ts +26 -0
  102. package/dist/components/google-button.js +38 -0
  103. package/dist/components/google-consent.d.ts +23 -0
  104. package/dist/components/google-consent.js +28 -0
  105. package/dist/components/google-sign-in.d.ts +26 -0
  106. package/dist/components/google-sign-in.js +36 -0
  107. package/dist/components/hover-card.d.ts +30 -0
  108. package/dist/components/hover-card.js +55 -0
  109. package/dist/components/icon-button.d.ts +41 -11
  110. package/dist/components/icon-button.js +47 -61
  111. package/dist/components/image-crop-modal.d.ts +3 -3
  112. package/dist/components/image-crop-modal.js +66 -52
  113. package/dist/components/image-upload.d.ts +21 -29
  114. package/dist/components/image-upload.js +59 -219
  115. package/dist/components/index.d.ts +105 -49
  116. package/dist/components/index.js +190 -68
  117. package/dist/components/input-otp.d.ts +35 -0
  118. package/dist/components/input-otp.js +119 -0
  119. package/dist/components/input.d.ts +23 -17
  120. package/dist/components/input.js +103 -108
  121. package/dist/components/insight-card.d.ts +25 -9
  122. package/dist/components/insight-card.js +45 -19
  123. package/dist/components/internal/announce.d.ts +3 -0
  124. package/dist/components/internal/announce.js +20 -0
  125. package/dist/components/internal/block.d.ts +15 -0
  126. package/dist/components/internal/block.js +14 -0
  127. package/dist/components/internal/button.d.ts +23 -0
  128. package/dist/components/internal/button.js +30 -0
  129. package/dist/components/internal/choice-card.d.ts +52 -0
  130. package/dist/components/internal/choice-card.js +117 -0
  131. package/dist/components/internal/choice.d.ts +25 -0
  132. package/dist/components/internal/choice.js +44 -0
  133. package/dist/components/internal/dates.d.ts +17 -0
  134. package/dist/components/internal/dates.js +59 -0
  135. package/dist/components/internal/field.d.ts +66 -0
  136. package/dist/components/internal/field.js +105 -0
  137. package/dist/components/internal/fieldset.d.ts +25 -0
  138. package/dist/components/internal/fieldset.js +56 -0
  139. package/dist/components/internal/focus-after.d.ts +3 -0
  140. package/dist/components/internal/focus-after.js +13 -0
  141. package/dist/components/internal/google.d.ts +47 -0
  142. package/dist/components/internal/google.js +73 -0
  143. package/dist/components/internal/icons.d.ts +108 -0
  144. package/dist/components/internal/icons.js +316 -0
  145. package/dist/components/internal/menu.d.ts +16 -0
  146. package/dist/components/internal/menu.js +14 -0
  147. package/dist/components/internal/modal.d.ts +50 -0
  148. package/dist/components/internal/modal.js +85 -0
  149. package/dist/components/internal/option-content.d.ts +10 -0
  150. package/dist/components/internal/option-content.js +13 -0
  151. package/dist/components/internal/radio-context.d.ts +16 -0
  152. package/dist/components/internal/radio-context.js +6 -0
  153. package/dist/components/internal/toggle.d.ts +7 -0
  154. package/dist/components/internal/toggle.js +13 -0
  155. package/dist/components/internal/use-listbox.d.ts +56 -0
  156. package/dist/components/internal/use-listbox.js +69 -0
  157. package/dist/components/internal/whatsapp.d.ts +8 -0
  158. package/dist/components/internal/whatsapp.js +12 -0
  159. package/dist/components/item.d.ts +32 -0
  160. package/dist/components/item.js +35 -0
  161. package/dist/components/kbd.d.ts +17 -0
  162. package/dist/components/kbd.js +18 -0
  163. package/dist/components/listbox.d.ts +34 -0
  164. package/dist/components/listbox.js +114 -0
  165. package/dist/components/marker.d.ts +24 -0
  166. package/dist/components/marker.js +28 -0
  167. package/dist/components/media-tile.d.ts +17 -14
  168. package/dist/components/media-tile.js +19 -24
  169. package/dist/components/message-scroller.d.ts +20 -0
  170. package/dist/components/message-scroller.js +108 -0
  171. package/dist/components/message.d.ts +33 -0
  172. package/dist/components/message.js +23 -0
  173. package/dist/components/navigation-menu.d.ts +42 -0
  174. package/dist/components/navigation-menu.js +30 -0
  175. package/dist/components/newsletter.d.ts +27 -0
  176. package/dist/components/newsletter.js +75 -0
  177. package/dist/components/number-input.d.ts +60 -0
  178. package/dist/components/number-input.js +234 -0
  179. package/dist/components/option-tile.d.ts +20 -19
  180. package/dist/components/option-tile.js +52 -131
  181. package/dist/components/page-header.d.ts +31 -0
  182. package/dist/components/page-header.js +25 -0
  183. package/dist/components/page-shell.d.ts +11 -1
  184. package/dist/components/page-shell.js +8 -27
  185. package/dist/components/page-skeleton.d.ts +15 -21
  186. package/dist/components/page-skeleton.js +37 -4
  187. package/dist/components/pagination.d.ts +32 -22
  188. package/dist/components/pagination.js +83 -76
  189. package/dist/components/password-input.d.ts +26 -0
  190. package/dist/components/password-input.js +112 -0
  191. package/dist/components/phone-input.d.ts +12 -8
  192. package/dist/components/phone-input.js +77 -47
  193. package/dist/components/phone.d.ts +27 -0
  194. package/dist/components/phone.js +35 -0
  195. package/dist/components/popover.d.ts +25 -36
  196. package/dist/components/popover.js +32 -129
  197. package/dist/components/pricing-card.d.ts +9 -25
  198. package/dist/components/pricing-card.js +9 -25
  199. package/dist/components/pricing.d.ts +48 -0
  200. package/dist/components/pricing.js +64 -0
  201. package/dist/components/progress.d.ts +30 -0
  202. package/dist/components/progress.js +57 -0
  203. package/dist/components/qr-display.d.ts +11 -6
  204. package/dist/components/qr-display.js +8 -19
  205. package/dist/components/questionnaire.d.ts +42 -0
  206. package/dist/components/questionnaire.js +107 -0
  207. package/dist/components/radio-group.d.ts +21 -0
  208. package/dist/components/radio-group.js +40 -0
  209. package/dist/components/radio.d.ts +15 -29
  210. package/dist/components/radio.js +46 -87
  211. package/dist/components/row-actions.d.ts +5 -0
  212. package/dist/components/row-actions.js +57 -56
  213. package/dist/components/saving-bar-context.d.ts +0 -5
  214. package/dist/components/saving-bar-context.js +16 -34
  215. package/dist/components/saving-bar.d.ts +26 -11
  216. package/dist/components/saving-bar.js +53 -65
  217. package/dist/components/section-card.d.ts +18 -4
  218. package/dist/components/section-card.js +26 -39
  219. package/dist/components/section-header.d.ts +8 -12
  220. package/dist/components/section-header.js +7 -2
  221. package/dist/components/select.d.ts +44 -16
  222. package/dist/components/select.js +85 -135
  223. package/dist/components/selectable-card.d.ts +11 -19
  224. package/dist/components/selectable-card.js +4 -21
  225. package/dist/components/separator.d.ts +20 -0
  226. package/dist/components/separator.js +19 -0
  227. package/dist/components/setting-row.d.ts +11 -15
  228. package/dist/components/setting-row.js +11 -14
  229. package/dist/components/settings-list.d.ts +10 -12
  230. package/dist/components/settings-list.js +9 -17
  231. package/dist/components/sheet.d.ts +21 -0
  232. package/dist/components/sheet.js +16 -0
  233. package/dist/components/sidebar.d.ts +79 -0
  234. package/dist/components/sidebar.js +111 -0
  235. package/dist/components/skeleton.d.ts +14 -20
  236. package/dist/components/skeleton.js +8 -36
  237. package/dist/components/slider.d.ts +21 -23
  238. package/dist/components/slider.js +65 -56
  239. package/dist/components/sparkline.d.ts +19 -0
  240. package/dist/components/sparkline.js +32 -0
  241. package/dist/components/spinner.d.ts +16 -8
  242. package/dist/components/spinner.js +35 -32
  243. package/dist/components/star-rating.d.ts +22 -0
  244. package/dist/components/star-rating.js +25 -0
  245. package/dist/components/stat.d.ts +33 -0
  246. package/dist/components/stat.js +29 -0
  247. package/dist/components/status.d.ts +27 -0
  248. package/dist/components/status.js +34 -0
  249. package/dist/components/step-progress.d.ts +13 -6
  250. package/dist/components/step-progress.js +20 -17
  251. package/dist/components/summary-bar.d.ts +20 -20
  252. package/dist/components/summary-bar.js +13 -50
  253. package/dist/components/switch.d.ts +20 -0
  254. package/dist/components/switch.js +46 -0
  255. package/dist/components/table.d.ts +56 -17
  256. package/dist/components/table.js +65 -59
  257. package/dist/components/tabs.d.ts +67 -0
  258. package/dist/components/tabs.js +56 -0
  259. package/dist/components/testimonial.d.ts +30 -0
  260. package/dist/components/testimonial.js +36 -0
  261. package/dist/components/textarea.d.ts +11 -16
  262. package/dist/components/textarea.js +55 -75
  263. package/dist/components/tile.d.ts +24 -0
  264. package/dist/components/tile.js +21 -0
  265. package/dist/components/time-picker.d.ts +40 -25
  266. package/dist/components/time-picker.js +191 -189
  267. package/dist/components/toast.d.ts +63 -0
  268. package/dist/components/toast.js +132 -0
  269. package/dist/components/toggle-card-compact.d.ts +15 -5
  270. package/dist/components/toggle-card-compact.js +22 -81
  271. package/dist/components/toggle-card.d.ts +11 -2
  272. package/dist/components/toggle-card.js +9 -70
  273. package/dist/components/toggle-group.d.ts +21 -59
  274. package/dist/components/toggle-group.js +31 -74
  275. package/dist/components/toggle.d.ts +19 -9
  276. package/dist/components/toggle.js +20 -55
  277. package/dist/components/tooltip.d.ts +25 -12
  278. package/dist/components/tooltip.js +16 -84
  279. package/dist/components/top-navigation.d.ts +33 -0
  280. package/dist/components/top-navigation.js +85 -0
  281. package/dist/components/typing-indicator.d.ts +6 -0
  282. package/dist/components/typing-indicator.js +3 -21
  283. package/dist/components/whatsapp-chat.d.ts +28 -0
  284. package/dist/components/whatsapp-chat.js +95 -0
  285. package/dist/components/whatsapp-message.d.ts +22 -0
  286. package/dist/components/whatsapp-message.js +34 -0
  287. package/dist/components/whatsapp-notification.d.ts +27 -0
  288. package/dist/components/whatsapp-notification.js +73 -0
  289. package/dist/components/whatsapp-template.d.ts +42 -0
  290. package/dist/components/whatsapp-template.js +69 -0
  291. package/dist/icons/index.d.ts +2 -0
  292. package/dist/icons/index.js +2 -0
  293. package/dist/icons/pix.d.ts +16 -0
  294. package/dist/icons/pix.js +29 -0
  295. package/dist/targets/native/components/accordion.js +31 -25
  296. package/dist/targets/native/components/alert.js +22 -16
  297. package/dist/targets/native/components/avatar.js +36 -29
  298. package/dist/targets/native/components/badge.js +4 -3
  299. package/dist/targets/native/components/button.js +11 -4
  300. package/dist/targets/native/components/card.js +2 -1
  301. package/dist/targets/native/components/checkbox.js +18 -15
  302. package/dist/targets/native/components/chips.js +19 -16
  303. package/dist/targets/native/components/choice-card.js +29 -23
  304. package/dist/targets/native/components/context-menu.js +13 -9
  305. package/dist/targets/native/components/currency-input.js +28 -25
  306. package/dist/targets/native/components/danger-zone.js +10 -4
  307. package/dist/targets/native/components/date-picker.js +86 -70
  308. package/dist/targets/native/components/divider.js +3 -2
  309. package/dist/targets/native/components/empty-state.js +6 -1
  310. package/dist/targets/native/components/fab.js +32 -26
  311. package/dist/targets/native/components/filter-chip.js +9 -8
  312. package/dist/targets/native/components/form-field.js +20 -10
  313. package/dist/targets/native/components/form-screen.js +50 -45
  314. package/dist/targets/native/components/google-icon.js +31 -25
  315. package/dist/targets/native/components/icon-button.js +6 -4
  316. package/dist/targets/native/components/icon.js +2 -1
  317. package/dist/targets/native/components/image-upload.js +59 -50
  318. package/dist/targets/native/components/index.d.ts +0 -2
  319. package/dist/targets/native/components/index.js +0 -4
  320. package/dist/targets/native/components/input.js +41 -34
  321. package/dist/targets/native/components/list-item.js +29 -23
  322. package/dist/targets/native/components/menu.js +12 -10
  323. package/dist/targets/native/components/modal.js +41 -32
  324. package/dist/targets/native/components/radio.js +19 -16
  325. package/dist/targets/native/components/search.js +41 -38
  326. package/dist/targets/native/components/select.js +71 -63
  327. package/dist/targets/native/components/sheet.js +36 -30
  328. package/dist/targets/native/components/skeleton.js +6 -5
  329. package/dist/targets/native/components/slider.js +51 -43
  330. package/dist/targets/native/components/spinner.js +2 -1
  331. package/dist/targets/native/components/stepper.js +14 -9
  332. package/dist/targets/native/components/switch.js +15 -14
  333. package/dist/targets/native/components/text.js +2 -1
  334. package/dist/targets/native/components/textarea.js +2 -1
  335. package/dist/targets/native/components/theme.js +2 -1
  336. package/dist/targets/native/components/toaster.js +24 -21
  337. package/dist/targets/native/index.d.ts +1 -1
  338. package/dist/targets/native/index.js +1 -3
  339. package/dist/targets/native/preset.cjs +0 -1
  340. package/dist/targets/native/theme.css +58 -60
  341. package/dist/targets/native/theme.d.ts +58 -60
  342. package/dist/targets/native/theme.js +58 -60
  343. package/package.json +35 -16
  344. package/styles/_primitives.generated.css +40 -0
  345. package/styles/base.css +15 -21
  346. package/styles/rds/components-styles.css +11365 -0
  347. package/styles/rds/components.css +993 -0
  348. package/styles/rds/foundation.css +74 -0
  349. package/styles/rds/theme.css +261 -0
  350. package/styles/rds.css +6 -0
  351. package/styles/themes/rojao.css +46 -53
  352. package/brand/rojao-black-on-white.png +0 -0
  353. package/brand/rojao-black.png +0 -0
  354. package/brand/rojao-white-on-black.png +0 -0
  355. package/brand/rojao-white.png +0 -0
  356. package/dist/components/blocker-card.d.ts +0 -42
  357. package/dist/components/blocker-card.js +0 -45
  358. package/dist/components/bottom-sheet.d.ts +0 -31
  359. package/dist/components/bottom-sheet.js +0 -120
  360. package/dist/components/chat-bubble.d.ts +0 -16
  361. package/dist/components/chat-bubble.js +0 -55
  362. package/dist/components/chips.d.ts +0 -22
  363. package/dist/components/chips.js +0 -94
  364. package/dist/components/copilot-hint.d.ts +0 -18
  365. package/dist/components/copilot-hint.js +0 -63
  366. package/dist/components/divider.d.ts +0 -20
  367. package/dist/components/divider.js +0 -47
  368. package/dist/components/empty-state.d.ts +0 -48
  369. package/dist/components/empty-state.js +0 -91
  370. package/dist/components/form-card-header.d.ts +0 -13
  371. package/dist/components/form-card-header.js +0 -8
  372. package/dist/components/label.d.ts +0 -16
  373. package/dist/components/label.js +0 -43
  374. package/dist/components/menu.d.ts +0 -50
  375. package/dist/components/menu.js +0 -80
  376. package/dist/components/modal.d.ts +0 -25
  377. package/dist/components/modal.js +0 -71
  378. package/dist/components/notice.d.ts +0 -50
  379. package/dist/components/notice.js +0 -103
  380. package/dist/components/page-tabs.d.ts +0 -35
  381. package/dist/components/page-tabs.js +0 -55
  382. package/dist/components/paywall-banner.d.ts +0 -37
  383. package/dist/components/paywall-banner.js +0 -42
  384. package/dist/components/paywall.d.ts +0 -44
  385. package/dist/components/paywall.js +0 -55
  386. package/dist/components/phone-frame.d.ts +0 -9
  387. package/dist/components/phone-frame.js +0 -18
  388. package/dist/components/pix-icon.d.ts +0 -8
  389. package/dist/components/pix-icon.js +0 -24
  390. package/dist/components/search.d.ts +0 -30
  391. package/dist/components/search.js +0 -81
  392. package/dist/components/themed.d.ts +0 -36
  393. package/dist/components/themed.js +0 -22
  394. package/dist/components/toaster.d.ts +0 -84
  395. package/dist/components/toaster.js +0 -284
  396. package/dist/components/use-dismiss.d.ts +0 -9
  397. package/dist/components/use-dismiss.js +0 -28
  398. package/dist/components/use-focus-trap.d.ts +0 -5
  399. package/dist/components/use-focus-trap.js +0 -54
  400. package/dist/targets/native/components/paywall-banner.d.ts +0 -11
  401. package/dist/targets/native/components/paywall-banner.js +0 -46
  402. package/dist/targets/native/components/paywall.d.ts +0 -18
  403. package/dist/targets/native/components/paywall.js +0 -61
@@ -0,0 +1,69 @@
1
+ import "../../chunk-ORMEWXMH.js";
2
+ import { useId, useState } from "react";
3
+ function toggleValue(selected, value) {
4
+ return selected.includes(value) ? selected.filter((v) => v !== value) : [...selected, value];
5
+ }
6
+ function useListbox({ items, showing, selected, multiple, onOpen, onChoose }) {
7
+ const listId = useId();
8
+ const [active, setActive] = useState(-1);
9
+ const optionId = (index) => `${listId}-${index}`;
10
+ const isSelected = (value) => selected.includes(value);
11
+ const choose = (item) => {
12
+ if (item.disabled) return;
13
+ onChoose(item);
14
+ };
15
+ const move = (step) => {
16
+ var _a;
17
+ if (!items.length) return;
18
+ let next = active < 0 && step < 0 ? items.length : active;
19
+ for (let i = 0; i < items.length; i++) {
20
+ next = (next + step + items.length) % items.length;
21
+ if (!items[next].disabled) break;
22
+ }
23
+ onOpen();
24
+ setActive(next);
25
+ (_a = document.getElementById(optionId(next))) == null ? void 0 : _a.scrollIntoView({ block: "nearest" });
26
+ };
27
+ const onKeyDown = (event) => {
28
+ if (event.key === "ArrowDown") {
29
+ event.preventDefault();
30
+ move(1);
31
+ } else if (event.key === "ArrowUp") {
32
+ event.preventDefault();
33
+ move(-1);
34
+ } else if (event.key === "Enter" && showing && active >= 0 && items[active]) {
35
+ event.preventDefault();
36
+ choose(items[active]);
37
+ } else {
38
+ return false;
39
+ }
40
+ return true;
41
+ };
42
+ const controlProps = {
43
+ "aria-expanded": showing,
44
+ "aria-controls": showing ? listId : void 0,
45
+ "aria-activedescendant": showing && active >= 0 ? optionId(active) : void 0
46
+ };
47
+ const listProps = {
48
+ id: listId,
49
+ role: "listbox",
50
+ "aria-multiselectable": multiple || void 0
51
+ };
52
+ const optionProps = (item, index) => ({
53
+ id: optionId(index),
54
+ role: "option",
55
+ "aria-selected": isSelected(item.value),
56
+ "aria-disabled": item.disabled || void 0,
57
+ "data-active": index === active ? "" : void 0,
58
+ // The focus stays in the field: pressing an option must not blur it.
59
+ onMouseDown: (event) => event.preventDefault(),
60
+ // mousemove, not mouseenter: a list that opens under a still cursor must not move the active option.
61
+ onMouseMove: () => !item.disabled && index !== active && setActive(index),
62
+ onClick: () => choose(item)
63
+ });
64
+ return { listId, active, setActive, move, choose, isSelected, onKeyDown, controlProps, listProps, optionProps };
65
+ }
66
+ export {
67
+ toggleValue,
68
+ useListbox
69
+ };
@@ -0,0 +1,8 @@
1
+ import * as react from 'react';
2
+
3
+ type WhatsAppPlatform = 'android' | 'ios';
4
+ declare const WhatsAppPlatformContext: react.Context<WhatsAppPlatform | undefined>;
5
+ /** The platform: the prop, else the chat's, else android. */
6
+ declare function useWhatsAppPlatform(platform: WhatsAppPlatform | undefined): WhatsAppPlatform;
7
+
8
+ export { type WhatsAppPlatform, WhatsAppPlatformContext, useWhatsAppPlatform };
@@ -0,0 +1,12 @@
1
+ import "../../chunk-ORMEWXMH.js";
2
+ import { createContext, useContext } from "react";
3
+ const WhatsAppPlatformContext = createContext(void 0);
4
+ function useWhatsAppPlatform(platform) {
5
+ var _a;
6
+ const inherited = useContext(WhatsAppPlatformContext);
7
+ return (_a = platform != null ? platform : inherited) != null ? _a : "android";
8
+ }
9
+ export {
10
+ WhatsAppPlatformContext,
11
+ useWhatsAppPlatform
12
+ };
@@ -0,0 +1,32 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ type ItemVariant = 'default' | 'outline' | 'muted';
5
+ type ItemSize = 'default' | 'sm';
6
+ interface ItemProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
7
+ /** The thing's name (Figma: `title`). */
8
+ title: ReactNode;
9
+ /** One supporting line (Figma: `showDescription` + `description`). */
10
+ description?: ReactNode;
11
+ /** A Tile for a thing, an Avatar for a person (Figma: `showMedia` + `media`). */
12
+ media?: ReactNode;
13
+ /** One action or control on the right (Figma: `showAction` + `action`): a ghost Button, an IconButton, a Switch. */
14
+ action?: ReactNode;
15
+ /** default: loose in the list, a line between rows; outline: each row a block; muted: a background, no border. */
16
+ variant?: ItemVariant;
17
+ /** sm for dense lists: 14 and 12 text, 8 12 padding. */
18
+ size?: ItemSize;
19
+ }
20
+ /**
21
+ * Item — Figma [RDS] Content/Item. One row of a list: media, title, description and one action. Inside an ItemGroup
22
+ * it is a list item (<li>); alone, a <div>. Styles: item.css.
23
+ */
24
+ declare function Item({ title, description, media, action, variant, size, className, ...rest }: ItemProps): react.JSX.Element;
25
+ interface ItemGroupProps extends HTMLAttributes<HTMLUListElement> {
26
+ /** The Items. One variant for the whole list. */
27
+ children: ReactNode;
28
+ }
29
+ /** The list the Items go in (<ul>). default rows get a line between them; outline and muted rows a gap of 8. */
30
+ declare function ItemGroup({ className, children, ...rest }: ItemGroupProps): react.JSX.Element;
31
+
32
+ export { Item, ItemGroup, type ItemGroupProps, type ItemProps, type ItemSize, type ItemVariant };
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import {
3
+ __objRest,
4
+ __spreadProps,
5
+ __spreadValues
6
+ } from "../chunk-ORMEWXMH.js";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { createContext, useContext } from "react";
9
+ const InGroup = createContext(false);
10
+ function Item(_a) {
11
+ var _b = _a, { title, description, media, action, variant = "default", size = "default", className } = _b, rest = __objRest(_b, ["title", "description", "media", "action", "variant", "size", "className"]);
12
+ const Root = useContext(InGroup) ? "li" : "div";
13
+ return /* @__PURE__ */ jsxs(
14
+ Root,
15
+ __spreadProps(__spreadValues({}, rest), {
16
+ className: ["rds-item", `rds-item--${variant}`, size === "sm" && "rds-item--sm", className].filter(Boolean).join(" "),
17
+ children: [
18
+ media && /* @__PURE__ */ jsx("span", { className: "rds-item__media", children: media }),
19
+ /* @__PURE__ */ jsxs("span", { className: "rds-item__content", children: [
20
+ /* @__PURE__ */ jsx("span", { className: "rds-item__title", children: title }),
21
+ description && /* @__PURE__ */ jsx("span", { className: "rds-item__description", children: description })
22
+ ] }),
23
+ action && /* @__PURE__ */ jsx("span", { className: "rds-item__action", children: action })
24
+ ]
25
+ })
26
+ );
27
+ }
28
+ function ItemGroup(_c) {
29
+ var _d = _c, { className, children } = _d, rest = __objRest(_d, ["className", "children"]);
30
+ return /* @__PURE__ */ jsx(InGroup.Provider, { value: true, children: /* @__PURE__ */ jsx("ul", __spreadProps(__spreadValues({}, rest), { className: ["rds-item-group", className].filter(Boolean).join(" "), children })) });
31
+ }
32
+ export {
33
+ Item,
34
+ ItemGroup
35
+ };
@@ -0,0 +1,17 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ interface KbdProps extends HTMLAttributes<HTMLElement> {
5
+ /** One key (Figma: `label`): Ctrl, Enter, ⌘. For a symbol, add aria-label with its name ("Command"). */
6
+ children: ReactNode;
7
+ }
8
+ /** Kbd — Figma [RDS] Content/Kbd. One keyboard key, for shortcuts. A combination is a KbdGroup. Styles: kbd.css. */
9
+ declare function Kbd({ className, children, ...rest }: KbdProps): react.JSX.Element;
10
+ interface KbdGroupProps extends HTMLAttributes<HTMLElement> {
11
+ /** The keys, one Kbd each, with "+" between them as text. */
12
+ children: ReactNode;
13
+ }
14
+ /** A key combination: <kbd><kbd>Ctrl</kbd>+<kbd>K</kbd></kbd>, the HTML way to write it. */
15
+ declare function KbdGroup({ className, children, ...rest }: KbdGroupProps): react.JSX.Element;
16
+
17
+ export { Kbd, KbdGroup, type KbdGroupProps, type KbdProps };
@@ -0,0 +1,18 @@
1
+ import {
2
+ __objRest,
3
+ __spreadProps,
4
+ __spreadValues
5
+ } from "../chunk-ORMEWXMH.js";
6
+ import { jsx } from "react/jsx-runtime";
7
+ function Kbd(_a) {
8
+ var _b = _a, { className, children } = _b, rest = __objRest(_b, ["className", "children"]);
9
+ return /* @__PURE__ */ jsx("kbd", __spreadProps(__spreadValues({}, rest), { className: ["rds-kbd", className].filter(Boolean).join(" "), children }));
10
+ }
11
+ function KbdGroup(_c) {
12
+ var _d = _c, { className, children } = _d, rest = __objRest(_d, ["className", "children"]);
13
+ return /* @__PURE__ */ jsx("kbd", __spreadProps(__spreadValues({}, rest), { className: ["rds-kbd-group", className].filter(Boolean).join(" "), children }));
14
+ }
15
+ export {
16
+ Kbd,
17
+ KbdGroup
18
+ };
@@ -0,0 +1,34 @@
1
+ import * as react from 'react';
2
+ import { ComponentPropsWithRef, ReactNode } from 'react';
3
+
4
+ interface ListboxProps extends Omit<ComponentPropsWithRef<'ul'>, 'children' | 'defaultValue' | 'onChange'> {
5
+ /** The ListboxOptions (Figma: the slot `options`). */
6
+ children: ReactNode;
7
+ /** Controlled: the chosen option's value. */
8
+ value?: string;
9
+ /** Uncontrolled: the option chosen at first. */
10
+ defaultValue?: string;
11
+ onValueChange?: (value: string) => void;
12
+ }
13
+ /**
14
+ * Listbox — Figma [RDS] Forms/Listbox. A list of options always on screen, one choice, marked with a check
15
+ * (role listbox). The list takes the focus: the arrows move the active option past disabled ones, Home and End
16
+ * go to the ends, Enter or Space choose. It is the list the Select and the Combobox open; on its own, for a
17
+ * short list that should stay visible (a panel, a sidebar filter). Name it with aria-label or aria-labelledby.
18
+ * Styles: internal/listbox.css.
19
+ */
20
+ declare function Listbox({ children, value, defaultValue, onValueChange, className, onKeyDown, onFocus, ref, ...rest }: ListboxProps): react.JSX.Element;
21
+ interface ListboxOptionProps {
22
+ /** The value it stands for. */
23
+ value: string;
24
+ /** The option text (Figma: `text`). */
25
+ children: ReactNode;
26
+ /** An icon before the text (Figma: `showIcon` + `icon`). Decorative. */
27
+ icon?: ReactNode;
28
+ /** Cannot be chosen now: skipped by the arrows, read as unavailable. */
29
+ disabled?: boolean;
30
+ }
31
+ /** One option of the Listbox (Figma: .listbox/option). The chosen one gets the tint and the check. */
32
+ declare function ListboxOption({ value, children, icon, disabled }: ListboxOptionProps): react.JSX.Element;
33
+
34
+ export { Listbox, ListboxOption, type ListboxOptionProps, type ListboxProps };
@@ -0,0 +1,114 @@
1
+ "use client";
2
+ import {
3
+ __objRest,
4
+ __spreadProps,
5
+ __spreadValues
6
+ } from "../chunk-ORMEWXMH.js";
7
+ import { jsx } from "react/jsx-runtime";
8
+ import {
9
+ createContext,
10
+ useContext,
11
+ useId,
12
+ useRef,
13
+ useState
14
+ } from "react";
15
+ import { warnIfUnlabelled } from "./internal/field.js";
16
+ import { OptionContent } from "./internal/option-content.js";
17
+ const ListboxContext = createContext(null);
18
+ function Listbox(_a) {
19
+ var _b = _a, { children, value, defaultValue, onValueChange, className, onKeyDown, onFocus, ref } = _b, rest = __objRest(_b, ["children", "value", "defaultValue", "onValueChange", "className", "onKeyDown", "onFocus", "ref"]);
20
+ warnIfUnlabelled("Listbox", void 0, rest["aria-label"], rest["aria-labelledby"]);
21
+ const [own, setOwn] = useState(defaultValue);
22
+ const selected = value !== void 0 ? value : own;
23
+ const [activeId, setActiveId] = useState(null);
24
+ const list = useRef(null);
25
+ const options = () => {
26
+ var _a2, _b2;
27
+ return Array.from((_b2 = (_a2 = list.current) == null ? void 0 : _a2.querySelectorAll('[role="option"]')) != null ? _b2 : []).filter(
28
+ (o) => o.getAttribute("aria-disabled") !== "true"
29
+ );
30
+ };
31
+ function choose(next) {
32
+ if (value === void 0) setOwn(next);
33
+ onValueChange == null ? void 0 : onValueChange(next);
34
+ }
35
+ function activate(option) {
36
+ if (!option) return;
37
+ setActiveId(option.id);
38
+ option.scrollIntoView({ block: "nearest" });
39
+ }
40
+ function keyDown(event) {
41
+ var _a2;
42
+ onKeyDown == null ? void 0 : onKeyDown(event);
43
+ if (event.defaultPrevented) return;
44
+ const all = options();
45
+ const index = all.findIndex((o) => o.id === activeId);
46
+ const moves = {
47
+ ArrowDown: () => all[Math.min(index + 1, all.length - 1)],
48
+ ArrowUp: () => all[Math.max(index - 1, 0)],
49
+ Home: () => all[0],
50
+ End: () => all[all.length - 1]
51
+ };
52
+ if (moves[event.key]) {
53
+ event.preventDefault();
54
+ activate(moves[event.key]());
55
+ } else if ((event.key === "Enter" || event.key === " ") && index >= 0) {
56
+ event.preventDefault();
57
+ choose((_a2 = all[index].dataset.value) != null ? _a2 : "");
58
+ }
59
+ }
60
+ function setRef(node) {
61
+ list.current = node;
62
+ if (typeof ref === "function") ref(node);
63
+ else if (ref) ref.current = node;
64
+ }
65
+ return /* @__PURE__ */ jsx(ListboxContext.Provider, { value: { selected, activeId, setActiveId, choose }, children: /* @__PURE__ */ jsx(
66
+ "ul",
67
+ __spreadProps(__spreadValues({
68
+ tabIndex: 0
69
+ }, rest), {
70
+ ref: setRef,
71
+ role: "listbox",
72
+ "aria-activedescendant": activeId != null ? activeId : void 0,
73
+ className: ["rds-listbox", className].filter(Boolean).join(" "),
74
+ onKeyDown: keyDown,
75
+ onFocus: (event) => {
76
+ var _a2;
77
+ onFocus == null ? void 0 : onFocus(event);
78
+ if (activeId && document.getElementById(activeId)) return;
79
+ const all = options();
80
+ activate((_a2 = all.find((o) => o.dataset.value === selected)) != null ? _a2 : all[0]);
81
+ },
82
+ children
83
+ })
84
+ ) });
85
+ }
86
+ function ListboxOption({ value, children, icon, disabled }) {
87
+ const context = useContext(ListboxContext);
88
+ const id = useId();
89
+ if (!context) throw new Error("[@rojaostudio/ds] ListboxOption goes inside a Listbox.");
90
+ const selected = context.selected === value;
91
+ return /* @__PURE__ */ jsx(
92
+ "li",
93
+ {
94
+ id,
95
+ role: "option",
96
+ "data-value": value,
97
+ "aria-selected": selected,
98
+ "aria-disabled": disabled || void 0,
99
+ "data-active": context.activeId === id ? "" : void 0,
100
+ className: "rds-listbox__option",
101
+ onMouseMove: () => !disabled && context.activeId !== id && context.setActiveId(id),
102
+ onClick: () => {
103
+ if (disabled) return;
104
+ context.setActiveId(id);
105
+ context.choose(value);
106
+ },
107
+ children: /* @__PURE__ */ jsx(OptionContent, { icon, selected, children })
108
+ }
109
+ );
110
+ }
111
+ export {
112
+ Listbox,
113
+ ListboxOption
114
+ };
@@ -0,0 +1,24 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ type MarkerVariant = 'default' | 'border' | 'separator';
5
+ interface MarkerProps extends HTMLAttributes<HTMLDivElement> {
6
+ /** default: icon and text; border: with a line under it, to split rows; separator: the text between two lines. */
7
+ variant?: MarkerVariant;
8
+ /** The assistant's status, a system note or a date (Figma: `text`). */
9
+ children: ReactNode;
10
+ /**
11
+ * The icon before the text (Figma: `showIcon` + `icon`), decorative. By default the assistant's sparkles; `null`
12
+ * hides it. Not shown in `separator`.
13
+ */
14
+ icon?: ReactNode;
15
+ /** The status is in progress: a Spinner in place of the icon, and the text is announced (role="status"). */
16
+ loading?: boolean;
17
+ }
18
+ /**
19
+ * Marker — Figma [RDS] Chat/Marker. A line inside the conversation that is not a message: the assistant's status
20
+ * ("Buscando…"), a system note or a date between two lines. Styles: marker.css.
21
+ */
22
+ declare function Marker({ variant, children, icon, loading, className, ...rest }: MarkerProps): react.JSX.Element;
23
+
24
+ export { Marker, type MarkerProps, type MarkerVariant };
@@ -0,0 +1,28 @@
1
+ import {
2
+ __objRest,
3
+ __spreadProps,
4
+ __spreadValues
5
+ } from "../chunk-ORMEWXMH.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { SparklesIcon } from "./internal/icons.js";
8
+ import { Spinner } from "./spinner.js";
9
+ function Marker(_a) {
10
+ var _b = _a, { variant = "default", children, icon = /* @__PURE__ */ jsx(SparklesIcon, {}), loading, className } = _b, rest = __objRest(_b, ["variant", "children", "icon", "loading", "className"]);
11
+ const classes = ["rds-marker", `rds-marker--${variant}`, className].filter(Boolean).join(" ");
12
+ const role = loading ? "status" : void 0;
13
+ if (variant === "separator") {
14
+ return /* @__PURE__ */ jsxs("div", __spreadProps(__spreadValues({ role }, rest), { className: classes, children: [
15
+ /* @__PURE__ */ jsx("span", { className: "rds-marker__line", "aria-hidden": "true" }),
16
+ /* @__PURE__ */ jsx("span", { className: "rds-marker__text", children }),
17
+ /* @__PURE__ */ jsx("span", { className: "rds-marker__line", "aria-hidden": "true" })
18
+ ] }));
19
+ }
20
+ const shown = loading ? /* @__PURE__ */ jsx(Spinner, { size: "sm" }) : icon;
21
+ return /* @__PURE__ */ jsxs("div", __spreadProps(__spreadValues({ role }, rest), { className: classes, children: [
22
+ shown && /* @__PURE__ */ jsx("span", { className: "rds-marker__icon", "aria-hidden": "true", children: shown }),
23
+ /* @__PURE__ */ jsx("span", { className: "rds-marker__text", children })
24
+ ] }));
25
+ }
26
+ export {
27
+ Marker
28
+ };
@@ -1,24 +1,27 @@
1
1
  import * as react from 'react';
2
- import { ReactNode } from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
- /**
5
- * MediaTile — miniatura de mídia (produto, imagem) com fallback e label opcional.
6
- * Substitui o `<div className="rounded-xl border overflow-hidden">` + `<img>`/fallback
7
- * reimplementado em listas/grids. Agnóstico de framework: usa `<img>` nativo
8
- * (o consumidor que quiser next/image passa via `image` slot).
9
- */
10
- interface MediaTileProps {
4
+ type MediaTileAspect = 'square' | 'video';
5
+ interface MediaTileProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
6
+ /** The image (Figma: `media=image`). Without it, or when it fails to load, the tile shows the fallback. */
11
7
  src?: string | null;
8
+ /** The image's text alternative. Empty when the label already says what it is. */
12
9
  alt?: string;
13
- /** Conteúdo de imagem custom (ex: next/image). Tem precedência sobre `src`. */
10
+ /** Your own image element (next/image, a <picture>). Takes precedence over `src`. */
14
11
  image?: ReactNode;
12
+ /** The name under the image, cut at two lines (Figma: `showLabel` + `label`). */
15
13
  label?: ReactNode;
16
- /** Se passado, o tile vira um link de navegação. */
14
+ /** Makes the tile a link; only then it has the hover and focus outline (Figma: `state=hover`). */
17
15
  href?: string;
16
+ /** What shows when the image is missing (Figma: `media=fallback`). Defaults to the image-off icon. */
18
17
  fallback?: ReactNode;
19
- aspect?: 'square' | 'video';
20
- className?: string;
18
+ /** square (1:1) or video (16:9) (Figma: `aspect`). */
19
+ aspect?: MediaTileAspect;
21
20
  }
22
- declare function MediaTile({ src, alt, image, label, href, fallback, aspect, className }: MediaTileProps): react.JSX.Element;
21
+ /**
22
+ * MediaTile — Figma [RDS] Content/MediaTile. A thumbnail of a product or image with an optional label, for lists
23
+ * and grids. A link when it has `href`, otherwise a plain box. Styles: media-tile.css.
24
+ */
25
+ declare function MediaTile({ src, alt, image, label, href, fallback, aspect, className, ...rest }: MediaTileProps): react.JSX.Element;
23
26
 
24
- export { MediaTile, type MediaTileProps };
27
+ export { MediaTile, type MediaTileAspect, type MediaTileProps };
@@ -1,27 +1,22 @@
1
- import "../chunk-ORMEWXMH.js";
2
- import { ImageOff } from "lucide-react";
3
- const ASPECT = {
4
- square: "aspect-square",
5
- video: "aspect-video"
6
- };
7
- function MediaTile({ src, alt = "", image, label, href, fallback, aspect = "square", className = "" }) {
8
- const Wrapper = href ? "a" : "div";
9
- return /* @__PURE__ */ React.createElement(
10
- Wrapper,
11
- {
12
- href,
13
- className: [
14
- "group flex flex-col rounded-(--radius-card) overflow-hidden border border-stroke-default bg-surface-default transition-all",
15
- href ? "hover:shadow-md hover:ring-2 hover:ring-stroke-focus cursor-pointer" : "",
16
- className
17
- ].filter(Boolean).join(" ")
18
- },
19
- /* @__PURE__ */ React.createElement("div", { className: `relative w-full ${ASPECT[aspect]} bg-surface-raised overflow-hidden` }, image ? image : src ? (
20
- // eslint-disable-next-line @next/next/no-img-element
21
- /* @__PURE__ */ React.createElement("img", { src, alt, className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-300" })
22
- ) : /* @__PURE__ */ React.createElement("div", { className: "w-full h-full flex items-center justify-center text-fg-disabled" }, fallback != null ? fallback : /* @__PURE__ */ React.createElement(ImageOff, { className: "size-5", strokeWidth: 1.5 }))),
23
- label != null && /* @__PURE__ */ React.createElement("div", { className: "p-1.5" }, /* @__PURE__ */ React.createElement("p", { className: "text-[11px] font-medium text-fg-primary line-clamp-2 leading-snug" }, label))
24
- );
1
+ "use client";
2
+ import {
3
+ __objRest,
4
+ __spreadProps,
5
+ __spreadValues
6
+ } from "../chunk-ORMEWXMH.js";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ import { useState } from "react";
9
+ import { ImageOffIcon } from "./internal/icons.js";
10
+ function MediaTile(_a) {
11
+ var _b = _a, { src, alt = "", image, label, href, fallback, aspect = "square", className } = _b, rest = __objRest(_b, ["src", "alt", "image", "label", "href", "fallback", "aspect", "className"]);
12
+ const [failed, setFailed] = useState(null);
13
+ const showImage = !image && src && failed !== src;
14
+ const classes = ["rds-media-tile", `rds-media-tile--${aspect}`, href && "rds-media-tile--link", className].filter(Boolean).join(" ");
15
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
16
+ /* @__PURE__ */ jsx("span", { className: "rds-media-tile__media", children: image != null ? image : showImage ? /* @__PURE__ */ jsx("img", { src, alt, onError: () => setFailed(src) }) : /* @__PURE__ */ jsx("span", { className: "rds-media-tile__fallback", "aria-hidden": fallback ? void 0 : true, children: fallback != null ? fallback : /* @__PURE__ */ jsx(ImageOffIcon, {}) }) }),
17
+ label != null && label !== "" && /* @__PURE__ */ jsx("span", { className: "rds-media-tile__label", children: label })
18
+ ] });
19
+ return href ? /* @__PURE__ */ jsx("a", __spreadProps(__spreadValues({}, rest), { href, className: classes, children: content })) : /* @__PURE__ */ jsx("div", __spreadProps(__spreadValues({}, rest), { className: classes, children: content }));
25
20
  }
26
21
  export {
27
22
  MediaTile
@@ -0,0 +1,20 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ interface MessageScrollerProps extends HTMLAttributes<HTMLDivElement> {
5
+ /** The Messages and Markers, from the oldest to the newest (Figma: slot `content`). */
6
+ children: ReactNode;
7
+ /** Names the conversation for screen readers. */
8
+ label?: string;
9
+ /** The accessible name of the "go to the end" button. */
10
+ scrollButtonLabel?: string;
11
+ }
12
+ /**
13
+ * MessageScroller — Figma [RDS] Chat/MessageScroller. The frame that scrolls the conversation, held to the bottom
14
+ * (role="log", so screen readers hear what arrives). A new item keeps it at the end; if the person scrolled up to
15
+ * read, it stays put and the "go to the end" button appears by itself (Figma: `showButton` only simulates that).
16
+ * It fills its parent's height: size the parent to the chat area. Styles: message-scroller.css.
17
+ */
18
+ declare function MessageScroller({ children, label, scrollButtonLabel, className, onScroll, ...rest }: MessageScrollerProps): react.JSX.Element;
19
+
20
+ export { MessageScroller, type MessageScrollerProps };
@@ -0,0 +1,108 @@
1
+ "use client";
2
+ import {
3
+ __objRest,
4
+ __spreadProps,
5
+ __spreadValues
6
+ } from "../chunk-ORMEWXMH.js";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { useEffect, useLayoutEffect, useRef, useState } from "react";
9
+ import { IconButton } from "./icon-button.js";
10
+ import { Tooltip } from "./tooltip.js";
11
+ import { ArrowDownIcon } from "./internal/icons.js";
12
+ const NEAR_END = 24;
13
+ const reducedMotion = () => {
14
+ var _a;
15
+ return typeof window !== "undefined" && ((_a = window.matchMedia) == null ? void 0 : _a.call(window, "(prefers-reduced-motion: reduce)").matches);
16
+ };
17
+ function MessageScroller(_a) {
18
+ var _b = _a, {
19
+ children,
20
+ label = "Conversa",
21
+ scrollButtonLabel = "Ir para a mensagem mais nova",
22
+ className,
23
+ onScroll
24
+ } = _b, rest = __objRest(_b, [
25
+ "children",
26
+ "label",
27
+ "scrollButtonLabel",
28
+ "className",
29
+ "onScroll"
30
+ ]);
31
+ const ref = useRef(null);
32
+ const atEnd = useRef(true);
33
+ const goingToEnd = useRef(false);
34
+ const [showButton, setShowButton] = useState(false);
35
+ const toEnd = (behavior = "auto") => {
36
+ const box = ref.current;
37
+ if (box) box.scrollTo({ top: box.scrollHeight, behavior });
38
+ };
39
+ useLayoutEffect(() => {
40
+ if (atEnd.current) toEnd();
41
+ }, [children]);
42
+ useEffect(() => toEnd(), []);
43
+ useEffect(() => {
44
+ const box = ref.current;
45
+ if (!box) return;
46
+ const isAtEnd = () => box.scrollHeight - box.scrollTop - box.clientHeight <= NEAR_END;
47
+ const settle = () => {
48
+ atEnd.current = isAtEnd();
49
+ if (goingToEnd.current && !atEnd.current) {
50
+ const top = box.scrollTop;
51
+ requestAnimationFrame(
52
+ () => requestAnimationFrame(() => {
53
+ if (!goingToEnd.current || box.scrollTop !== top) return;
54
+ goingToEnd.current = false;
55
+ setShowButton(!isAtEnd());
56
+ })
57
+ );
58
+ return;
59
+ }
60
+ goingToEnd.current = false;
61
+ setShowButton(!atEnd.current);
62
+ };
63
+ box.addEventListener("scrollend", settle);
64
+ return () => box.removeEventListener("scrollend", settle);
65
+ }, []);
66
+ return /* @__PURE__ */ jsxs("div", { className: ["rds-scroller", className].filter(Boolean).join(" "), children: [
67
+ /* @__PURE__ */ jsx(
68
+ "div",
69
+ __spreadProps(__spreadValues({
70
+ ref,
71
+ role: "log",
72
+ "aria-label": label,
73
+ tabIndex: 0
74
+ }, rest), {
75
+ className: "rds-scroller__viewport",
76
+ onScroll: (event) => {
77
+ const box = event.currentTarget;
78
+ atEnd.current = box.scrollHeight - box.scrollTop - box.clientHeight <= NEAR_END;
79
+ if (atEnd.current) goingToEnd.current = false;
80
+ if (!goingToEnd.current) setShowButton(!atEnd.current);
81
+ onScroll == null ? void 0 : onScroll(event);
82
+ },
83
+ children: /* @__PURE__ */ jsx("div", { className: "rds-scroller__content", children })
84
+ })
85
+ ),
86
+ showButton && /* @__PURE__ */ jsx(Tooltip, { text: scrollButtonLabel, children: /* @__PURE__ */ jsx(
87
+ IconButton,
88
+ {
89
+ className: "rds-scroller__to-end",
90
+ icon: /* @__PURE__ */ jsx(ArrowDownIcon, {}),
91
+ label: scrollButtonLabel,
92
+ tone: "neutral",
93
+ variant: "outline",
94
+ onClick: () => {
95
+ var _a2;
96
+ (_a2 = ref.current) == null ? void 0 : _a2.focus({ preventScroll: true });
97
+ atEnd.current = true;
98
+ goingToEnd.current = true;
99
+ setShowButton(false);
100
+ toEnd(reducedMotion() ? "auto" : "smooth");
101
+ }
102
+ }
103
+ ) })
104
+ ] });
105
+ }
106
+ export {
107
+ MessageScroller
108
+ };