@cdx-ui/components 0.2.3 → 0.2.5

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 (296) hide show
  1. package/AGENTS.md +24 -0
  2. package/README.md +2 -0
  3. package/coverage.svg +1 -1
  4. package/docs/components/accordion/content.md +538 -0
  5. package/docs/components/alert/content.md +203 -0
  6. package/docs/components/alert-dialog/content.md +319 -0
  7. package/docs/components/avatar/content.md +368 -0
  8. package/docs/components/avatar/design.md +202 -0
  9. package/docs/components/badge/content.md +225 -0
  10. package/docs/components/bottom-sheet/content.md +353 -0
  11. package/docs/components/bottom-sheet/design.md +249 -0
  12. package/docs/components/box/content.md +141 -0
  13. package/docs/components/breadcrumbs/content.md +169 -0
  14. package/docs/components/button/content.md +398 -0
  15. package/docs/components/button/design.md +258 -0
  16. package/docs/components/calendar/content.md +137 -0
  17. package/docs/components/card/content.md +283 -0
  18. package/docs/components/carousel/content.md +417 -0
  19. package/docs/components/checkbox/content.md +236 -0
  20. package/docs/components/checkbox/design.md +214 -0
  21. package/docs/components/chip/content.md +439 -0
  22. package/docs/components/chip/design.md +418 -0
  23. package/docs/components/color-area/content.md +84 -0
  24. package/docs/components/color-field/content.md +132 -0
  25. package/docs/components/color-picker/content.md +209 -0
  26. package/docs/components/color-slider/content.md +118 -0
  27. package/docs/components/color-swatch/content.md +62 -0
  28. package/docs/components/color-swatch-picker/content.md +124 -0
  29. package/docs/components/content.md +98 -0
  30. package/docs/components/currency-input/content.md +205 -0
  31. package/docs/components/data-grid/content.md +521 -0
  32. package/docs/components/date-field/content.md +147 -0
  33. package/docs/components/date-picker/content.md +360 -0
  34. package/docs/components/date-range-picker/content.md +301 -0
  35. package/docs/components/date-time-field/content.md +157 -0
  36. package/docs/components/date-time-list/content.md +105 -0
  37. package/docs/components/date-time-picker/content.md +272 -0
  38. package/docs/components/dialog/content.md +436 -0
  39. package/docs/components/dialog/design.md +192 -0
  40. package/docs/components/divider/content.md +112 -0
  41. package/docs/components/drawer/content.md +428 -0
  42. package/docs/components/field/content.md +277 -0
  43. package/docs/components/form/content.md +62 -0
  44. package/docs/components/full-screen-dialog/content.md +881 -0
  45. package/docs/components/heading/content.md +55 -0
  46. package/docs/components/icon/content.md +190 -0
  47. package/docs/components/icon-button/content.md +200 -0
  48. package/docs/components/icon-button/design.md +165 -0
  49. package/docs/components/image/content.md +104 -0
  50. package/docs/components/input/content.md +346 -0
  51. package/docs/components/input/design.md +389 -0
  52. package/docs/components/insurance-disclosure/content.md +103 -0
  53. package/docs/components/link/content.md +180 -0
  54. package/docs/components/link/design.md +160 -0
  55. package/docs/components/list-item/content.md +695 -0
  56. package/docs/components/menu/content.md +1254 -0
  57. package/docs/components/month-calendar/content.md +84 -0
  58. package/docs/components/month-picker/content.md +273 -0
  59. package/docs/components/otp-input/content.md +327 -0
  60. package/docs/components/progress-bar/content.md +87 -0
  61. package/docs/components/progress-circle/content.md +176 -0
  62. package/docs/components/progress-segmented/content.md +119 -0
  63. package/docs/components/quick-action-button/content.md +154 -0
  64. package/docs/components/quick-action-button/design.md +170 -0
  65. package/docs/components/radio/content.md +224 -0
  66. package/docs/components/range-calendar/content.md +123 -0
  67. package/docs/components/reorderable-list/content.md +311 -0
  68. package/docs/components/scoped-theme/content.md +47 -0
  69. package/docs/components/scroll-shadow/content.md +693 -0
  70. package/docs/components/select/content.md +473 -0
  71. package/docs/components/select/design.md +301 -0
  72. package/docs/components/skeleton/content.md +104 -0
  73. package/docs/components/slider/content.md +423 -0
  74. package/docs/components/stack/content.md +161 -0
  75. package/docs/components/switch/content.md +150 -0
  76. package/docs/components/switch/design.md +208 -0
  77. package/docs/components/table/content.md +548 -0
  78. package/docs/components/table-pagination/content.md +177 -0
  79. package/docs/components/tabs/content.md +297 -0
  80. package/docs/components/text/content.md +142 -0
  81. package/docs/components/textarea/content.md +222 -0
  82. package/docs/components/tile/content.md +702 -0
  83. package/docs/components/toast/content.md +456 -0
  84. package/docs/components/toggle-button/content.md +505 -0
  85. package/docs/components/tooltip/content.md +350 -0
  86. package/docs/components/virtualized-list/content.md +250 -0
  87. package/docs/foundations/content.md +9 -0
  88. package/docs/foundations/expressions/icons/content.md +19 -0
  89. package/docs/foundations/styles/tokens/all-tokens/content.md +192 -0
  90. package/docs/foundations/styles/tokens/what-are-tokens/content.md +33 -0
  91. package/docs/foundations/styles/tokens/what-are-tokens/design.md +33 -0
  92. package/docs/getting-started/content.md +4 -0
  93. package/docs/getting-started/designers/content.md +13 -0
  94. package/docs/getting-started/designers/design.md +13 -0
  95. package/docs/getting-started/developers/accessibility/content.md +31 -0
  96. package/docs/getting-started/developers/content.md +612 -0
  97. package/docs/getting-started/developers/styling/content.md +195 -0
  98. package/docs/llms.txt +195 -0
  99. package/docs/patterns/account-management/content.md +75 -0
  100. package/docs/patterns/authentication/content.md +50 -0
  101. package/docs/patterns/content.md +10 -0
  102. package/docs/patterns/dashboard/content.md +34 -0
  103. package/docs/patterns/empty-states/content.md +32 -0
  104. package/docs/patterns/forms/content.md +108 -0
  105. package/docs/patterns/onboarding/content.md +69 -0
  106. package/docs/patterns/payments/content.md +35 -0
  107. package/docs/patterns/settings/content.md +72 -0
  108. package/docs/resources/content.md +9 -0
  109. package/docs/resources/figma-libraries/content.md +42 -0
  110. package/docs/resources/release-notes/0.0.1-beta.118/content.md +27 -0
  111. package/docs/resources/release-notes/0.0.1-beta.122/content.md +21 -0
  112. package/docs/resources/release-notes/0.0.1-beta.124/content.md +16 -0
  113. package/docs/resources/release-notes/0.0.1-beta.126/content.md +10 -0
  114. package/docs/resources/release-notes/0.0.1-beta.127/content.md +14 -0
  115. package/docs/resources/release-notes/0.0.1-beta.128/content.md +9 -0
  116. package/docs/resources/release-notes/0.0.1-beta.129/content.md +18 -0
  117. package/docs/resources/release-notes/0.0.1-beta.130/content.md +18 -0
  118. package/docs/resources/release-notes/0.0.1-beta.133/content.md +7 -0
  119. package/docs/resources/release-notes/0.0.1-beta.134/content.md +17 -0
  120. package/docs/resources/release-notes/0.0.1-beta.136/content.md +7 -0
  121. package/docs/resources/release-notes/0.0.1-beta.137/content.md +10 -0
  122. package/docs/resources/release-notes/0.0.1-beta.138/content.md +7 -0
  123. package/docs/resources/release-notes/0.0.1-beta.139/content.md +13 -0
  124. package/docs/resources/release-notes/0.0.1-beta.140/content.md +26 -0
  125. package/docs/resources/release-notes/0.0.1-beta.141/content.md +63 -0
  126. package/docs/resources/release-notes/0.0.1-beta.142/content.md +7 -0
  127. package/docs/resources/release-notes/0.0.1-beta.143/content.md +12 -0
  128. package/docs/resources/release-notes/0.0.1-beta.144/content.md +7 -0
  129. package/docs/resources/release-notes/0.0.1-beta.145/content.md +7 -0
  130. package/docs/resources/release-notes/0.0.1-beta.147/content.md +10 -0
  131. package/docs/resources/release-notes/0.0.1-beta.149/content.md +10 -0
  132. package/docs/resources/release-notes/0.0.1-beta.150/content.md +13 -0
  133. package/docs/resources/release-notes/0.0.1-beta.152/content.md +7 -0
  134. package/docs/resources/release-notes/0.0.1-beta.154/content.md +15 -0
  135. package/docs/resources/release-notes/0.0.1-beta.156/content.md +7 -0
  136. package/docs/resources/release-notes/0.0.1-beta.158/content.md +9 -0
  137. package/docs/resources/release-notes/0.0.1-beta.159/content.md +11 -0
  138. package/docs/resources/release-notes/0.0.1-beta.160/content.md +7 -0
  139. package/docs/resources/release-notes/0.0.1-beta.161/content.md +7 -0
  140. package/docs/resources/release-notes/0.0.1-beta.163/content.md +7 -0
  141. package/docs/resources/release-notes/0.0.1-beta.164/content.md +9 -0
  142. package/docs/resources/release-notes/0.0.1-beta.166/content.md +17 -0
  143. package/docs/resources/release-notes/0.0.1-beta.167/content.md +7 -0
  144. package/docs/resources/release-notes/0.0.1-beta.168/content.md +7 -0
  145. package/docs/resources/release-notes/0.0.1-beta.169/content.md +7 -0
  146. package/docs/resources/release-notes/0.0.1-beta.171/content.md +16 -0
  147. package/docs/resources/release-notes/0.0.1-beta.172/content.md +24 -0
  148. package/docs/resources/release-notes/0.0.1-beta.173/content.md +15 -0
  149. package/docs/resources/release-notes/0.0.1-beta.174/content.md +7 -0
  150. package/docs/resources/release-notes/0.0.1-beta.176/content.md +32 -0
  151. package/docs/resources/release-notes/0.0.1-beta.179/content.md +11 -0
  152. package/docs/resources/release-notes/0.0.1-beta.182/content.md +13 -0
  153. package/docs/resources/release-notes/0.0.1-beta.185/content.md +7 -0
  154. package/docs/resources/release-notes/0.0.1-beta.187/content.md +27 -0
  155. package/docs/resources/release-notes/0.1.1/content.md +23 -0
  156. package/docs/resources/release-notes/0.1.2/content.md +7 -0
  157. package/docs/resources/release-notes/0.1.4/content.md +19 -0
  158. package/docs/resources/release-notes/0.1.5/content.md +7 -0
  159. package/docs/resources/release-notes/0.1.6/content.md +7 -0
  160. package/docs/resources/release-notes/0.2.0/content.md +31 -0
  161. package/docs/resources/release-notes/0.2.1/content.md +17 -0
  162. package/docs/resources/release-notes/0.2.2/content.md +11 -0
  163. package/docs/resources/release-notes/0.2.3/content.md +15 -0
  164. package/docs/resources/release-notes/0.2.4/content.md +17 -0
  165. package/docs/resources/release-notes/content.md +65 -0
  166. package/lib/commonjs/components/Box/Box.js +9 -1
  167. package/lib/commonjs/components/Box/Box.js.map +1 -1
  168. package/lib/commonjs/components/Breadcrumbs/index.js +28 -3
  169. package/lib/commonjs/components/Breadcrumbs/index.js.map +1 -1
  170. package/lib/commonjs/components/Breadcrumbs/styles.js +27 -0
  171. package/lib/commonjs/components/Breadcrumbs/styles.js.map +1 -1
  172. package/lib/commonjs/components/DateTimeList/index.js +11 -26
  173. package/lib/commonjs/components/DateTimeList/index.js.map +1 -1
  174. package/lib/commonjs/components/DateTimeList/styles.js +2 -12
  175. package/lib/commonjs/components/DateTimeList/styles.js.map +1 -1
  176. package/lib/commonjs/components/ListItem/index.js.map +1 -1
  177. package/lib/commonjs/components/ListItem/styles.js +2 -1
  178. package/lib/commonjs/components/ListItem/styles.js.map +1 -1
  179. package/lib/commonjs/components/Menu/index.js +11 -5
  180. package/lib/commonjs/components/Menu/index.js.map +1 -1
  181. package/lib/commonjs/components/ScrollShadow/gradient.js +29 -0
  182. package/lib/commonjs/components/ScrollShadow/gradient.js.map +1 -0
  183. package/lib/commonjs/components/ScrollShadow/index.js +171 -44
  184. package/lib/commonjs/components/ScrollShadow/index.js.map +1 -1
  185. package/lib/commonjs/components/ScrollShadow/styles.js +58 -14
  186. package/lib/commonjs/components/ScrollShadow/styles.js.map +1 -1
  187. package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js +63 -0
  188. package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
  189. package/lib/commonjs/components/ScrollShadow/useScrollShadow.js +48 -8
  190. package/lib/commonjs/components/ScrollShadow/useScrollShadow.js.map +1 -1
  191. package/lib/commonjs/components/Stack/HStack.js +6 -2
  192. package/lib/commonjs/components/Stack/HStack.js.map +1 -1
  193. package/lib/commonjs/components/Stack/VStack.js +6 -2
  194. package/lib/commonjs/components/Stack/VStack.js.map +1 -1
  195. package/lib/commonjs/components/Tabs/index.js +16 -23
  196. package/lib/commonjs/components/Tabs/index.js.map +1 -1
  197. package/lib/commonjs/components/Tabs/styles.js +1 -10
  198. package/lib/commonjs/components/Tabs/styles.js.map +1 -1
  199. package/lib/commonjs/figma/ListItem.SectionHeader.figma.js +20 -5
  200. package/lib/commonjs/figma/ListItem.SectionHeader.figma.js.map +1 -1
  201. package/lib/commonjs/index.js +10 -10
  202. package/lib/commonjs/index.js.map +1 -1
  203. package/lib/module/components/Box/Box.js +9 -1
  204. package/lib/module/components/Box/Box.js.map +1 -1
  205. package/lib/module/components/Breadcrumbs/index.js +29 -4
  206. package/lib/module/components/Breadcrumbs/index.js.map +1 -1
  207. package/lib/module/components/Breadcrumbs/styles.js +26 -0
  208. package/lib/module/components/Breadcrumbs/styles.js.map +1 -1
  209. package/lib/module/components/DateTimeList/index.js +12 -27
  210. package/lib/module/components/DateTimeList/index.js.map +1 -1
  211. package/lib/module/components/DateTimeList/styles.js +1 -11
  212. package/lib/module/components/DateTimeList/styles.js.map +1 -1
  213. package/lib/module/components/ListItem/index.js.map +1 -1
  214. package/lib/module/components/ListItem/styles.js +2 -1
  215. package/lib/module/components/ListItem/styles.js.map +1 -1
  216. package/lib/module/components/Menu/index.js +11 -5
  217. package/lib/module/components/Menu/index.js.map +1 -1
  218. package/lib/module/components/ScrollShadow/gradient.js +24 -0
  219. package/lib/module/components/ScrollShadow/gradient.js.map +1 -0
  220. package/lib/module/components/ScrollShadow/index.js +170 -48
  221. package/lib/module/components/ScrollShadow/index.js.map +1 -1
  222. package/lib/module/components/ScrollShadow/styles.js +57 -13
  223. package/lib/module/components/ScrollShadow/styles.js.map +1 -1
  224. package/lib/module/components/ScrollShadow/useComposedScrollHandler.js +57 -0
  225. package/lib/module/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
  226. package/lib/module/components/ScrollShadow/useScrollShadow.js +46 -8
  227. package/lib/module/components/ScrollShadow/useScrollShadow.js.map +1 -1
  228. package/lib/module/components/Stack/HStack.js +6 -2
  229. package/lib/module/components/Stack/HStack.js.map +1 -1
  230. package/lib/module/components/Stack/VStack.js +6 -2
  231. package/lib/module/components/Stack/VStack.js.map +1 -1
  232. package/lib/module/components/Tabs/index.js +17 -24
  233. package/lib/module/components/Tabs/index.js.map +1 -1
  234. package/lib/module/components/Tabs/styles.js +0 -9
  235. package/lib/module/components/Tabs/styles.js.map +1 -1
  236. package/lib/module/figma/ListItem.SectionHeader.figma.js +20 -5
  237. package/lib/module/figma/ListItem.SectionHeader.figma.js.map +1 -1
  238. package/lib/module/index.js +6 -1
  239. package/lib/module/index.js.map +1 -1
  240. package/lib/typescript/animation/hooks/usePopupDialogContentAnimation.d.ts +2 -2
  241. package/lib/typescript/animation/hooks/usePopupOverlayAnimation.d.ts +2 -2
  242. package/lib/typescript/components/Box/Box.d.ts +4 -0
  243. package/lib/typescript/components/Box/Box.d.ts.map +1 -1
  244. package/lib/typescript/components/Breadcrumbs/index.d.ts +3 -1
  245. package/lib/typescript/components/Breadcrumbs/index.d.ts.map +1 -1
  246. package/lib/typescript/components/Breadcrumbs/styles.d.ts +2 -0
  247. package/lib/typescript/components/Breadcrumbs/styles.d.ts.map +1 -1
  248. package/lib/typescript/components/DateTimeList/index.d.ts.map +1 -1
  249. package/lib/typescript/components/DateTimeList/styles.d.ts +1 -4
  250. package/lib/typescript/components/DateTimeList/styles.d.ts.map +1 -1
  251. package/lib/typescript/components/ListItem/index.d.ts +5 -4
  252. package/lib/typescript/components/ListItem/index.d.ts.map +1 -1
  253. package/lib/typescript/components/ListItem/styles.d.ts +1 -1
  254. package/lib/typescript/components/ListItem/styles.d.ts.map +1 -1
  255. package/lib/typescript/components/Menu/index.d.ts.map +1 -1
  256. package/lib/typescript/components/ScrollShadow/gradient.d.ts +7 -0
  257. package/lib/typescript/components/ScrollShadow/gradient.d.ts.map +1 -0
  258. package/lib/typescript/components/ScrollShadow/index.d.ts +57 -15
  259. package/lib/typescript/components/ScrollShadow/index.d.ts.map +1 -1
  260. package/lib/typescript/components/ScrollShadow/styles.d.ts +8 -2
  261. package/lib/typescript/components/ScrollShadow/styles.d.ts.map +1 -1
  262. package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts +13 -0
  263. package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts.map +1 -0
  264. package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts +15 -2
  265. package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts.map +1 -1
  266. package/lib/typescript/components/Stack/HStack.d.ts +3 -2
  267. package/lib/typescript/components/Stack/HStack.d.ts.map +1 -1
  268. package/lib/typescript/components/Stack/VStack.d.ts +3 -2
  269. package/lib/typescript/components/Stack/VStack.d.ts.map +1 -1
  270. package/lib/typescript/components/Tabs/index.d.ts.map +1 -1
  271. package/lib/typescript/components/Tabs/styles.d.ts +0 -7
  272. package/lib/typescript/components/Tabs/styles.d.ts.map +1 -1
  273. package/lib/typescript/components/Toast/animation.d.ts +3 -3
  274. package/lib/typescript/components/Toast/animation.d.ts.map +1 -1
  275. package/lib/typescript/figma/ListItem.SectionHeader.figma.d.ts.map +1 -1
  276. package/lib/typescript/index.d.ts +6 -1
  277. package/lib/typescript/index.d.ts.map +1 -1
  278. package/package.json +11 -9
  279. package/src/components/Box/Box.tsx +18 -4
  280. package/src/components/Breadcrumbs/index.tsx +28 -4
  281. package/src/components/Breadcrumbs/styles.ts +30 -0
  282. package/src/components/DateTimeList/index.tsx +13 -26
  283. package/src/components/DateTimeList/styles.ts +1 -10
  284. package/src/components/ListItem/index.tsx +5 -4
  285. package/src/components/ListItem/styles.ts +1 -0
  286. package/src/components/Menu/index.tsx +11 -8
  287. package/src/components/ScrollShadow/gradient.ts +48 -0
  288. package/src/components/ScrollShadow/index.tsx +300 -69
  289. package/src/components/ScrollShadow/styles.ts +45 -28
  290. package/src/components/ScrollShadow/useComposedScrollHandler.ts +58 -0
  291. package/src/components/ScrollShadow/useScrollShadow.ts +72 -10
  292. package/src/components/Stack/HStack.tsx +8 -4
  293. package/src/components/Stack/VStack.tsx +8 -4
  294. package/src/components/Tabs/index.tsx +25 -35
  295. package/src/components/Tabs/styles.ts +0 -9
  296. package/src/index.ts +8 -1
