@rojaostudio/ds 1.0.2 → 2.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) 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 -93
  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 +67 -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 -90
  15. package/dist/components/badge.d.ts +30 -41
  16. package/dist/components/badge.js +13 -110
  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 +38 -56
  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 +45 -108
  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 +31 -46
  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 +87 -81
  43. package/dist/components/chip-input.d.ts +46 -20
  44. package/dist/components/chip-input.js +172 -176
  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 -62
  49. package/dist/components/choice-carousel.d.ts +9 -0
  50. package/dist/components/choice-carousel.js +28 -44
  51. package/dist/components/choice-preview-card.d.ts +10 -20
  52. package/dist/components/choice-preview-card.js +12 -40
  53. package/dist/components/color-input.d.ts +36 -11
  54. package/dist/components/color-input.js +131 -59
  55. package/dist/components/combobox.d.ts +60 -57
  56. package/dist/components/combobox.js +210 -213
  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 +41 -68
  63. package/dist/components/copy-field.d.ts +10 -5
  64. package/dist/components/copy-field.js +24 -29
  65. package/dist/components/currency-input.d.ts +25 -11
  66. package/dist/components/currency-input.js +29 -65
  67. package/dist/components/danger-zone.d.ts +10 -1
  68. package/dist/components/danger-zone.js +14 -18
  69. package/dist/components/data-table-header.d.ts +13 -2
  70. package/dist/components/data-table-header.js +114 -190
  71. package/dist/components/date-picker.d.ts +31 -32
  72. package/dist/components/date-picker.js +119 -254
  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 +57 -89
  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 -58
  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 -51
  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 -61
  93. package/dist/components/floating-stepper.d.ts +7 -18
  94. package/dist/components/floating-stepper.js +27 -55
  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 +44 -64
  111. package/dist/components/image-crop-modal.d.ts +3 -3
  112. package/dist/components/image-crop-modal.js +32 -39
  113. package/dist/components/image-upload.d.ts +21 -29
  114. package/dist/components/image-upload.js +55 -259
  115. package/dist/components/index.d.ts +105 -52
  116. package/dist/components/index.js +190 -74
  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 +104 -137
  121. package/dist/components/insight-card.d.ts +25 -9
  122. package/dist/components/insight-card.js +42 -27
  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 -27
  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 -137
  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 -34
  185. package/dist/components/page-skeleton.d.ts +15 -21
  186. package/dist/components/page-skeleton.js +28 -25
  187. package/dist/components/pagination.d.ts +32 -22
  188. package/dist/components/pagination.js +78 -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 +75 -64
  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 +30 -131
  197. package/dist/components/pricing-card.d.ts +9 -25
  198. package/dist/components/pricing-card.js +9 -40
  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 +6 -22
  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 +45 -103
  211. package/dist/components/row-actions.d.ts +5 -0
  212. package/dist/components/row-actions.js +27 -34
  213. package/dist/components/saving-bar-context.d.ts +0 -5
  214. package/dist/components/saving-bar-context.js +16 -40
  215. package/dist/components/saving-bar.d.ts +26 -11
  216. package/dist/components/saving-bar.js +50 -65
  217. package/dist/components/section-card.d.ts +18 -4
  218. package/dist/components/section-card.js +29 -50
  219. package/dist/components/section-header.d.ts +8 -12
  220. package/dist/components/section-header.js +5 -10
  221. package/dist/components/select.d.ts +44 -16
  222. package/dist/components/select.js +83 -154
  223. package/dist/components/selectable-card.d.ts +11 -19
  224. package/dist/components/selectable-card.js +4 -28
  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 +10 -23
  229. package/dist/components/settings-list.d.ts +10 -12
  230. package/dist/components/settings-list.js +7 -19
  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 -37
  237. package/dist/components/slider.d.ts +21 -23
  238. package/dist/components/slider.js +59 -64
  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 +34 -37
  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 +18 -16
  251. package/dist/components/summary-bar.d.ts +20 -20
  252. package/dist/components/summary-bar.js +13 -55
  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 +59 -58
  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 -91
  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 +185 -203
  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 +19 -86
  271. package/dist/components/toggle-card.d.ts +11 -2
  272. package/dist/components/toggle-card.js +8 -77
  273. package/dist/components/toggle-group.d.ts +21 -59
  274. package/dist/components/toggle-group.js +31 -80
  275. package/dist/components/toggle.d.ts +19 -9
  276. package/dist/components/toggle.js +16 -61
  277. package/dist/components/tooltip.d.ts +25 -12
  278. package/dist/components/tooltip.js +15 -88
  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 -24
  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/targets/native/components/index.d.ts +0 -2
  295. package/dist/targets/native/components/index.js +0 -4
  296. package/dist/targets/native/preset.cjs +0 -1
  297. package/dist/targets/native/theme.css +58 -60
  298. package/dist/targets/native/theme.d.ts +58 -60
  299. package/dist/targets/native/theme.js +58 -60
  300. package/package.json +34 -12
  301. package/styles/_primitives.generated.css +40 -0
  302. package/styles/base.css +12 -18
  303. package/styles/rds/components-styles.css +11365 -0
  304. package/styles/rds/components.css +993 -0
  305. package/styles/rds/foundation.css +74 -0
  306. package/styles/rds/theme.css +261 -0
  307. package/styles/rds.css +6 -0
  308. package/styles/themes/rojao.css +46 -53
  309. package/dist/components/blocker-card.d.ts +0 -42
  310. package/dist/components/blocker-card.js +0 -54
  311. package/dist/components/bottom-sheet.d.ts +0 -31
  312. package/dist/components/bottom-sheet.js +0 -127
  313. package/dist/components/chat-bubble.d.ts +0 -16
  314. package/dist/components/chat-bubble.js +0 -56
  315. package/dist/components/chips.d.ts +0 -22
  316. package/dist/components/chips.js +0 -101
  317. package/dist/components/copilot-hint.d.ts +0 -18
  318. package/dist/components/copilot-hint.js +0 -72
  319. package/dist/components/divider.d.ts +0 -20
  320. package/dist/components/divider.js +0 -50
  321. package/dist/components/empty-state.d.ts +0 -48
  322. package/dist/components/empty-state.js +0 -94
  323. package/dist/components/form-card-header.d.ts +0 -13
  324. package/dist/components/form-card-header.js +0 -16
  325. package/dist/components/label.d.ts +0 -16
  326. package/dist/components/label.js +0 -48
  327. package/dist/components/menu.d.ts +0 -50
  328. package/dist/components/menu.js +0 -83
  329. package/dist/components/modal.d.ts +0 -25
  330. package/dist/components/modal.js +0 -86
  331. package/dist/components/notice.d.ts +0 -50
  332. package/dist/components/notice.js +0 -121
  333. package/dist/components/page-tabs.d.ts +0 -35
  334. package/dist/components/page-tabs.js +0 -68
  335. package/dist/components/paywall-banner.d.ts +0 -37
  336. package/dist/components/paywall-banner.js +0 -58
  337. package/dist/components/paywall.d.ts +0 -44
  338. package/dist/components/paywall.js +0 -65
  339. package/dist/components/phone-frame.d.ts +0 -9
  340. package/dist/components/phone-frame.js +0 -19
  341. package/dist/components/pix-icon.d.ts +0 -8
  342. package/dist/components/search.d.ts +0 -30
  343. package/dist/components/search.js +0 -86
  344. package/dist/components/themed.d.ts +0 -36
  345. package/dist/components/themed.js +0 -23
  346. package/dist/components/toaster.d.ts +0 -84
  347. package/dist/components/toaster.js +0 -290
  348. package/dist/components/use-dismiss.d.ts +0 -9
  349. package/dist/components/use-dismiss.js +0 -28
  350. package/dist/components/use-focus-trap.d.ts +0 -5
  351. package/dist/components/use-focus-trap.js +0 -54
  352. package/dist/targets/native/components/paywall-banner.d.ts +0 -11
  353. package/dist/targets/native/components/paywall-banner.js +0 -55
  354. package/dist/targets/native/components/paywall.d.ts +0 -18
  355. package/dist/targets/native/components/paywall.js +0 -71
  356. /package/dist/{components/pix-icon.js → icons/pix.js} +0 -0
