@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
@@ -1,213 +1,232 @@
1
1
  "use client";
2
- import "../chunk-ORMEWXMH.js";
3
- import { forwardRef, useState, useRef, useEffect, useId, useImperativeHandle } from "react";
4
- import { ChevronDown, Check, Search as SearchIcon, X, Plus } from "lucide-react";
5
- import { Popover } from "./popover.js";
6
- const SIZE_CLASS = {
7
- sm: "h-8 text-caption px-2.5",
8
- md: "h-10 text-label px-3"
9
- };
10
- function defaultFilter(opt, q) {
11
- var _a, _b;
12
- if (!q) return true;
13
- const lower = q.toLowerCase();
14
- return opt.label.toLowerCase().includes(lower) || ((_b = (_a = opt.description) == null ? void 0 : _a.toLowerCase().includes(lower)) != null ? _b : false);
15
- }
16
- const Combobox = forwardRef(function Combobox2(props, ref) {
17
- var _a;
2
+ import {
3
+ __spreadProps,
4
+ __spreadValues
5
+ } from "../chunk-ORMEWXMH.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { useMemo, useRef, useState } from "react";
8
+ import { Chip } from "./chip.js";
9
+ import { announce } from "./internal/announce.js";
10
+ import { FieldShell, useFieldIds, warnIfUnlabelled } from "./internal/field.js";
11
+ import { ChevronDownIcon, PlusIcon } from "./internal/icons.js";
12
+ import { OptionContent } from "./internal/option-content.js";
13
+ import { toggleValue, useListbox } from "./internal/use-listbox.js";
14
+ const CREATE = "\0create";
15
+ const normalize = (text) => text.normalize("NFD").replace(new RegExp("\\p{Diacritic}", "gu"), "").toLowerCase();
16
+ function Combobox(props) {
17
+ var _a, _b, _c, _d;
18
18
  const {
19
- options,
20
- placeholder = "Selecione\u2026",
21
- filter = defaultFilter,
22
- emptyMessage = "Nada encontrado",
23
- width = "full",
24
- size = "md",
25
- disabled = false,
26
- className = "",
27
- triggerContent,
28
- dropdownMinWidth,
19
+ label,
20
+ labelPosition,
21
+ hint,
22
+ error,
23
+ errorMessage,
24
+ required,
25
+ options: rawOptions,
26
+ emptyMessage = "Nenhum resultado",
27
+ resultsMessage = (count) => `${count} ${count === 1 ? "resultado" : "resultados"}`,
29
28
  onCreate,
30
- createLabel = (q) => `+ "${q}"`
29
+ creatable = onCreate !== void 0,
30
+ createLabel = (text) => `Cadastrar "${text}"`,
31
+ placeholder,
32
+ leadingIcon,
33
+ name,
34
+ disabled,
35
+ id,
36
+ className,
37
+ style,
38
+ "aria-label": ariaLabel,
39
+ "aria-labelledby": ariaLabelledBy
31
40
  } = props;
32
- const isMulti = props.multi === true;
33
- const [open, setOpen] = useState(false);
41
+ const multiple = props.multiple === true;
42
+ warnIfUnlabelled("Combobox", label, ariaLabel, ariaLabelledBy);
43
+ const { controlId, hintId, errorId, invalid, describedBy } = useFieldIds(id, hint, error, errorMessage);
44
+ const [created, setCreated] = useState([]);
45
+ const options = useMemo(
46
+ () => [...rawOptions.map((o) => typeof o === "string" ? { value: o, label: o } : o), ...created],
47
+ [rawOptions, created]
48
+ );
49
+ const labelOf = (v) => {
50
+ var _a2, _b2;
51
+ return (_b2 = (_a2 = options.find((o) => o.value === v)) == null ? void 0 : _a2.label) != null ? _b2 : v;
52
+ };
53
+ const [ownSingle, setOwnSingle] = useState(multiple ? "" : (_a = props.defaultValue) != null ? _a : "");
54
+ const [ownMany, setOwnMany] = useState(multiple ? (_b = props.defaultValue) != null ? _b : [] : []);
55
+ const chosen = multiple ? (_c = props.value) != null ? _c : ownMany : [(_d = props.value) != null ? _d : ownSingle].filter(Boolean);
56
+ const chosenLabel = !multiple && chosen[0] ? labelOf(chosen[0]) : "";
57
+ const input = useRef(null);
34
58
  const [query, setQuery] = useState("");
35
- const [activeIdx, setActiveIdx] = useState(0);
36
- const [dropdownWidth, setDropdownWidth] = useState(0);
37
- const triggerRef = useRef(null);
38
- const inputRef = useRef(null);
39
- const id = useId();
40
- useImperativeHandle(ref, () => triggerRef.current);
41
- useEffect(() => {
42
- if (open && triggerRef.current) {
43
- setDropdownWidth(triggerRef.current.offsetWidth);
44
- }
45
- }, [open]);
46
- useEffect(() => {
47
- if (open) {
48
- requestAnimationFrame(() => {
49
- var _a2;
50
- return (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
51
- });
52
- setActiveIdx(0);
53
- } else {
54
- setQuery("");
55
- }
56
- }, [open]);
57
- const filtered = options.filter((o) => filter(o, query));
58
- const trimmed = query.trim();
59
- const showCreate = !!onCreate && trimmed.length > 0 && !options.some((o) => o.label.toLowerCase() === trimmed.toLowerCase());
60
- function doCreate() {
61
- if (!onCreate || !trimmed) return;
62
- onCreate(trimmed);
63
- setOpen(false);
59
+ const [typing, setTyping] = useState(false);
60
+ const [open, setOpen] = useState(false);
61
+ function listFor(text, filtering2) {
62
+ const matches2 = filtering2 ? options.filter((o) => normalize(o.label).includes(normalize(text))) : options;
63
+ const typed = text.trim();
64
+ const exact = options.some((o) => normalize(o.label) === normalize(typed));
65
+ const rows2 = creatable && filtering2 && typed && !exact ? [...matches2, { value: CREATE, label: createLabel(typed), create: typed }] : matches2;
66
+ return { matches: matches2, rows: rows2 };
64
67
  }
65
- function isSelected(opt) {
66
- return isMulti ? props.value.includes(opt.value) : props.value === opt.value;
68
+ const onlyCreate = (rows2) => rows2.length === 1 && rows2[0].create !== void 0;
69
+ const filtering = multiple ? query !== "" : typing && query !== "";
70
+ const { matches, rows } = listFor(query, filtering);
71
+ const showList = open && rows.length > 0;
72
+ const empty = open && rows.length === 0;
73
+ function commitSingle(next) {
74
+ var _a2;
75
+ if (props.value === void 0) setOwnSingle(next);
76
+ (_a2 = props.onValueChange) == null ? void 0 : _a2.call(props, next);
67
77
  }
68
- function selectedOption() {
78
+ function commitMany(next) {
69
79
  var _a2;
70
- if (isMulti) return null;
71
- return (_a2 = options.find((o) => o.value === props.value)) != null ? _a2 : null;
80
+ if (props.value === void 0) setOwnMany(next);
81
+ (_a2 = props.onValueChange) == null ? void 0 : _a2.call(props, next);
72
82
  }
73
- function handleSelect(opt) {
74
- if (opt.disabled) return;
75
- if (isMulti) {
76
- const current = props.value;
77
- const next = current.includes(opt.value) ? current.filter((v) => v !== opt.value) : [...current, opt.value];
78
- props.onChange(next);
79
- } else {
80
- props.onChange(opt.value);
81
- setOpen(false);
82
- }
83
+ function create(text) {
84
+ const made = onCreate == null ? void 0 : onCreate(text);
85
+ const option = typeof made === "string" ? { value: made, label: text } : made != null ? made : { value: text, label: text };
86
+ if (!options.some((o) => o.value === option.value)) setCreated((all) => [...all, option]);
87
+ return option;
83
88
  }
84
- function handleKey(e) {
85
- if (e.key === "ArrowDown") {
86
- e.preventDefault();
87
- setActiveIdx((i) => Math.min(i + 1, filtered.length - 1));
88
- } else if (e.key === "ArrowUp") {
89
- e.preventDefault();
90
- setActiveIdx((i) => Math.max(i - 1, 0));
91
- } else if (e.key === "Enter") {
92
- e.preventDefault();
93
- const opt = filtered[activeIdx];
94
- if (opt) handleSelect(opt);
95
- else if (showCreate) doCreate();
96
- } else if (e.key === "Escape") {
97
- setOpen(false);
89
+ const { setActive, isSelected, onKeyDown: listKeyDown, controlProps, listProps, optionProps } = useListbox({
90
+ items: rows,
91
+ showing: showList,
92
+ selected: chosen,
93
+ multiple,
94
+ onOpen: () => setOpen(true),
95
+ onChoose: (row) => {
96
+ if (multiple) {
97
+ if (row.create) {
98
+ const option = create(row.create);
99
+ commitMany([...chosen, option.value]);
100
+ announce(`${option.label} adicionado`);
101
+ } else {
102
+ const adding = !chosen.includes(row.value);
103
+ commitMany(toggleValue(chosen, row.value));
104
+ announce(`${row.label} ${adding ? "adicionado" : "removido"}`);
105
+ }
106
+ if (query !== "") {
107
+ setQuery("");
108
+ setActive(-1);
109
+ }
110
+ } else {
111
+ commitSingle(row.create ? create(row.create).value : row.value);
112
+ setTyping(false);
113
+ setOpen(false);
114
+ setActive(-1);
115
+ }
116
+ }
117
+ });
118
+ function keyDown(event) {
119
+ if (listKeyDown(event)) return;
120
+ if (event.key === "Escape") {
121
+ if (open) {
122
+ event.preventDefault();
123
+ setOpen(false);
124
+ setActive(-1);
125
+ } else if (!multiple) {
126
+ setTyping(false);
127
+ }
128
+ } else if (multiple && event.key === "Backspace" && query === "" && chosen.length) {
129
+ const last = chosen[chosen.length - 1];
130
+ commitMany(chosen.slice(0, -1));
131
+ announce(`${labelOf(last)} removido`);
98
132
  }
99
133
  }
100
- const sel = selectedOption();
101
- const triggerLabel = isMulti ? props.value.length === 0 ? placeholder : `${props.value.length} selecionado(s)` : (_a = sel == null ? void 0 : sel.label) != null ? _a : placeholder;
102
- const isPlaceholder = isMulti ? props.value.length === 0 : !sel;
103
- const dropdown = /* @__PURE__ */ React.createElement(
104
- "div",
134
+ function remove(v) {
135
+ const next = chosen.filter((x) => x !== v);
136
+ commitMany(next);
137
+ if (next.length === 0) requestAnimationFrame(() => {
138
+ var _a2;
139
+ return (_a2 = input.current) == null ? void 0 : _a2.focus();
140
+ });
141
+ }
142
+ const listName = typeof label === "string" ? label : ariaLabel;
143
+ return /* @__PURE__ */ jsxs(
144
+ FieldShell,
105
145
  {
106
- id,
107
- role: "listbox",
108
- style: { width: Math.max(dropdownWidth, dropdownMinWidth != null ? dropdownMinWidth : 0) || void 0 },
109
- className: "max-h-72 overflow-hidden rounded-(--radius-control) border border-stroke-control bg-surface-default shadow-lg flex flex-col"
110
- },
111
- /* @__PURE__ */ React.createElement("div", { className: "relative shrink-0 border-b border-stroke-subtle" }, /* @__PURE__ */ React.createElement(SearchIcon, { size: 14, className: "absolute left-3 top-1/2 -translate-y-1/2 text-fg-muted pointer-events-none" }), /* @__PURE__ */ React.createElement(
112
- "input",
113
- {
114
- ref: inputRef,
115
- type: "text",
116
- value: query,
117
- onChange: (e) => {
118
- setQuery(e.target.value);
119
- setActiveIdx(0);
120
- },
121
- onKeyDown: handleKey,
122
- placeholder: "Buscar\u2026",
123
- className: "w-full pl-9 pr-8 py-2 text-label bg-transparent outline-none text-fg-primary placeholder:text-fg-placeholder",
124
- "aria-label": "Buscar op\xE7\xF5es"
125
- }
126
- ), query && /* @__PURE__ */ React.createElement(
127
- "button",
128
- {
129
- type: "button",
130
- onClick: () => {
131
- var _a2;
132
- setQuery("");
133
- (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
134
- },
135
- "aria-label": "Limpar",
136
- className: "absolute right-2 top-1/2 -translate-y-1/2 text-fg-muted hover:text-fg-primary p-1"
137
- },
138
- /* @__PURE__ */ React.createElement(X, { size: 12 })
139
- )),
140
- /* @__PURE__ */ React.createElement("div", { className: "overflow-y-auto py-1 max-h-60" }, filtered.length === 0 && !showCreate ? /* @__PURE__ */ React.createElement("div", { className: "px-3 py-3 text-label text-fg-muted text-center" }, emptyMessage) : /* @__PURE__ */ React.createElement(React.Fragment, null, filtered.map((opt, idx) => {
141
- const selected = isSelected(opt);
142
- const active = idx === activeIdx;
143
- return /* @__PURE__ */ React.createElement(
144
- "button",
145
- {
146
- key: opt.value,
147
- type: "button",
148
- role: "option",
149
- "aria-selected": selected,
150
- disabled: opt.disabled,
151
- onClick: () => handleSelect(opt),
152
- onMouseEnter: () => setActiveIdx(idx),
153
- className: [
154
- "w-full flex items-start gap-2.5 px-3 py-2 text-label text-left transition-colors",
155
- "disabled:cursor-not-allowed disabled:opacity-50",
156
- active ? "bg-surface-raised" : "hover:bg-surface-raised"
157
- ].join(" ")
158
- },
159
- opt.icon && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 text-fg-muted mt-0.5 [&_svg]:size-4" }, opt.icon),
160
- /* @__PURE__ */ React.createElement("span", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React.createElement("span", { className: "block text-fg-primary truncate" }, opt.label), opt.description && /* @__PURE__ */ React.createElement("span", { className: "block text-caption text-fg-muted truncate" }, opt.description)),
161
- selected && /* @__PURE__ */ React.createElement(Check, { size: 14, className: "shrink-0 text-fg-muted mt-0.5" })
162
- );
163
- }), showCreate && /* @__PURE__ */ React.createElement(
164
- "button",
165
- {
166
- type: "button",
167
- onClick: doCreate,
168
- className: "w-full flex items-center gap-2.5 px-3 py-2 text-label text-left text-fg-primary transition-colors hover:bg-surface-raised border-t border-stroke-subtle"
169
- },
170
- /* @__PURE__ */ React.createElement(Plus, { size: 14, className: "shrink-0 text-fg-muted" }),
171
- /* @__PURE__ */ React.createElement("span", { className: "truncate" }, createLabel(trimmed))
172
- )))
146
+ kind: "rds-combobox",
147
+ controlId,
148
+ hintId,
149
+ errorId,
150
+ label,
151
+ labelPosition,
152
+ hint,
153
+ errorMessage,
154
+ invalid,
155
+ required,
156
+ disabled,
157
+ boxClassName: multiple ? "rds-combobox__box--multiple" : void 0,
158
+ className,
159
+ style,
160
+ children: [
161
+ leadingIcon && /* @__PURE__ */ jsx("span", { className: "rds-field__icon", "aria-hidden": "true", children: leadingIcon }),
162
+ multiple && chosen.length > 0 && /* @__PURE__ */ jsx("ul", { className: "rds-combobox__chips", "aria-label": `Escolhidos: ${chosen.length}`, children: chosen.map((v) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Chip, { disabled, onRemove: () => remove(v), children: labelOf(v) }) }, v)) }),
163
+ /* @__PURE__ */ jsx(
164
+ "input",
165
+ __spreadProps(__spreadValues({
166
+ ref: input,
167
+ id: controlId,
168
+ className: "rds-field__control",
169
+ type: "text",
170
+ role: "combobox",
171
+ autoComplete: "off",
172
+ "aria-autocomplete": "list"
173
+ }, controlProps), {
174
+ "aria-label": ariaLabel,
175
+ "aria-labelledby": ariaLabelledBy,
176
+ "aria-invalid": invalid || void 0,
177
+ "aria-describedby": describedBy,
178
+ "aria-required": required || void 0,
179
+ disabled,
180
+ placeholder: multiple && chosen.length ? void 0 : labelPosition === "floating" && label ? " " : placeholder,
181
+ value: multiple ? query : typing ? query : chosenLabel,
182
+ onChange: (event) => {
183
+ const text = event.target.value;
184
+ setQuery(text);
185
+ setTyping(true);
186
+ setOpen(true);
187
+ setActive(onlyCreate(listFor(text, text !== "").rows) ? 0 : -1);
188
+ if (!multiple && text === "" && chosen.length) commitSingle("");
189
+ },
190
+ onClick: () => setOpen((current) => !current),
191
+ onKeyDown: keyDown,
192
+ onBlur: () => {
193
+ setOpen(false);
194
+ setTyping(false);
195
+ setQuery("");
196
+ setActive(-1);
197
+ }
198
+ })
199
+ ),
200
+ /* @__PURE__ */ jsx(
201
+ "span",
202
+ {
203
+ className: ["rds-field__icon", "rds-combobox__chevron", open && "rds-combobox__chevron--open"].filter(Boolean).join(" "),
204
+ "aria-hidden": "true",
205
+ onMouseDown: (event) => {
206
+ var _a2;
207
+ event.preventDefault();
208
+ if (disabled) return;
209
+ (_a2 = input.current) == null ? void 0 : _a2.focus();
210
+ setOpen((current) => !current);
211
+ },
212
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, {})
213
+ }
214
+ ),
215
+ name && (chosen.length ? chosen : multiple ? [] : [""]).map((v) => /* @__PURE__ */ jsx("input", { type: "hidden", name, value: v }, v)),
216
+ showList && /* @__PURE__ */ jsx("ul", __spreadProps(__spreadValues({}, listProps), { "aria-label": listName, className: "rds-listbox rds-combobox__list", children: rows.map((row, index) => /* @__PURE__ */ jsx(
217
+ "li",
218
+ __spreadProps(__spreadValues({}, optionProps(row, index)), {
219
+ className: row.create ? "rds-listbox__option rds-combobox__create" : "rds-listbox__option",
220
+ children: /* @__PURE__ */ jsx(OptionContent, { icon: row.create ? /* @__PURE__ */ jsx(PlusIcon, {}) : row.icon, selected: !row.create && isSelected(row.value), children: row.label })
221
+ }),
222
+ row.value
223
+ )) })),
224
+ empty && /* @__PURE__ */ jsx("div", { className: "rds-listbox rds-combobox__list rds-combobox__empty", "aria-hidden": "true", children: emptyMessage }),
225
+ /* @__PURE__ */ jsx("span", { className: "rds-visually-hidden", "aria-live": "polite", children: open && filtering ? matches.length ? resultsMessage(matches.length) : emptyMessage : "" })
226
+ ]
227
+ }
173
228
  );
174
- return /* @__PURE__ */ React.createElement("div", { className: ["relative inline-block", width === "full" ? "w-full" : "w-auto", className].join(" ") }, /* @__PURE__ */ React.createElement(
175
- Popover,
176
- {
177
- trigger: /* @__PURE__ */ React.createElement(
178
- "button",
179
- {
180
- ref: triggerRef,
181
- type: "button",
182
- onClick: (e) => {
183
- e.stopPropagation();
184
- if (!disabled) setOpen((o) => !o);
185
- },
186
- disabled,
187
- "aria-haspopup": "listbox",
188
- "aria-expanded": open,
189
- "aria-controls": id,
190
- className: [
191
- "w-full flex items-center justify-between gap-2 rounded-(--radius-control) border border-stroke-control bg-surface-default",
192
- "transition-colors focus:outline-none focus:border-stroke-focus focus:ring-2 focus:ring-stroke-focus/20",
193
- "disabled:opacity-50 disabled:cursor-not-allowed",
194
- SIZE_CLASS[size]
195
- ].join(" ")
196
- },
197
- /* @__PURE__ */ React.createElement("span", { className: ["truncate inline-flex items-center", isPlaceholder ? "text-fg-placeholder" : "text-fg-primary"].join(" ") }, triggerContent ? triggerContent(sel) : /* @__PURE__ */ React.createElement(React.Fragment, null, (sel == null ? void 0 : sel.icon) && /* @__PURE__ */ React.createElement("span", { className: "inline-flex mr-2 align-middle [&_svg]:size-4" }, sel.icon), triggerLabel)),
198
- /* @__PURE__ */ React.createElement(ChevronDown, { size: 16, className: "text-fg-muted shrink-0" })
199
- ),
200
- triggerClassName: width === "full" ? "block w-full" : "inline-block",
201
- placement: "bottom-start",
202
- offset: 4,
203
- open,
204
- onOpenChange: (v) => {
205
- if (!disabled) setOpen(v);
206
- }
207
- },
208
- () => dropdown
209
- ));
210
- });
229
+ }
211
230
  export {
212
231
  Combobox
213
232
  };
@@ -0,0 +1,58 @@
1
+ import * as react from 'react';
2
+ import { ReactElement, ReactNode } from 'react';
3
+ import { MenuItemContentProps } from './internal/menu.js';
4
+
5
+ interface CommandProps {
6
+ /** The element that opens it (a Button). Ctrl K (⌘ K on a Mac) opens it too, unless `hotkey` is off. */
7
+ trigger?: ReactElement;
8
+ open?: boolean;
9
+ defaultOpen?: boolean;
10
+ onOpenChange?: (open: boolean) => void;
11
+ /** Controlled: what is typed in the search (Figma: `query`). */
12
+ query?: string;
13
+ /** Uncontrolled: what the search starts with. */
14
+ defaultQuery?: string;
15
+ onQueryChange?: (query: string) => void;
16
+ /** What the person can search for, shown while the search is empty. */
17
+ placeholder?: string;
18
+ /** The results (Figma: the `results` slot): CommandGroups of CommandItems. They filter by the search. */
19
+ children: ReactNode;
20
+ /** Shown when nothing matches the search. */
21
+ emptyMessage?: string;
22
+ /** Ctrl K (⌘ K) opens and closes it. On by default. */
23
+ hotkey?: boolean;
24
+ /** The window's name for screen readers. */
25
+ label?: string;
26
+ /** Where the layer is portaled (default document.body). */
27
+ container?: HTMLElement | null;
28
+ }
29
+ /**
30
+ * Command — Figma [RDS] Overlays/Command. The command palette: search, then go anywhere or run an action. A modal
31
+ * window (Radix Dialog) with a search field (role="combobox", aria-activedescendant) over a listbox of results in
32
+ * groups. Typing filters (accents and case don't matter, `keywords` count too), the arrows move, Enter runs the
33
+ * highlighted result, Escape closes and gives the focus back. Everything in it also exists on the screen.
34
+ * Styles: internal/menu.css and command.css.
35
+ */
36
+ declare function Command({ trigger, open, defaultOpen, onOpenChange, query: queryProp, defaultQuery, onQueryChange, placeholder, children, emptyMessage, hotkey, label, container, }: CommandProps): react.JSX.Element;
37
+ interface CommandGroupProps {
38
+ /** The group's visible name ("Ir para", "Ações"). */
39
+ label: string;
40
+ /** The CommandItems. The group hides when none matches. */
41
+ children: ReactNode;
42
+ }
43
+ /** A group of results under a name (Figma: the `group` and its `group-label`). */
44
+ declare function CommandGroup({ label, children }: CommandGroupProps): react.JSX.Element;
45
+ interface CommandItemProps extends MenuItemContentProps {
46
+ /** Runs when chosen (Enter or a click); the palette closes first. */
47
+ onSelect?: () => void;
48
+ /** The text the search matches. Defaults to the label when it is plain text. */
49
+ value?: string;
50
+ /** Other words that find it ("envio" finds "Novo disparo"). */
51
+ keywords?: string[];
52
+ /** Shown but can't be chosen; the arrows skip it. */
53
+ disabled?: boolean;
54
+ }
55
+ /** One result (Figma .menu/item): role="option". It shows only while it matches the search. */
56
+ declare function CommandItem({ children, icon, shortcut, onSelect, value, keywords, disabled }: CommandItemProps): react.JSX.Element | null;
57
+
58
+ export { Command, CommandGroup, type CommandGroupProps, CommandItem, type CommandItemProps, type CommandProps };