@@ -0,0 +1,456 @@
1
+ # Toast (https://design.candescent.com/docs/components/toast)
2
+
3
+ Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=5170-8043), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/feedback-toast--default)
4
+
5
+ A stacking notification surface shown imperatively through `useToast()`. Toasts auto-dismiss, can be swiped away on native, and are rendered by the provider rather than at the call site.
6
+
7
+ ```tsx
8
+ import { Toast, ToastProvider, useToast } from '@cdx-ui/components';
9
+ ```
10
+
11
+ > [!WARNING]
12
+ >
13
+ > **Provider required**
14
+ >
15
+ > Mount `ToastProvider` once near your app root — `ForgeDesignProvider` includes it automatically.
16
+ > `useToast()` throws when no provider is above it in the tree.
17
+
18
+ ## Basic
19
+
20
+ The provider owns the toast viewport, so a toast anchors to the edge of the window no matter where `toast.show()` was called from.
21
+
22
+ ```tsx
23
+ import { Button, useToast } from '@cdx-ui/components';
24
+
25
+ export default function ToastBasicDemo() {
26
+ const { toast } = useToast();
27
+
28
+ return (
29
+ <Button
30
+ onPress={() =>
31
+ toast.show({
32
+ label: 'Payment scheduled',
33
+ description: 'Your $250.00 payment will be sent on Friday.',
34
+ })
35
+ }
36
+ >
37
+ <Button.Label>Show toast</Button.Label>
38
+ </Button>
39
+ );
40
+ }
41
+ ```
42
+
43
+ ## Colors
44
+
45
+ `color` sets the surface fill and the title, description, and icon. `neutral` is a dark inverse surface; status values use the matching subtle fill and on-subtle content color.
46
+
47
+ ```tsx
48
+ import { Button, HStack, useToast, type ToastColor } from '@cdx-ui/components';
49
+
50
+ const scenarios: {
51
+ color: ToastColor;
52
+ buttonColor: 'action' | 'danger' | 'warning' | 'success';
53
+ label: string;
54
+ description: string;
55
+ }[] = [
56
+ {
57
+ color: 'neutral',
58
+ buttonColor: 'action',
59
+ label: 'Statement ready',
60
+ description: 'Your July statement is available to download.',
61
+ },
62
+ {
63
+ color: 'info',
64
+ buttonColor: 'action',
65
+ label: 'Scheduled maintenance',
66
+ description: 'Transfers are unavailable Sunday from 1–3 AM ET.',
67
+ },
68
+ {
69
+ color: 'success',
70
+ buttonColor: 'success',
71
+ label: 'Transfer complete',
72
+ description: '$250.00 was sent to Jordan Ellis.',
73
+ },
74
+ {
75
+ color: 'warning',
76
+ buttonColor: 'warning',
77
+ label: 'Low balance',
78
+ description: 'Everyday Checking is below your $100.00 alert threshold.',
79
+ },
80
+ {
81
+ color: 'danger',
82
+ buttonColor: 'danger',
83
+ label: 'Payment failed',
84
+ description: 'The card ending in 4821 was declined.',
85
+ },
86
+ ];
87
+
88
+ export default function ToastColorsDemo() {
89
+ const { toast } = useToast();
90
+
91
+ return (
92
+ <HStack space="sm" className="flex-wrap justify-center">
93
+ {scenarios.map((scenario) => (
94
+ <Button
95
+ key={scenario.color}
96
+ variant="outline"
97
+ color={scenario.buttonColor}
98
+ onPress={() =>
99
+ toast.show({
100
+ color: scenario.color,
101
+ label: scenario.label,
102
+ description: scenario.description,
103
+ })
104
+ }
105
+ >
106
+ <Button.Label>{scenario.color}</Button.Label>
107
+ </Button>
108
+ ))}
109
+ </HStack>
110
+ );
111
+ }
112
+ ```
113
+
114
+ ## Placements
115
+
116
+ On web, `-start` and `-end` pin the toast to that horizontal edge and cap it at 460 px; plain `top` and `bottom` center it. On native every value spans the full width. Each placement maintains an independent stack, so toasts elsewhere do not affect its index, visibility, or animation.
117
+
118
+ ```tsx
119
+ import { Button, HStack, useToast, type ToastPlacement } from '@cdx-ui/components';
120
+
121
+ const placements: ToastPlacement[] = [
122
+ 'top-start',
123
+ 'top',
124
+ 'top-end',
125
+ 'bottom-start',
126
+ 'bottom',
127
+ 'bottom-end',
128
+ ];
129
+
130
+ export default function ToastPlacementsDemo() {
131
+ const { toast } = useToast();
132
+
133
+ return (
134
+ <HStack space="sm" className="flex-wrap justify-center">
135
+ {placements.map((placement) => (
136
+ <Button
137
+ key={placement}
138
+ variant="outline"
139
+ onPress={() =>
140
+ toast.show({
141
+ placement,
142
+ label: `Placed at ${placement}`,
143
+ })
144
+ }
145
+ >
146
+ <Button.Label>{placement}</Button.Label>
147
+ </Button>
148
+ ))}
149
+ </HStack>
150
+ );
151
+ }
152
+ ```
153
+
154
+ ## With icon
155
+
156
+ Pass a Forge icon to `icon`. It renders through `Toast.Icon`, so it picks up the toast's color automatically.
157
+
158
+ ```tsx
159
+ import { CheckCircle } from '@cdx-ui/icons';
160
+ import { Button, useToast } from '@cdx-ui/components';
161
+
162
+ export default function ToastWithIconDemo() {
163
+ const { toast } = useToast();
164
+
165
+ return (
166
+ <Button
167
+ variant="outline"
168
+ color="success"
169
+ onPress={() =>
170
+ toast.show({
171
+ color: 'success',
172
+ icon: CheckCircle,
173
+ label: 'Direct deposit received',
174
+ description: '$1,200.00 was added to Everyday Checking.',
175
+ })
176
+ }
177
+ >
178
+ <Button.Label>Show toast with icon</Button.Label>
179
+ </Button>
180
+ );
181
+ }
182
+ ```
183
+
184
+ ## With action
185
+
186
+ `onActionPress` receives `{ show, hide }` so an action can dismiss the current toast and confirm the result. Dismissal is not automatic — call `hide()` yourself.
187
+
188
+ ```tsx
189
+ import { Button, useToast } from '@cdx-ui/components';
190
+
191
+ export default function ToastWithActionDemo() {
192
+ const { toast } = useToast();
193
+
194
+ return (
195
+ <Button
196
+ variant="outline"
197
+ onPress={() =>
198
+ toast.show({
199
+ label: 'Payee deleted',
200
+ description: 'Jordan Ellis was removed from your saved payees.',
201
+ actionLabel: 'Undo',
202
+ onActionPress: ({ hide, show }) => {
203
+ hide();
204
+ show({ color: 'success', label: 'Payee restored' });
205
+ },
206
+ })
207
+ }
208
+ >
209
+ <Button.Label>Delete payee</Button.Label>
210
+ </Button>
211
+ );
212
+ }
213
+ ```
214
+
215
+ ## Persistent
216
+
217
+ Set `duration: 'persistent'` for progress that ends on a real event instead of a timer, and pass an explicit `id` so you can dismiss it later. Re-showing an `id` that is already visible is a no-op.
218
+
219
+ ```tsx
220
+ import { Sync } from '@cdx-ui/icons';
221
+ import { Button, HStack, useToast } from '@cdx-ui/components';
222
+
223
+ const UPLOAD_TOAST_ID = 'check-deposit-upload';
224
+
225
+ export default function ToastPersistentDemo() {
226
+ const { toast } = useToast();
227
+
228
+ return (
229
+ <HStack space="sm" className="flex-wrap justify-center">
230
+ <Button
231
+ variant="outline"
232
+ onPress={() =>
233
+ toast.show({
234
+ id: UPLOAD_TOAST_ID,
235
+ color: 'info',
236
+ icon: Sync,
237
+ label: 'Uploading check images',
238
+ description: 'Keep this screen open until the upload finishes.',
239
+ duration: 'persistent',
240
+ })
241
+ }
242
+ >
243
+ <Button.Label>Start upload</Button.Label>
244
+ </Button>
245
+ <Button variant="ghost" onPress={() => toast.hide(UPLOAD_TOAST_ID)}>
246
+ <Button.Label>Finish upload</Button.Label>
247
+ </Button>
248
+ </HStack>
249
+ );
250
+ }
251
+ ```
252
+
253
+ ## Custom content
254
+
255
+ Use `component` to compose the toast from its sub-components. Spread the supplied props onto `Toast` — they carry the placement-specific stacking metrics and dismissal wiring that `Toast.Close` depends on. Place the sub-components as direct children; `Toast` lays them out for you, with the icon first, the title and description stacked beside it, and the action and close controls at the end, so no wrapper or layout `className` is needed. Set custom placement on `toast.show({ placement, component })` so the provider can assign the correct stack.
256
+
257
+ ```tsx
258
+ import { CheckCircle } from '@cdx-ui/icons';
259
+ import { Button, Toast, useToast, type ToastComponentProps } from '@cdx-ui/components';
260
+
261
+ export default function ToastCustomComponentDemo() {
262
+ const { toast } = useToast();
263
+
264
+ return (
265
+ <Button
266
+ variant="outline"
267
+ color="success"
268
+ onPress={() =>
269
+ toast.show({
270
+ duration: 6000,
271
+ component: (props: ToastComponentProps) => (
272
+ <Toast {...props} color="success">
273
+ <Toast.Icon as={CheckCircle} />
274
+ <Toast.Title>Mobile deposit submitted</Toast.Title>
275
+ <Toast.Description>
276
+ $725.00 is under review. Up to $225.00 may be available today.
277
+ </Toast.Description>
278
+ <Toast.Close />
279
+ </Toast>
280
+ ),
281
+ })
282
+ }
283
+ >
284
+ <Button.Label>Submit deposit</Button.Label>
285
+ </Button>
286
+ );
287
+ }
288
+ ```
289
+
290
+ ## API
291
+
292
+ ### Toast
293
+
294
+ The presentational root, used only inside a `component` render function. Stacking and dismissal props are supplied by the provider.
295
+
296
+ Whatever the JSX order, the root renders its direct children as a row: the first `Toast.Icon`, then a column holding every other child, then each `Toast.Action` and `Toast.Close` in source order. The column is omitted when it would be empty. A wrapper you place around `Toast.Title` and `Toast.Description` yourself still works; it renders inside the column.
297
+
298
+ `Toast.Icon`, `Toast.Action`, and `Toast.Close` are matched by component identity. Wrapping one in `memo()`, an HOC, or a custom component moves it into the column. Extra icons are not rendered.
299
+
300
+ | Prop | Type | Default | Description |
301
+ | --- | --- | --- | --- |
302
+ | `className?` | `string` | — | Additional CSS class for the toast container |
303
+ | `children?` | `ReactNode` | — | Laid out automatically: the first `Toast.Icon` at the start, `Toast.Action` and `Toast.Close` at the end, and everything else in a text column between them. Additional `Toast.Icon` children are dropped. `Toast.Icon`, `Toast.Action`, and `Toast.Close` must be **direct** children — wrapping them in `memo()` or an HOC hides them from the layout, and they render in the text column instead. |
304
+ | `role?` | `'status' \| 'alert'` | `'status'` | ARIA role for the toast element. Use `'alert'` for urgent/danger toasts that require assertive announcements. |
305
+ | `color?` | `'neutral' \| 'info' \| 'success' \| 'warning' \| 'danger' \| 'default' \| null` | `'neutral'` | Color of the toast |
306
+ | `animation?` | `ToastRootAnimation` | — | Animation configuration for toast - `false` or `"disabled"`: Disable only root animations - `"disable-all"`: Disable all animations including children - `true` or `undefined`: Use default animations - `object`: Custom animation configuration |
307
+ | `isSwipeable?` | `boolean` | `true` | Whether the toast can be swiped to dismiss and dragged with rubber effect |
308
+ | `isAnimatedStyleActive?` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active When `false`, the animated style is removed and you can implement custom logic This prop should only be used when you want to write custom styling logic instead of the default animated styles |
309
+ | `asChild?` | `boolean` | — | — |
310
+
311
+ Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props), except `role`. `color="default"` is deprecated; use `neutral` instead.
312
+
313
+ `opacity`, `transform`, and `height` are driven by the stacking animation and cannot be set through `className`. Customize them with `animation`, or set `isAnimatedStyleActive={false}` to take over styling entirely.
314
+
315
+ ### ToastProvider
316
+
317
+ Mounts the toast viewport and supplies the manager returned by `useToast()`.
318
+
319
+ | Prop | Type | Default | Description |
320
+ | --- | --- | --- | --- |
321
+ | `disableFullWindowOverlay?` | `boolean` | `false` | When true, uses a regular View instead of FullWindowOverlay on iOS for toasts. Enables React Native element inspector but toasts won't appear above native modals. |
322
+ | `unstable_accessibilityContainerViewIsModal?` | `boolean` | `false` | Controls whether VoiceOver treats the toast overlay window as a modal container. When `false`, VoiceOver can still access elements behind the overlay. When `true`, VoiceOver is restricted to elements inside the overlay. |
323
+ | `defaultProps?` | `ToastGlobalConfig` | — | Global toast configuration These values are used as defaults for all toasts unless overridden locally Local configs have precedence over global config |
324
+ | `insets?` | `ToastInsets` | `Platform-specific: - iOS: { top: 0, bottom: 6, left: 12, right: 12 } - Android: { top: 12, bottom: 12, left: 12, right: 12 }` | Insets for spacing from screen edges (added to safe area insets) |
325
+ | `maxVisibleToasts?` | `number` | `3` | Maximum number of visible toasts before opacity starts fading Controls when toast items begin to fade out as they move beyond the visible stack |
326
+ | `contentWrapper?` | `((children: React.ReactNode) => React.ReactElement)` | — | Custom wrapper function to wrap the toast content Receives children and should return a component that wraps them The wrapper should apply flex: 1 (via className or style) to ensure proper layout and `pointerEvents: 'box-none'` so it does not block interaction with the page behind. On web, `box-none` only takes effect from a `StyleSheet.create` style, not an inline object. Can be any component wrapper - KeyboardAvoidingView, View, or any custom component |
327
+ | `announceLabel?` | `string` | `'Notifications'` | Accessible label for the toast notification region on web. Screen readers announce this as the landmark name for the ARIA live region that wraps all visible toasts. |
328
+ | `container?` | `Element \| null` | — | Element that receives the toast viewport instead of `document.body`. Use it to keep toasts inside an embedded surface, such as a device preview. The fixed viewport stays inside the container only when an ancestor of it creates a containing block for fixed descendants, for example through a `transform`. While `null`, such as before a callback ref attaches, no viewport renders. |
329
+ | `children?` | `React.ReactNode` | — | Children to render |
330
+
331
+ Values in `defaultProps` apply to every toast; per-toast options passed to `toast.show()` win. `insets` are added to the safe-area insets — iOS defaults to `{ top: 0, bottom: 6, left: 12, right: 12 }` and Android to `12` on all edges. On web, pass a `container` element to keep the viewport inside an embedded surface such as a device preview instead of `document.body`.
332
+
333
+ ## Sub-components
334
+
335
+ ### Toast.Title
336
+
337
+ Headline text, rendered with `role="heading"` and `aria-level={3}` and colored by the parent toast's `color`.
338
+
339
+ | Prop | Type | Default | Description |
340
+ | --- | --- | --- | --- |
341
+ | `children?` | `ReactNode` | — | Content to be rendered as title |
342
+ | `className?` | `string` | — | Additional CSS class for the title |
343
+
344
+ Remaining props are forwarded to the underlying [`Text`](https://design.candescent.com/docs/components/text/content.md).
345
+
346
+ ### Toast.Description
347
+
348
+ Body text, colored by the parent toast's `color`.
349
+
350
+ | Prop | Type | Default | Description |
351
+ | --- | --- | --- | --- |
352
+ | `children?` | `ReactNode` | — | Content to be rendered as description |
353
+ | `className?` | `string` | — | Additional CSS class for the description |
354
+
355
+ Remaining props are forwarded to the underlying [`Text`](https://design.candescent.com/docs/components/text/content.md).
356
+
357
+ ### Toast.Icon
358
+
359
+ Leading glyph. Renders nothing unless `as` or `asChild` is provided.
360
+
361
+ | Prop | Type | Default | Description |
362
+ | --- | --- | --- | --- |
363
+ | `className?` | `string` | — | Utility classes for size (`size-*`) and placement, merged after the defaults. |
364
+ | `children?` | `ReactNode` | — | Child element to render when `asChild` is set. |
365
+ | `filled?` | `boolean` | — | When `true`, renders the filled variant of the icon (if available). Defaults to `false` (outlined). |
366
+ | `size?` | `string \| number` | — | Width and height of the icon, in pixels or any SVG length. The bare icon renders at 24 when omitted. |
367
+ | `data-testid?` | `string` | — | Test identifier forwarded to the rendered SVG. |
368
+ | `as?` | `ForgeIcon` | — | Forge icon component to render. Required unless `asChild` is set. |
369
+ | `asChild?` | `boolean` | — | — |
370
+
371
+ ### Toast.Action
372
+
373
+ Action control rendered as a [`Button`](https://design.candescent.com/docs/components/button/content.md) and accepting all of its props. Defaults to `variant="outline"` and `size="small"`, with `color` derived from the toast's `color` (`neutral` maps to `action`). On a `neutral` toast the action label and border use inverse content color so they stay legible on the dark surface; an explicit `color` still wins. Children are wrapped in `Button.Label` automatically.
374
+
375
+ ### Toast.Close
376
+
377
+ Dismiss control rendered as an [`IconButton`](https://design.candescent.com/docs/components/icon-button/content.md) and accepting all of its props except `as`, which is narrowed to a `ForgeIcon`. Defaults to `variant="ghost"`, `size="small"`, `aria-label="Close"`, and the close glyph. Pressing it hides the parent toast, so no `onPress` is required; a supplied `onPress` runs in addition.
378
+
379
+ ## Hook
380
+
381
+ ### useToast
382
+
383
+ Returns the toast manager and current visibility:
384
+
385
+ ```tsx
386
+ const { toast, isToastVisible } = useToast();
387
+ ```
388
+
389
+ | Return | Type | Description |
390
+ | ---------------- | -------------- | -------------------------------------------------------- |
391
+ | `toast` | `ToastManager` | Imperative API — `show`, `hide`, `pauseAll`, `resumeAll` |
392
+ | `isToastVisible` | `boolean` | Whether any toast is currently displayed |
393
+
394
+ ### toast.show
395
+
396
+ Displays a toast and returns its id. Accepts three shapes:
397
+
398
+ | Argument | Result |
399
+ | --------------------------------------- | ------------------------------------------------------- |
400
+ | `toast.show('Saved')` | Default toast using the string as its title |
401
+ | `toast.show({ label, description, … })` | Default toast, fully configured |
402
+ | `toast.show({ component })` | Custom layout built from `Toast` and its sub-components |
403
+
404
+ `component` cannot be combined with the styling and content options below.
405
+
406
+ | Prop | Type | Default | Description |
407
+ | --- | --- | --- | --- |
408
+ | `duration?` | `number \| "persistent"` | `4000` | Duration in milliseconds before the toast automatically disappears Set to `'persistent'` to prevent auto-hide (toast will remain until manually dismissed) |
409
+ | `id?` | `string` | — | Optional ID for the toast. If omitted, one is generated. If a toast with this id is already in the stack, `show` returns that id and does not add another. |
410
+ | `label?` | `string` | — | Label text for the toast |
411
+ | `description?` | `string` | — | Description text for the toast |
412
+ | `actionLabel?` | `string` | — | Action button label text |
413
+ | `onActionPress?` | `((helpers: { show: (options: string \| ToastShowOptions) => string; hide: (ids?: (string & {}) \| string[] \| "all") => void; }) => void)` | — | Callback function called when the action button is pressed Receives show and hide functions for programmatic toast control |
414
+ | `icon?` | `ForgeIcon` | — | Forge icon component to display in the toast. Rendered via `Toast.Icon` internally — inherits color-aware coloring automatically. |
415
+ | `onShow?` | `(() => void)` | — | Callback function called when the toast is shown |
416
+ | `onHide?` | `(() => void)` | — | Callback function called when the toast is hidden |
417
+ | `color?` | `'neutral' \| 'info' \| 'success' \| 'warning' \| 'danger' \| 'default' \| null` | `'neutral'` | Color of the toast |
418
+ | `placement?` | `'top-start' \| 'top' \| 'top-end' \| 'bottom-start' \| 'bottom' \| 'bottom-end'` | `'bottom'` | Placement of the toast |
419
+ | `isSwipeable?` | `boolean` | `true` | Whether the toast can be swiped to dismiss and dragged with rubber effect |
420
+ | `animation?` | `ToastRootAnimation` | — | Animation configuration for toast - `false` or `"disabled"`: Disable only root animations - `"disable-all"`: Disable all animations including children - `true` or `undefined`: Use default animations - `object`: Custom animation configuration |
421
+
422
+ ### toast.hide
423
+
424
+ | Call | Behavior |
425
+ | ---------------------- | -------------------------- |
426
+ | `toast.hide()` | Hides the front-most toast |
427
+ | `toast.hide(id)` | Hides one toast |
428
+ | `toast.hide([id, id])` | Hides several toasts |
429
+ | `toast.hide('all')` | Hides every toast |
430
+
431
+ ### toast.pauseAll / toast.resumeAll
432
+
433
+ Pause and resume every auto-dismiss timer; each resumes with only the time it had left. On web these are called for you (see Accessibility). On native they are no-ops unless you call them.
434
+
435
+ ## Anatomy
436
+
437
+ | `data-slot` | Element |
438
+ | ------------ | ------------ |
439
+ | `toast` | Root surface |
440
+ | `toast-icon` | Leading icon |
441
+
442
+ ## Accessibility
443
+
444
+ - The viewport is a `role="region"` landmark labelled by `announceLabel`, with `aria-live="polite"` on web so new toasts are announced.
445
+ - `color="danger"` upgrades the toast to `role="alert"` for assertive announcements.
446
+ - Timers pause automatically on web while the pointer is over a toast, while a toast holds focus, or while the tab is hidden (WCAG 2.2.1).
447
+ - Escape dismisses the front-most toast on web.
448
+ - On iOS the viewport is wrapped in `FullWindowOverlay` so toasts sit above native modals.
449
+
450
+ ## Constraints
451
+
452
+ - `ToastProvider` must be mounted once near the app root; `useToast()` throws without it.
453
+ - Toasts are imperative only. There is no declarative `open` prop and no trigger sub-component.
454
+ - `maxVisibleToasts` is set on the provider, not per toast. Beyond it, older toasts fade rather than unmount.
455
+ - Swipe-to-dismiss is native only and needs a `GestureHandlerRootView` above the provider.
456
+ - `duration: 0` dismisses immediately; `'persistent'`, negative, and non-finite values skip the timer.