package/README.md CHANGED
@@ -3,31 +3,43 @@
3
3
  React components, styles and a React Native target for [Rojão DS](https://ds.rojao.ai).
4
4
 
5
5
  > **Only want the theme?** The engine is [`@rojaostudio/ds-core`](https://www.npmjs.com/package/@rojaostudio/ds-core) —
6
- > tokens and theme derivation, with **zero peer dependencies**. It won't make you declare React
7
- > or Tailwind.
6
+ > tokens and theme derivation, with **zero peer dependencies**. It won't make you declare React.
8
7
 
9
8
  ```bash
10
9
  npm i @rojaostudio/ds
11
10
  ```
12
11
 
13
12
  ```css
14
- /* your root stylesheet */
15
- @import "tailwindcss";
16
- @import "@rojaostudio/ds/styles/base.css";
17
- @import "@rojaostudio/ds/styles/themes/rojao.css"; /* or your own generated theme */
13
+ /* your root stylesheet: the theme, the tokens and every component's styles, in cascade layers */
14
+ @import "@rojaostudio/ds/styles/rds.css";
18
15
  ```
19
16
 
20
17
  ```tsx
21
18
  import { Button } from '@rojaostudio/ds/components/button';
22
19
 
23
- <Button variant="primary">Save</Button>
20
+ <Button>Salvar</Button>
24
21
  ```
25
22
 
26
- Then put the theme class on `<html>` — add `dark` for dark mode:
23
+ Add `dark` to `<html>` (or any element) for dark mode:
27
24
 
28
25
  ```html
29
- <html class="theme-rojao">
30
- <html class="theme-rojao dark">
26
+ <html class="dark">
27
+ ```
28
+
29
+ The stylesheet declares its layers first (`rds.theme`, `rds.tokens`, `rds.components`), so your own unlayered CSS
30
+ always wins over the design system without `!important`. The components need no Tailwind and no other stylesheet.
31
+
32
+ ### Legacy: `base.css` (deprecated)
33
+
34
+ `styles/base.css` is the 1.x stylesheet. It stays in the package for the apps that still use its Tailwind
35
+ utilities (`bg-surface-*`, `text-fg-*`, `h-control-*`…) and its CSS variables, and it still needs Tailwind 4
36
+ (`@theme inline`). No component reads it any more. Move app code off it; it leaves in a future major.
37
+
38
+ ```css
39
+ /* only while the app still uses the 1.x utilities */
40
+ @import "tailwindcss";
41
+ @import "@rojaostudio/ds/styles/base.css";
42
+ @import "@rojaostudio/ds/styles/rds.css";
31
43
  ```
32
44
 
33
45
  ## Import the component, not the barrel
@@ -45,11 +57,61 @@ can keep the barrel and add:
45
57
  experimental: { optimizePackageImports: ['@rojaostudio/ds'] }
46
58
  ```
47
59
 
60
+ ## Button sizes and the icon side
61
+
62
+ `Button` and `IconButton` take `size`: `sm` (36), `md` (44, the default) or `lg` (52). Text is 14/20 on sm and
63
+ md, 16/24 on lg; the Button icon is 16, 16, 20 and the IconButton icon 16, 20, 24. The measures come from the
64
+ `--button-size-<sm|md|lg>-*` tokens (height, padding-x, padding-y, gap, icon, icon-only, text-size, text-line).
65
+
66
+ The touch target is 44 × 44 in every size. On `sm`, an invisible layer extends it to 44 under a coarse
67
+ pointer (`@media (pointer: coarse)`), without moving the layout or the focus ring. Keep two `sm` buttons at
68
+ least 8px apart on touch screens, or their targets overlap.
69
+
70
+ `Button` also takes `iconPosition`: `end` (the default) puts the icon after the text, `start` before it. While
71
+ `loading`, the loader takes the icon's side; without an icon, it covers the label.
72
+
73
+ ```tsx
74
+ <Button size="sm" icon={<PlusIcon />} iconPosition="start">Novo cliente</Button>
75
+ <IconButton size="lg" icon={<PlusIcon />} label="Novo cliente" />
76
+ ```
77
+
78
+ The components that draw a Button or an IconButton inside (Alert, Toast, Dialog, Calendar, Carousel…) use md,
79
+ as their Figma specs do.
80
+
81
+ ## IconButton goes with a Tooltip
82
+
83
+ An icon alone doesn't say what the button does. Every `IconButton` is paired with a `Tooltip` carrying the
84
+ same text as its `label`; it shows on hover and on keyboard focus. They are two components, always together
85
+ (the IconButton has no tooltip inside it):
86
+
87
+ ```tsx
88
+ import { IconButton } from '@rojaostudio/ds/components/icon-button';
89
+ import { Tooltip } from '@rojaostudio/ds/components/tooltip';
90
+
91
+ <Tooltip text="Novo cliente">
92
+ <IconButton icon={<PlusIcon />} label="Novo cliente" />
93
+ </Tooltip>
94
+ ```
95
+
96
+ The pair can itself be the trigger of a `DropdownMenu` or a `Popover`. The IconButtons the design system
97
+ renders itself (the × of Alert, Dialog and Toast, the Calendar and Carousel arrows) already come with theirs.
98
+
48
99
  ## Requirements
49
100
 
50
- Tailwind CSS 4 and React 19. `base.css` uses `@theme inline`, so Tailwind 4 isn't optional here —
51
- it's the layer the utilities come from. If that's not your stack, `@rojaostudio/ds-core` gives you
52
- the tokens without any of it.
101
+ React 19. Tailwind CSS is an **optional** peer: only the legacy `base.css` needs it. A few components bring an
102
+ optional peer of their own, installed only if you use them: `react-image-crop` (ImageCropModal, ImageUpload) and
103
+ `react-international-phone` (PhoneInput).
104
+
105
+ ## Icons
106
+
107
+ `@rojaostudio/ds/icons` re-exports a set of `lucide-react` icons (an optional peer) and carries the icons lucide
108
+ does not have, drawn by the design system itself, such as `PixIcon`:
109
+
110
+ ```tsx
111
+ import { PixIcon } from '@rojaostudio/ds/icons';
112
+
113
+ <PixIcon size={16} />
114
+ ```
53
115
 
54
116
  ## React Native
55
117
 
@@ -2,5 +2,4 @@ export * from '@rojaostudio/ds-core/generate';
2
2
  import '@rojaostudio/ds-core/recipes';
3
3
  import '@rojaostudio/ds-core/themes';
4
4
  import '@rojaostudio/ds-core/tokens';
5
- import 'lucide-react';
6
5
  import 'lucide-react-native';
@@ -1,35 +1,45 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
 
4
- interface AccordionSingleProps {
5
- type?: 'single';
6
- defaultValue?: string;
7
- value?: string | null;
8
- onChange?: (value: string | null) => void;
9
- collapsible?: boolean;
4
+ type Heading = 'h2' | 'h3' | 'h4';
5
+ type AccordionBase = {
6
+ /** The AccordionItems, in order (Figma: the `items` slot). */
10
7
  children: ReactNode;
11
8
  className?: string;
12
- }
13
- interface AccordionMultiProps {
14
- type: 'multi';
9
+ };
10
+ type AccordionProps = AccordionBase & ({
11
+ /** single (default): one open at a time, and it can close. multiple: when the person compares sections. */
12
+ type?: 'single';
13
+ /** The item open at first (its `value`). */
14
+ defaultValue?: string;
15
+ value?: string;
16
+ onValueChange?: (value: string) => void;
17
+ } | {
18
+ type: 'multiple';
15
19
  defaultValue?: string[];
16
20
  value?: string[];
17
- onChange?: (value: string[]) => void;
18
- children: ReactNode;
19
- className?: string;
20
- }
21
- type AccordionProps = AccordionSingleProps | AccordionMultiProps;
22
- declare const Accordion: react.ForwardRefExoticComponent<AccordionProps & react.RefAttributes<HTMLDivElement>>;
21
+ onValueChange?: (value: string[]) => void;
22
+ });
23
+ /**
24
+ * Accordion — Figma [RDS] Content/Accordion (Radix Accordion). Questions or sections that open and close, one under
25
+ * the other. Keyboard: Tab between the triggers, Enter or Space opens, arrows move between them, Home and End jump
26
+ * to the first and the last. It is also the Collapsible: a single section that opens is an Accordion with one item.
27
+ * Styles: accordion.css.
28
+ */
29
+ declare function Accordion({ className, children, ...props }: AccordionProps): react.JSX.Element;
23
30
  interface AccordionItemProps {
31
+ /** A unique id for this item, used by `defaultValue` and `value`. */
24
32
  value: string;
33
+ /** What is inside (Figma: `title`), as a question or a subject. Never a vague "more information". */
25
34
  title: ReactNode;
26
- /** Subtítulo opcional ao lado do título (ex: contagem, tag). */
27
- meta?: ReactNode;
35
+ /** The heading level that fits the page's heading order. */
36
+ titleAs?: Heading;
37
+ /** The answer (Figma: `content`). */
28
38
  children: ReactNode;
29
- /** Ícone leading no header. */
30
- icon?: ReactNode;
31
39
  disabled?: boolean;
40
+ className?: string;
32
41
  }
33
- declare function AccordionItem({ value, title, meta, children, icon, disabled }: AccordionItemProps): react.JSX.Element;
42
+ /** One item (Figma: .accordion/item): a heading with a button, and a region that opens. */
43
+ declare function AccordionItem({ value, title, titleAs, children, disabled, className }: AccordionItemProps): react.JSX.Element;
34
44
 
35
45
  export { Accordion, AccordionItem, type AccordionItemProps, type AccordionProps };
@@ -1,99 +1,37 @@
1
1
  "use client";
2
- import "../chunk-ORMEWXMH.js";
2
+ import {
3
+ __objRest,
4
+ __spreadProps,
5
+ __spreadValues
6
+ } from "../chunk-ORMEWXMH.js";
3
7
  import { jsx, jsxs } from "react/jsx-runtime";
4
- import { forwardRef, useState, useId, useImperativeHandle, useRef } from "react";
5
- import { ChevronDown } from "lucide-react";
6
- import { createContext, useContext } from "react";
7
- const Ctx = createContext(null);
8
- const Accordion = forwardRef(function Accordion2(props, ref) {
9
- var _a, _b;
10
- const rootRef = useRef(null);
11
- useImperativeHandle(ref, () => rootRef.current);
12
- const isMulti = props.type === "multi";
13
- const [internalSingle, setInternalSingle] = useState(
14
- isMulti ? null : (_a = props.defaultValue) != null ? _a : null
15
- );
16
- const [internalMulti, setInternalMulti] = useState(
17
- isMulti ? (_b = props.defaultValue) != null ? _b : [] : []
18
- );
19
- const isControlled = props.value !== void 0;
20
- const isOpen = (v) => {
21
- if (isMulti) {
22
- const value2 = isControlled ? props.value : internalMulti;
23
- return value2.includes(v);
24
- }
25
- const value = isControlled ? props.value : internalSingle;
26
- return value === v;
27
- };
28
- const toggle = (v) => {
29
- var _a2, _b2;
30
- if (isMulti) {
31
- const current = isControlled ? props.value : internalMulti;
32
- const next = current.includes(v) ? current.filter((x) => x !== v) : [...current, v];
33
- if (!isControlled) setInternalMulti(next);
34
- (_a2 = props.onChange) == null ? void 0 : _a2.call(props, next);
35
- } else {
36
- const single = props;
37
- const current = isControlled ? props.value : internalSingle;
38
- const collapsible = single.collapsible !== false;
39
- const next = current === v ? collapsible ? null : current : v;
40
- if (!isControlled) setInternalSingle(next);
41
- (_b2 = single.onChange) == null ? void 0 : _b2.call(single, next);
8
+ import * as AccordionPrimitive from "@radix-ui/react-accordion";
9
+ import { ChevronDownIcon } from "./internal/icons.js";
10
+ function Accordion(_a) {
11
+ var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
12
+ const classes = ["rds-accordion", className].filter(Boolean).join(" ");
13
+ if (props.type === "multiple") {
14
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Root, __spreadProps(__spreadValues({}, props), { type: "multiple", className: classes, children }));
15
+ }
16
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Root, __spreadProps(__spreadValues({}, props), { type: "single", collapsible: true, className: classes, children }));
17
+ }
18
+ function AccordionItem({ value, title, titleAs = "h3", children, disabled, className }) {
19
+ const Title = titleAs;
20
+ return /* @__PURE__ */ jsxs(
21
+ AccordionPrimitive.Item,
22
+ {
23
+ value,
24
+ disabled,
25
+ className: ["rds-accordion__item", className].filter(Boolean).join(" "),
26
+ children: [
27
+ /* @__PURE__ */ jsx(AccordionPrimitive.Header, { asChild: true, children: /* @__PURE__ */ jsx(Title, { className: "rds-accordion__heading", children: /* @__PURE__ */ jsxs(AccordionPrimitive.Trigger, { className: "rds-accordion__trigger", children: [
28
+ /* @__PURE__ */ jsx("span", { className: "rds-accordion__title", children: title }),
29
+ /* @__PURE__ */ jsx("span", { className: "rds-accordion__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx(ChevronDownIcon, {}) })
30
+ ] }) }) }),
31
+ /* @__PURE__ */ jsx(AccordionPrimitive.Content, { className: "rds-accordion__content", children: /* @__PURE__ */ jsx("div", { className: "rds-accordion__body", children }) })
32
+ ]
42
33
  }
43
- };
44
- return /* @__PURE__ */ jsx(Ctx.Provider, { value: { isOpen, toggle }, children: /* @__PURE__ */ jsx("div", { ref: rootRef, className: ["border-y border-stroke-default divide-y divide-stroke-subtle", props.className].filter(Boolean).join(" "), children: props.children }) });
45
- });
46
- function AccordionItem({ value, title, meta, children, icon, disabled = false }) {
47
- const ctx = useContext(Ctx);
48
- if (!ctx) throw new Error("AccordionItem must be used inside Accordion");
49
- const open = ctx.isOpen(value);
50
- const id = useId();
51
- const headerId = `${id}-header`;
52
- const panelId = `${id}-panel`;
53
- return /* @__PURE__ */ jsxs("div", { children: [
54
- /* @__PURE__ */ jsx("h3", { children: /* @__PURE__ */ jsxs(
55
- "button",
56
- {
57
- type: "button",
58
- id: headerId,
59
- "aria-expanded": open,
60
- "aria-controls": panelId,
61
- disabled,
62
- onClick: () => ctx.toggle(value),
63
- className: [
64
- "w-full flex items-center gap-3 py-3 px-4 min-h-control-md text-left transition-colors",
65
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-stroke-focus focus-visible:ring-inset",
66
- "disabled:cursor-not-allowed disabled:opacity-50",
67
- "hover:bg-surface-raised"
68
- ].join(" "),
69
- children: [
70
- icon && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-fg-muted [&_svg]:size-4", children: icon }),
71
- /* @__PURE__ */ jsx("span", { className: "flex-1 font-medium text-fg-primary text-label", children: title }),
72
- meta && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-caption text-fg-muted", children: meta }),
73
- /* @__PURE__ */ jsx(
74
- ChevronDown,
75
- {
76
- size: 16,
77
- className: ["shrink-0 text-fg-muted transition-transform", open ? "rotate-180" : ""].join(" ")
78
- }
79
- )
80
- ]
81
- }
82
- ) }),
83
- /* @__PURE__ */ jsx(
84
- "div",
85
- {
86
- id: panelId,
87
- role: "region",
88
- "aria-labelledby": headerId,
89
- className: [
90
- "grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none",
91
- open ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
92
- ].join(" "),
93
- children: /* @__PURE__ */ jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "px-4 pb-4 text-label text-fg-secondary leading-relaxed", children }) })
94
- }
95
- )
96
- ] });
34
+ );
97
35
  }
98
36
  export {
99
37
  Accordion,
@@ -0,0 +1,24 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ interface ActionBarProps extends HTMLAttributes<HTMLDivElement> {
5
+ /** How many are selected, as shown and announced ("3 selecionados") (Figma: `count`). */
6
+ count: ReactNode;
7
+ /**
8
+ * The actions (Figma: slot `actions`). Use `tone="inverse"` Buttons (ghost): the bar is painted with
9
+ * colors/primary, which is what the inverse tone is drawn for, in light and in dark.
10
+ */
11
+ children: ReactNode;
12
+ /** Shows the X that clears the selection and is called when it is pressed (Figma: `showClear`). */
13
+ onClear?: () => void;
14
+ /** The X's accessible name. */
15
+ clearLabel?: string;
16
+ }
17
+ /**
18
+ * ActionBar — Figma [RDS] Actions/ActionBar. The bulk action bar: it shows while items are selected and
19
+ * leaves when the selection is cleared. It does not place itself: put it sticky or fixed at the foot of
20
+ * the area. Styles: action-bar.css.
21
+ */
22
+ declare function ActionBar({ count, children, onClear, clearLabel, className, ...rest }: ActionBarProps): react.JSX.Element;
23
+
24
+ export { ActionBar, type ActionBarProps };
@@ -0,0 +1,55 @@
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 { IconButton } from "./icon-button.js";
9
+ import { Tooltip } from "./tooltip.js";
10
+ import { CloseIcon } from "./internal/icons.js";
11
+ function ActionBar(_a) {
12
+ var _b = _a, {
13
+ count,
14
+ children,
15
+ onClear,
16
+ clearLabel = "Limpar sele\xE7\xE3o",
17
+ className
18
+ } = _b, rest = __objRest(_b, [
19
+ "count",
20
+ "children",
21
+ "onClear",
22
+ "clearLabel",
23
+ "className"
24
+ ]);
25
+ return /* @__PURE__ */ jsxs(
26
+ "div",
27
+ __spreadProps(__spreadValues({
28
+ role: "region",
29
+ "aria-label": "A\xE7\xF5es da sele\xE7\xE3o"
30
+ }, rest), {
31
+ className: ["rds-actionbar", className].filter(Boolean).join(" "),
32
+ children: [
33
+ /* @__PURE__ */ jsx("span", { className: "rds-actionbar__count", "aria-live": "polite", children: count }),
34
+ /* @__PURE__ */ jsx("span", { className: "rds-actionbar__divider", "aria-hidden": "true" }),
35
+ /* @__PURE__ */ jsxs("div", { className: "rds-actionbar__actions", children: [
36
+ children,
37
+ onClear && /* @__PURE__ */ jsx(Tooltip, { text: clearLabel, children: /* @__PURE__ */ jsx(
38
+ IconButton,
39
+ {
40
+ className: "rds-actionbar__clear",
41
+ icon: /* @__PURE__ */ jsx(CloseIcon, {}),
42
+ label: clearLabel,
43
+ tone: "inverse",
44
+ variant: "ghost",
45
+ onClick: onClear
46
+ }
47
+ ) })
48
+ ] })
49
+ ]
50
+ })
51
+ );
52
+ }
53
+ export {
54
+ ActionBar
55
+ };
@@ -0,0 +1,31 @@
1
+ import * as react from 'react';
2
+ import { ReactElement, ReactNode } from 'react';
3
+
4
+ type AlertDialogTone = 'danger' | 'action';
5
+ interface AlertDialogProps {
6
+ /** The element that opens it (a Button). Leave it out to control it with `open`. */
7
+ trigger?: ReactElement;
8
+ open?: boolean;
9
+ defaultOpen?: boolean;
10
+ onOpenChange?: (open: boolean) => void;
11
+ /** The question, with its object (Figma: `title`): "Excluir a lista Clientes?". */
12
+ title: ReactNode;
13
+ /** The consequence, including that it can't be undone (Figma: `description`). */
14
+ description: ReactNode;
15
+ /** danger when the action deletes or loses something; action when it only can't be taken back. */
16
+ tone?: AlertDialogTone;
17
+ /** The confirm button repeats the title's verb ("Excluir lista"), never a bare "Sim" or "OK". */
18
+ confirmLabel: string;
19
+ onConfirm: () => void;
20
+ cancelLabel?: string;
21
+ /** The veil over the page (Figma: `showScrim`). */
22
+ showScrim?: boolean;
23
+ }
24
+ /**
25
+ * AlertDialog — Figma [RDS] Feedback/AlertDialog. A question that interrupts before an action with no way back
26
+ * (Radix AlertDialog): role="alertdialog", the focus opens on Cancel and stays inside until it closes, then goes
27
+ * back to what opened it. Escape cancels; clicking outside does not close. Styles: alert-dialog.css.
28
+ */
29
+ declare function AlertDialog({ trigger, open, defaultOpen, onOpenChange, title, description, tone, confirmLabel, onConfirm, cancelLabel, showScrim, }: AlertDialogProps): react.JSX.Element;
30
+
31
+ export { AlertDialog, type AlertDialogProps, type AlertDialogTone };
@@ -0,0 +1,43 @@
1
+ "use client";
2
+ import "../chunk-ORMEWXMH.js";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
5
+ import { Button } from "./button.js";
6
+ function AlertDialog({
7
+ trigger,
8
+ open,
9
+ defaultOpen,
10
+ onOpenChange,
11
+ title,
12
+ description,
13
+ tone = "danger",
14
+ confirmLabel,
15
+ onConfirm,
16
+ cancelLabel = "Cancelar",
17
+ showScrim = true
18
+ }) {
19
+ return /* @__PURE__ */ jsxs(AlertDialogPrimitive.Root, { open, defaultOpen, onOpenChange, children: [
20
+ trigger && /* @__PURE__ */ jsx(AlertDialogPrimitive.Trigger, { asChild: true, children: trigger }),
21
+ /* @__PURE__ */ jsxs(AlertDialogPrimitive.Portal, { children: [
22
+ /* @__PURE__ */ jsx(
23
+ AlertDialogPrimitive.Overlay,
24
+ {
25
+ className: showScrim ? "rds-alert-dialog__scrim" : "rds-alert-dialog__scrim rds-alert-dialog__scrim--clear"
26
+ }
27
+ ),
28
+ /* @__PURE__ */ jsxs(AlertDialogPrimitive.Content, { className: "rds-alert-dialog", children: [
29
+ /* @__PURE__ */ jsxs("div", { className: "rds-alert-dialog__content", children: [
30
+ /* @__PURE__ */ jsx(AlertDialogPrimitive.Title, { className: "rds-alert-dialog__title", children: title }),
31
+ /* @__PURE__ */ jsx(AlertDialogPrimitive.Description, { className: "rds-alert-dialog__description", children: description })
32
+ ] }),
33
+ /* @__PURE__ */ jsxs("div", { className: "rds-alert-dialog__footer", children: [
34
+ /* @__PURE__ */ jsx(AlertDialogPrimitive.Cancel, { asChild: true, children: /* @__PURE__ */ jsx(Button, { tone: "neutral", variant: "outline", children: cancelLabel }) }),
35
+ /* @__PURE__ */ jsx(AlertDialogPrimitive.Action, { asChild: true, children: /* @__PURE__ */ jsx(Button, { tone, variant: "fill", onClick: onConfirm, children: confirmLabel }) })
36
+ ] })
37
+ ] })
38
+ ] })
39
+ ] });
40
+ }
41
+ export {
42
+ AlertDialog
43
+ };
@@ -1,24 +1,36 @@
1
1
  import * as react from 'react';
2
- import { ReactNode } from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
- type AlertVariant = 'success' | 'danger' | 'warning' | 'info' | 'neutral';
5
- interface AlertProps {
6
- variant?: AlertVariant;
7
- title?: ReactNode;
8
- children?: ReactNode;
9
- /** Botão close (X). */
4
+ type AlertTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
5
+ interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
6
+ /** danger went wrong; warning can still be avoided; success went right; info and neutral only inform. */
7
+ tone?: AlertTone;
8
+ /** What happened, in one line (Figma: `title`). */
9
+ title: ReactNode;
10
+ /** What to do about it (Figma: `showDescription` + `description`). */
11
+ description?: ReactNode;
12
+ /** The tone's icon (Figma: `showIcon`). Decorative: the title says the same in words. */
13
+ showIcon?: boolean;
14
+ /** One way out (Figma: `showAction`), usually a neutral ghost Button or a link rendered with Button asChild. */
15
+ action?: ReactNode;
16
+ /**
17
+ * Lets the person dismiss it (Figma: `showClose`): an × named by `closeLabel`. The Alert hides itself, calls
18
+ * this, and the focus moves to what comes next on the page.
19
+ */
10
20
  onClose?: () => void;
11
- /** Action button inline (label + onClick). */
12
- action?: {
13
- label: string;
14
- onClick: () => void;
15
- };
16
- /** Ícone customizado (substitui o default da variant). */
17
- icon?: ReactNode;
18
- /** Esconde o ícone. default = false. */
19
- hideIcon?: boolean;
20
- className?: string;
21
+ /** The ×'s accessible name. */
22
+ closeLabel?: string;
23
+ /**
24
+ * How it is announced. none (default): already on the page when it loads. status: it appears after
25
+ * something, calmly (role="status"). alert: it appears after an action and is urgent (role="alert").
26
+ */
27
+ announce?: 'none' | 'status' | 'alert';
21
28
  }
22
- declare function Alert({ variant, title, children, onClose, action, icon, hideIcon, className, }: AlertProps): react.JSX.Element;
29
+ /**
30
+ * Alert — Figma [RDS] Feedback/Alert. A message that stays on the screen, inside the content, while the situation
31
+ * lasts: what happened and what to do. One per screen. A short confirmation after an action is a Toast.
32
+ * Styles: alert.css.
33
+ */
34
+ declare function Alert({ tone, title, description, showIcon, action, onClose, closeLabel, announce, className, ...rest }: AlertProps): react.JSX.Element | null;
23
35
 
24
- export { Alert, type AlertProps, type AlertVariant };
36
+ export { Alert, type AlertProps, type AlertTone };