@cdx-ui/components 0.1.7 → 0.2.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 (260) hide show
  1. package/coverage.svg +1 -1
  2. package/lib/commonjs/components/ColorArea/ColorAreaPaint.js +78 -0
  3. package/lib/commonjs/components/ColorArea/ColorAreaPaint.js.map +1 -0
  4. package/lib/commonjs/components/ColorArea/ColorAreaPaint.web.js +31 -0
  5. package/lib/commonjs/components/ColorArea/ColorAreaPaint.web.js.map +1 -0
  6. package/lib/commonjs/components/ColorArea/index.js +57 -0
  7. package/lib/commonjs/components/ColorArea/index.js.map +1 -0
  8. package/lib/commonjs/components/ColorArea/styles.js +12 -0
  9. package/lib/commonjs/components/ColorArea/styles.js.map +1 -0
  10. package/lib/commonjs/components/ColorField/index.js +138 -0
  11. package/lib/commonjs/components/ColorField/index.js.map +1 -0
  12. package/lib/commonjs/components/ColorField/styles.js +14 -0
  13. package/lib/commonjs/components/ColorField/styles.js.map +1 -0
  14. package/lib/commonjs/components/ColorPicker/index.js +88 -0
  15. package/lib/commonjs/components/ColorPicker/index.js.map +1 -0
  16. package/lib/commonjs/components/ColorPicker/styles.js +22 -0
  17. package/lib/commonjs/components/ColorPicker/styles.js.map +1 -0
  18. package/lib/commonjs/components/ColorSlider/ColorSliderRailPaint.js +68 -0
  19. package/lib/commonjs/components/ColorSlider/ColorSliderRailPaint.js.map +1 -0
  20. package/lib/commonjs/components/ColorSlider/ColorSliderRailPaint.web.js +41 -0
  21. package/lib/commonjs/components/ColorSlider/ColorSliderRailPaint.web.js.map +1 -0
  22. package/lib/commonjs/components/ColorSlider/index.js +123 -0
  23. package/lib/commonjs/components/ColorSlider/index.js.map +1 -0
  24. package/lib/commonjs/components/ColorSlider/styles.js +50 -0
  25. package/lib/commonjs/components/ColorSlider/styles.js.map +1 -0
  26. package/lib/commonjs/components/ColorSwatch/index.js +54 -0
  27. package/lib/commonjs/components/ColorSwatch/index.js.map +1 -0
  28. package/lib/commonjs/components/ColorSwatch/styles.js +25 -0
  29. package/lib/commonjs/components/ColorSwatch/styles.js.map +1 -0
  30. package/lib/commonjs/components/ColorSwatchPicker/index.js +110 -0
  31. package/lib/commonjs/components/ColorSwatchPicker/index.js.map +1 -0
  32. package/lib/commonjs/components/ColorSwatchPicker/styles.js +17 -0
  33. package/lib/commonjs/components/ColorSwatchPicker/styles.js.map +1 -0
  34. package/lib/commonjs/components/Heading/styles.js +3 -0
  35. package/lib/commonjs/components/Heading/styles.js.map +1 -1
  36. package/lib/commonjs/components/Icon/index.js +27 -3
  37. package/lib/commonjs/components/Icon/index.js.map +1 -1
  38. package/lib/commonjs/components/Icon/styles.js +19 -0
  39. package/lib/commonjs/components/Icon/styles.js.map +1 -0
  40. package/lib/commonjs/components/Text/index.js +13 -4
  41. package/lib/commonjs/components/Text/index.js.map +1 -1
  42. package/lib/commonjs/components/Text/styles.js +39 -3
  43. package/lib/commonjs/components/Text/styles.js.map +1 -1
  44. package/lib/commonjs/components/Toast/hooks.js +0 -1
  45. package/lib/commonjs/components/Toast/hooks.js.map +1 -1
  46. package/lib/commonjs/components/Toast/index.js +9 -6
  47. package/lib/commonjs/components/Toast/index.js.map +1 -1
  48. package/lib/commonjs/components/Toast/styles.js +36 -19
  49. package/lib/commonjs/components/Toast/styles.js.map +1 -1
  50. package/lib/commonjs/components/ToggleButton/index.js +5 -4
  51. package/lib/commonjs/components/ToggleButton/index.js.map +1 -1
  52. package/lib/commonjs/components/index.js +68 -0
  53. package/lib/commonjs/components/index.js.map +1 -1
  54. package/lib/commonjs/components/picker/surfaces.js +9 -2
  55. package/lib/commonjs/components/picker/surfaces.js.map +1 -1
  56. package/lib/commonjs/figma/Icon.figma.js +30 -3
  57. package/lib/commonjs/figma/Icon.figma.js.map +1 -1
  58. package/lib/commonjs/figma/Text.figma.js +15 -1
  59. package/lib/commonjs/figma/Text.figma.js.map +1 -1
  60. package/lib/commonjs/providers/toast/insets-container.js +15 -3
  61. package/lib/commonjs/providers/toast/insets-container.js.map +1 -1
  62. package/lib/commonjs/providers/toast/provider.js +1 -0
  63. package/lib/commonjs/providers/toast/provider.js.map +1 -1
  64. package/lib/commonjs/styles/constants.js +14 -1
  65. package/lib/commonjs/styles/constants.js.map +1 -1
  66. package/lib/module/components/ColorArea/ColorAreaPaint.js +74 -0
  67. package/lib/module/components/ColorArea/ColorAreaPaint.js.map +1 -0
  68. package/lib/module/components/ColorArea/ColorAreaPaint.web.js +27 -0
  69. package/lib/module/components/ColorArea/ColorAreaPaint.web.js.map +1 -0
  70. package/lib/module/components/ColorArea/index.js +53 -0
  71. package/lib/module/components/ColorArea/index.js.map +1 -0
  72. package/lib/module/components/ColorArea/styles.js +8 -0
  73. package/lib/module/components/ColorArea/styles.js.map +1 -0
  74. package/lib/module/components/ColorField/index.js +134 -0
  75. package/lib/module/components/ColorField/index.js.map +1 -0
  76. package/lib/module/components/ColorField/styles.js +10 -0
  77. package/lib/module/components/ColorField/styles.js.map +1 -0
  78. package/lib/module/components/ColorPicker/index.js +79 -0
  79. package/lib/module/components/ColorPicker/index.js.map +1 -0
  80. package/lib/module/components/ColorPicker/styles.js +18 -0
  81. package/lib/module/components/ColorPicker/styles.js.map +1 -0
  82. package/lib/module/components/ColorSlider/ColorSliderRailPaint.js +64 -0
  83. package/lib/module/components/ColorSlider/ColorSliderRailPaint.js.map +1 -0
  84. package/lib/module/components/ColorSlider/ColorSliderRailPaint.web.js +37 -0
  85. package/lib/module/components/ColorSlider/ColorSliderRailPaint.web.js.map +1 -0
  86. package/lib/module/components/ColorSlider/index.js +119 -0
  87. package/lib/module/components/ColorSlider/index.js.map +1 -0
  88. package/lib/module/components/ColorSlider/styles.js +46 -0
  89. package/lib/module/components/ColorSlider/styles.js.map +1 -0
  90. package/lib/module/components/ColorSwatch/index.js +50 -0
  91. package/lib/module/components/ColorSwatch/index.js.map +1 -0
  92. package/lib/module/components/ColorSwatch/styles.js +21 -0
  93. package/lib/module/components/ColorSwatch/styles.js.map +1 -0
  94. package/lib/module/components/ColorSwatchPicker/index.js +106 -0
  95. package/lib/module/components/ColorSwatchPicker/index.js.map +1 -0
  96. package/lib/module/components/ColorSwatchPicker/styles.js +13 -0
  97. package/lib/module/components/ColorSwatchPicker/styles.js.map +1 -0
  98. package/lib/module/components/Heading/styles.js +3 -0
  99. package/lib/module/components/Heading/styles.js.map +1 -1
  100. package/lib/module/components/Icon/index.js +27 -3
  101. package/lib/module/components/Icon/index.js.map +1 -1
  102. package/lib/module/components/Icon/styles.js +16 -0
  103. package/lib/module/components/Icon/styles.js.map +1 -0
  104. package/lib/module/components/Text/index.js +14 -5
  105. package/lib/module/components/Text/index.js.map +1 -1
  106. package/lib/module/components/Text/styles.js +38 -2
  107. package/lib/module/components/Text/styles.js.map +1 -1
  108. package/lib/module/components/Toast/hooks.js +0 -1
  109. package/lib/module/components/Toast/hooks.js.map +1 -1
  110. package/lib/module/components/Toast/index.js +10 -7
  111. package/lib/module/components/Toast/index.js.map +1 -1
  112. package/lib/module/components/Toast/styles.js +35 -19
  113. package/lib/module/components/Toast/styles.js.map +1 -1
  114. package/lib/module/components/ToggleButton/index.js +3 -3
  115. package/lib/module/components/ToggleButton/index.js.map +1 -1
  116. package/lib/module/components/index.js +6 -0
  117. package/lib/module/components/index.js.map +1 -1
  118. package/lib/module/components/picker/surfaces.js +10 -3
  119. package/lib/module/components/picker/surfaces.js.map +1 -1
  120. package/lib/module/figma/Icon.figma.js +30 -3
  121. package/lib/module/figma/Icon.figma.js.map +1 -1
  122. package/lib/module/figma/Text.figma.js +15 -1
  123. package/lib/module/figma/Text.figma.js.map +1 -1
  124. package/lib/module/providers/toast/insets-container.js +15 -4
  125. package/lib/module/providers/toast/insets-container.js.map +1 -1
  126. package/lib/module/providers/toast/provider.js +2 -1
  127. package/lib/module/providers/toast/provider.js.map +1 -1
  128. package/lib/module/styles/constants.js +13 -0
  129. package/lib/module/styles/constants.js.map +1 -1
  130. package/lib/typescript/components/Alert/index.d.ts +1 -1
  131. package/lib/typescript/components/Alert/index.d.ts.map +1 -1
  132. package/lib/typescript/components/Avatar/index.d.ts +1 -1
  133. package/lib/typescript/components/Avatar/index.d.ts.map +1 -1
  134. package/lib/typescript/components/Badge/styles.d.ts +3 -3
  135. package/lib/typescript/components/Breadcrumbs/styles.d.ts +1 -1
  136. package/lib/typescript/components/Button/index.d.ts +1 -1
  137. package/lib/typescript/components/Button/index.d.ts.map +1 -1
  138. package/lib/typescript/components/Button/styles.d.ts +4 -4
  139. package/lib/typescript/components/Checkbox/index.d.ts +1 -1
  140. package/lib/typescript/components/Checkbox/index.d.ts.map +1 -1
  141. package/lib/typescript/components/Chip/index.d.ts +1 -1
  142. package/lib/typescript/components/Chip/index.d.ts.map +1 -1
  143. package/lib/typescript/components/Chip/styles.d.ts +3 -3
  144. package/lib/typescript/components/ColorArea/ColorAreaPaint.d.ts +5 -0
  145. package/lib/typescript/components/ColorArea/ColorAreaPaint.d.ts.map +1 -0
  146. package/lib/typescript/components/ColorArea/ColorAreaPaint.web.d.ts +5 -0
  147. package/lib/typescript/components/ColorArea/ColorAreaPaint.web.d.ts.map +1 -0
  148. package/lib/typescript/components/ColorArea/index.d.ts +20 -0
  149. package/lib/typescript/components/ColorArea/index.d.ts.map +1 -0
  150. package/lib/typescript/components/ColorArea/styles.d.ts +4 -0
  151. package/lib/typescript/components/ColorArea/styles.d.ts.map +1 -0
  152. package/lib/typescript/components/ColorField/index.d.ts +41 -0
  153. package/lib/typescript/components/ColorField/index.d.ts.map +1 -0
  154. package/lib/typescript/components/ColorField/styles.d.ts +13 -0
  155. package/lib/typescript/components/ColorField/styles.d.ts.map +1 -0
  156. package/lib/typescript/components/ColorPicker/index.d.ts +28 -0
  157. package/lib/typescript/components/ColorPicker/index.d.ts.map +1 -0
  158. package/lib/typescript/components/ColorPicker/styles.d.ts +9 -0
  159. package/lib/typescript/components/ColorPicker/styles.d.ts.map +1 -0
  160. package/lib/typescript/components/ColorSlider/ColorSliderRailPaint.d.ts +5 -0
  161. package/lib/typescript/components/ColorSlider/ColorSliderRailPaint.d.ts.map +1 -0
  162. package/lib/typescript/components/ColorSlider/ColorSliderRailPaint.web.d.ts +5 -0
  163. package/lib/typescript/components/ColorSlider/ColorSliderRailPaint.web.d.ts.map +1 -0
  164. package/lib/typescript/components/ColorSlider/index.d.ts +33 -0
  165. package/lib/typescript/components/ColorSlider/index.d.ts.map +1 -0
  166. package/lib/typescript/components/ColorSlider/styles.d.ts +14 -0
  167. package/lib/typescript/components/ColorSlider/styles.d.ts.map +1 -0
  168. package/lib/typescript/components/ColorSwatch/index.d.ts +19 -0
  169. package/lib/typescript/components/ColorSwatch/index.d.ts.map +1 -0
  170. package/lib/typescript/components/ColorSwatch/styles.d.ts +7 -0
  171. package/lib/typescript/components/ColorSwatch/styles.d.ts.map +1 -0
  172. package/lib/typescript/components/ColorSwatchPicker/index.d.ts +37 -0
  173. package/lib/typescript/components/ColorSwatchPicker/index.d.ts.map +1 -0
  174. package/lib/typescript/components/ColorSwatchPicker/styles.d.ts +5 -0
  175. package/lib/typescript/components/ColorSwatchPicker/styles.d.ts.map +1 -0
  176. package/lib/typescript/components/Divider/index.d.ts +1 -1
  177. package/lib/typescript/components/Divider/index.d.ts.map +1 -1
  178. package/lib/typescript/components/Heading/styles.d.ts.map +1 -1
  179. package/lib/typescript/components/Icon/index.d.ts +14 -22
  180. package/lib/typescript/components/Icon/index.d.ts.map +1 -1
  181. package/lib/typescript/components/Icon/styles.d.ts +6 -0
  182. package/lib/typescript/components/Icon/styles.d.ts.map +1 -0
  183. package/lib/typescript/components/IconButton/styles.d.ts +2 -2
  184. package/lib/typescript/components/Input/index.d.ts +1 -1
  185. package/lib/typescript/components/Input/index.d.ts.map +1 -1
  186. package/lib/typescript/components/Link/index.d.ts +1 -1
  187. package/lib/typescript/components/Link/index.d.ts.map +1 -1
  188. package/lib/typescript/components/Menu/index.d.ts +2 -2
  189. package/lib/typescript/components/Menu/index.d.ts.map +1 -1
  190. package/lib/typescript/components/Select/index.d.ts +1 -1
  191. package/lib/typescript/components/Select/index.d.ts.map +1 -1
  192. package/lib/typescript/components/Slider/styles.d.ts +3 -3
  193. package/lib/typescript/components/Text/index.d.ts +40 -3
  194. package/lib/typescript/components/Text/index.d.ts.map +1 -1
  195. package/lib/typescript/components/Text/styles.d.ts +9 -0
  196. package/lib/typescript/components/Text/styles.d.ts.map +1 -1
  197. package/lib/typescript/components/Toast/hooks.d.ts +1 -1
  198. package/lib/typescript/components/Toast/hooks.d.ts.map +1 -1
  199. package/lib/typescript/components/Toast/index.d.ts.map +1 -1
  200. package/lib/typescript/components/Toast/styles.d.ts +4 -0
  201. package/lib/typescript/components/Toast/styles.d.ts.map +1 -1
  202. package/lib/typescript/components/Toast/types.d.ts +1 -1
  203. package/lib/typescript/components/Toast/types.d.ts.map +1 -1
  204. package/lib/typescript/components/ToggleButton/index.d.ts +5 -3
  205. package/lib/typescript/components/ToggleButton/index.d.ts.map +1 -1
  206. package/lib/typescript/components/index.d.ts +6 -0
  207. package/lib/typescript/components/index.d.ts.map +1 -1
  208. package/lib/typescript/components/picker/surfaces.d.ts +5 -1
  209. package/lib/typescript/components/picker/surfaces.d.ts.map +1 -1
  210. package/lib/typescript/figma/Icon.figma.d.ts.map +1 -1
  211. package/lib/typescript/figma/Text.figma.d.ts.map +1 -1
  212. package/lib/typescript/providers/toast/insets-container.d.ts +12 -0
  213. package/lib/typescript/providers/toast/insets-container.d.ts.map +1 -1
  214. package/lib/typescript/providers/toast/types.d.ts +5 -0
  215. package/lib/typescript/providers/toast/types.d.ts.map +1 -1
  216. package/lib/typescript/styles/constants.d.ts +10 -0
  217. package/lib/typescript/styles/constants.d.ts.map +1 -1
  218. package/package.json +5 -5
  219. package/src/components/Alert/index.tsx +1 -1
  220. package/src/components/Avatar/index.tsx +1 -1
  221. package/src/components/Button/index.tsx +1 -1
  222. package/src/components/Checkbox/index.tsx +1 -1
  223. package/src/components/Chip/index.tsx +1 -1
  224. package/src/components/ColorArea/ColorAreaPaint.tsx +51 -0
  225. package/src/components/ColorArea/ColorAreaPaint.web.tsx +31 -0
  226. package/src/components/ColorArea/index.tsx +71 -0
  227. package/src/components/ColorArea/styles.ts +18 -0
  228. package/src/components/ColorField/index.tsx +181 -0
  229. package/src/components/ColorField/styles.ts +20 -0
  230. package/src/components/ColorPicker/index.tsx +110 -0
  231. package/src/components/ColorPicker/styles.ts +33 -0
  232. package/src/components/ColorSlider/ColorSliderRailPaint.tsx +60 -0
  233. package/src/components/ColorSlider/ColorSliderRailPaint.web.tsx +33 -0
  234. package/src/components/ColorSlider/index.tsx +147 -0
  235. package/src/components/ColorSlider/styles.ts +72 -0
  236. package/src/components/ColorSwatch/index.tsx +56 -0
  237. package/src/components/ColorSwatch/styles.ts +24 -0
  238. package/src/components/ColorSwatchPicker/index.tsx +150 -0
  239. package/src/components/ColorSwatchPicker/styles.ts +32 -0
  240. package/src/components/Divider/index.tsx +1 -1
  241. package/src/components/Heading/styles.ts +3 -0
  242. package/src/components/Icon/index.tsx +46 -6
  243. package/src/components/Icon/styles.ts +15 -0
  244. package/src/components/Input/index.tsx +1 -1
  245. package/src/components/Link/index.tsx +1 -1
  246. package/src/components/Menu/index.tsx +2 -2
  247. package/src/components/Select/index.tsx +1 -1
  248. package/src/components/Text/index.tsx +32 -5
  249. package/src/components/Text/styles.ts +39 -1
  250. package/src/components/Toast/hooks.ts +0 -1
  251. package/src/components/Toast/index.tsx +14 -8
  252. package/src/components/Toast/styles.ts +47 -19
  253. package/src/components/Toast/types.ts +1 -1
  254. package/src/components/ToggleButton/index.tsx +9 -7
  255. package/src/components/index.ts +6 -0
  256. package/src/components/picker/surfaces.tsx +15 -2
  257. package/src/providers/toast/insets-container.tsx +23 -9
  258. package/src/providers/toast/provider.tsx +2 -2
  259. package/src/providers/toast/types.ts +5 -0
  260. package/src/styles/constants.ts +13 -0
@@ -1,16 +1,43 @@
1
1
  import { forwardRef, type ComponentPropsWithoutRef, type ComponentRef } from 'react';
2
2
  import { Text as RNText } from 'react-native';
3
+ import { useHasTextAncestor } from '@cdx-ui/primitives';
3
4
  import { cn } from '@cdx-ui/utils';
4
- import { textStyle, TextVariantProps } from './styles';
5
+ import { nestedTextStyle, textStyle, type TextVariantProps } from './styles';
5
6
 
6
- export type TextProps = TextVariantProps &
7
- ComponentPropsWithoutRef<typeof RNText> & { className?: string };
7
+ export type TextColor = NonNullable<TextVariantProps['color']>;
8
+ export type TextSize = NonNullable<TextVariantProps['size']>;
9
+ export type TextWeight = NonNullable<TextVariantProps['weight']>;
10
+
11
+ export type TextProps = Omit<TextVariantProps, 'color' | 'size' | 'weight'> &
12
+ ComponentPropsWithoutRef<typeof RNText> & {
13
+ /**
14
+ * Semantic content color, mapped to the matching `text-content-*` token.
15
+ * A `Text` nested inside another text element inherits its parent's color when omitted.
16
+ * @default 'primary'
17
+ */
18
+ color?: TextColor;
19
+ /**
20
+ * Body typography style. A nested `Text` inherits its parent's size when omitted, and
21
+ * setting it keeps the parent's font family and weight.
22
+ * @default 'md'
23
+ */
24
+ size?: TextSize;
25
+ /**
26
+ * Font weight. A nested `Text` inherits its parent's weight when omitted.
27
+ * @default 'normal'
28
+ */
29
+ weight?: TextWeight;
30
+ className?: string;
31
+ };
8
32
 
9
33
  export const Text = forwardRef<ComponentRef<typeof RNText>, TextProps>(function Text(
10
- { className, size = 'md', ...props },
34
+ { className, color, size, weight, italic, ...props },
11
35
  ref,
12
36
  ) {
13
- return <RNText className={cn(textStyle({ size }), className)} {...props} ref={ref} />;
37
+ const variants = { color, size, weight, italic };
38
+ const classes = useHasTextAncestor() ? nestedTextStyle(variants) : textStyle(variants);
39
+
40
+ return <RNText className={cn(classes, className)} {...props} ref={ref} />;
14
41
  });
15
42
 
16
43
  Text.displayName = 'Text';
@@ -1,9 +1,20 @@
1
1
  import { Platform } from 'react-native';
2
2
  import { cva, type VariantProps } from '@cdx-ui/utils';
3
+ import { CONTENT_COLOR } from '../../styles/constants';
4
+
5
+ const TEXT_WEIGHT = {
6
+ normal: 'font-normal',
7
+ medium: 'font-medium',
8
+ semibold: 'font-semibold',
9
+ bold: 'font-bold',
10
+ } as const;
11
+
12
+ const TEXT_ITALIC = {
13
+ true: 'italic',
14
+ } as const;
3
15
 
4
16
  export const textStyle = cva(
5
17
  [
6
- 'text-content-primary',
7
18
  Platform.select({
8
19
  web: 'font-body my-0 bg-transparent no-underline',
9
20
  default: '',
@@ -11,6 +22,7 @@ export const textStyle = cva(
11
22
  ],
12
23
  {
13
24
  variants: {
25
+ color: CONTENT_COLOR,
14
26
  size: {
15
27
  xl: 'body-xl',
16
28
  lg: 'body-lg',
@@ -18,8 +30,34 @@ export const textStyle = cva(
18
30
  sm: 'body-sm',
19
31
  xs: 'body-xs',
20
32
  },
33
+ weight: TEXT_WEIGHT,
34
+ italic: TEXT_ITALIC,
35
+ },
36
+ defaultVariants: {
37
+ color: 'primary',
38
+ size: 'md',
39
+ weight: 'normal',
21
40
  },
22
41
  },
23
42
  );
24
43
 
25
44
  export type TextVariantProps = VariantProps<typeof textStyle>;
45
+
46
+ // A `Text` inside another text element emits only the props it is given, with no
47
+ // base classes or defaults, so everything it omits inherits from the parent. Its
48
+ // sizes use the `-size` companions of the body styles, which leave the font
49
+ // family and weight to inherit too.
50
+ export const nestedTextStyle = cva([], {
51
+ variants: {
52
+ color: CONTENT_COLOR,
53
+ size: {
54
+ xl: 'body-xl-size',
55
+ lg: 'body-lg-size',
56
+ md: 'body-md-size',
57
+ sm: 'body-sm-size',
58
+ xs: 'body-xs-size',
59
+ } satisfies Record<NonNullable<TextVariantProps['size']>, string>,
60
+ weight: TEXT_WEIGHT,
61
+ italic: TEXT_ITALIC,
62
+ },
63
+ });
@@ -12,7 +12,6 @@ export function useButtonColor({
12
12
  color: ButtonProps['color'];
13
13
  toastColor: ToastColorInternal;
14
14
  }) {
15
- // TODO: Add toastActionVariants to styles.ts to restore color-aware action styling
16
15
  return useMemo(() => {
17
16
  if (color) return color;
18
17
 
@@ -35,6 +35,10 @@ import {
35
35
  toastLabelVariants,
36
36
  toastDescriptionVariants,
37
37
  toastIconVariants,
38
+ toastActionRootVariants,
39
+ toastActionLabelVariants,
40
+ toastCloseRootVariants,
41
+ toastCloseIconVariants,
38
42
  toastStyleSheet,
39
43
  toastTextVariants,
40
44
  toastWrapperVariants,
@@ -415,10 +419,8 @@ const ToastAction = forwardRef<View, ToastActionProps>((props, ref) => {
415
419
  const { children, variant, color, size = 'small', className, ...restProps } = props;
416
420
 
417
421
  const { color: toastColor } = useToastStyleContext();
418
-
419
- // TODO: Add toastActionVariants to styles.ts to restore color-aware action styling
420
-
421
422
  const buttonColor = useButtonColor({ color, toastColor });
423
+ const usesNeutralStandIn = toastColor === 'neutral' && !color;
422
424
 
423
425
  return (
424
426
  <Button
@@ -426,10 +428,12 @@ const ToastAction = forwardRef<View, ToastActionProps>((props, ref) => {
426
428
  variant={variant ?? 'outline'}
427
429
  color={buttonColor}
428
430
  size={size}
429
- className={className}
431
+ className={cn(usesNeutralStandIn ? toastActionRootVariants() : undefined, className)}
430
432
  {...restProps}
431
433
  >
432
- <Button.Label>{children}</Button.Label>
434
+ <Button.Label className={usesNeutralStandIn ? toastActionLabelVariants() : undefined}>
435
+ {children}
436
+ </Button.Label>
433
437
  </Button>
434
438
  );
435
439
  });
@@ -437,8 +441,9 @@ const ToastAction = forwardRef<View, ToastActionProps>((props, ref) => {
437
441
  // --------------------------------------------------
438
442
 
439
443
  const ToastClose = forwardRef<View, ToastCloseProps>((props, ref) => {
440
- const { children, size = 'small', className, onPress, ...restProps } = props;
441
- const { hide, id } = useToastStyleContext();
444
+ const { children, size = 'small', className, onPress, iconClassName, ...restProps } = props;
445
+ const { hide, id, color: toastColor } = useToastStyleContext();
446
+ const usesNeutralStandIn = toastColor === 'neutral';
442
447
 
443
448
  /**
444
449
  * Handle close button press
@@ -460,7 +465,8 @@ const ToastClose = forwardRef<View, ToastCloseProps>((props, ref) => {
460
465
  variant="ghost"
461
466
  size={size}
462
467
  aria-label="Close"
463
- className={className}
468
+ className={cn(usesNeutralStandIn ? toastCloseRootVariants() : undefined, className)}
469
+ iconClassName={cn(usesNeutralStandIn ? toastCloseIconVariants() : undefined, iconClassName)}
464
470
  onPress={handlePress}
465
471
  as={CloseIcon}
466
472
  {...restProps}
@@ -1,6 +1,15 @@
1
- import { StyleSheet } from 'react-native';
1
+ import { Platform, StyleSheet } from 'react-native';
2
2
  import { cva, type VariantProps } from '@cdx-ui/utils';
3
3
 
4
+ const NEUTRAL_ON_STRONG_INTERACTION = Platform.select({
5
+ default: 'data-[active=true]:bg-surface-neutral-strong',
6
+ web: [
7
+ 'data-[hover=true]:bg-surface-neutral-strong-hover',
8
+ 'data-[active=true]:data-[hover=true]:bg-surface-neutral-strong',
9
+ 'web:data-[focus-visible=true]:ring-offset-surface-neutral-strong-active',
10
+ ].join(' '),
11
+ });
12
+
4
13
  /**
5
14
  * Toast root styles
6
15
  *
@@ -40,17 +49,18 @@ export const toastRootVariants = cva(
40
49
  // shadow and clips the child's transform mid-transition, producing a
41
50
  // visual "cut off" during enter/exit. Consumers that need clipping for
42
51
  // custom child content (e.g. a background image) can add it themselves.
43
- 'flex-row items-center gap-3 rounded-[var(--border-radius-default)] min-h-12 px-4 py-2 shadow-lg bg-surface-primary border border-stroke-secondary',
52
+ 'flex-row items-center gap-3 rounded-[var(--border-radius-default)] min-h-12 px-4 py-2 shadow-lg border border-transparent',
44
53
  'native:overflow-hidden',
45
54
  ],
46
55
  {
47
56
  variants: {
48
57
  color: {
49
- neutral: '',
50
- info: '',
51
- success: '',
52
- warning: '',
53
- danger: '',
58
+ // color.component.toast.neutral.surface
59
+ neutral: 'bg-surface-neutral-strong-active',
60
+ info: 'bg-surface-info-subtle',
61
+ success: 'bg-surface-success-subtle',
62
+ warning: 'bg-surface-warning-subtle',
63
+ danger: 'bg-surface-danger-subtle',
54
64
  },
55
65
  },
56
66
  defaultVariants: {
@@ -146,11 +156,12 @@ export const toastTextVariants = cva(['flex-1 flex-col min-w-0']);
146
156
  export const toastLabelVariants = cva(['text-base font-medium'], {
147
157
  variants: {
148
158
  color: {
149
- neutral: 'text-content-primary',
150
- info: 'text-content-info',
151
- success: 'text-content-success',
152
- warning: 'text-content-warning',
153
- danger: 'text-content-danger',
159
+ // color.component.toast.neutral.content
160
+ neutral: 'text-content-neutral-on-strong',
161
+ info: 'text-content-info-on-subtle',
162
+ success: 'text-content-success-on-subtle',
163
+ warning: 'text-content-warning-on-subtle',
164
+ danger: 'text-content-danger-on-subtle',
154
165
  },
155
166
  },
156
167
  defaultVariants: {
@@ -158,14 +169,15 @@ export const toastLabelVariants = cva(['text-base font-medium'], {
158
169
  },
159
170
  });
160
171
 
161
- export const toastDescriptionVariants = cva(['text-sm text-content-primary'], {
172
+ export const toastDescriptionVariants = cva(['text-sm'], {
162
173
  variants: {
163
174
  color: {
164
- neutral: 'text-content-primary',
165
- info: 'text-content-info',
166
- success: 'text-content-success',
167
- warning: 'text-content-warning',
168
- danger: 'text-content-danger',
175
+ // color.component.toast.neutral.content
176
+ neutral: 'text-content-neutral-on-strong',
177
+ info: 'text-content-info-on-subtle',
178
+ success: 'text-content-success-on-subtle',
179
+ warning: 'text-content-warning-on-subtle',
180
+ danger: 'text-content-danger-on-subtle',
169
181
  },
170
182
  },
171
183
  defaultVariants: {
@@ -176,7 +188,8 @@ export const toastDescriptionVariants = cva(['text-sm text-content-primary'], {
176
188
  export const toastIconVariants = cva(['size-5'], {
177
189
  variants: {
178
190
  color: {
179
- neutral: 'text-content-primary',
191
+ // color.component.toast.neutral.content
192
+ neutral: 'text-content-neutral-on-strong',
180
193
  info: 'text-content-info',
181
194
  success: 'text-content-success',
182
195
  warning: 'text-content-warning',
@@ -188,6 +201,21 @@ export const toastIconVariants = cva(['size-5'], {
188
201
  },
189
202
  });
190
203
 
204
+ export const toastActionRootVariants = cva([
205
+ 'border-content-neutral-on-strong', // color.component.toast.neutral.action
206
+ NEUTRAL_ON_STRONG_INTERACTION,
207
+ ]);
208
+
209
+ export const toastActionLabelVariants = cva([
210
+ 'text-content-neutral-on-strong', // color.component.toast.neutral.action
211
+ ]);
212
+
213
+ export const toastCloseRootVariants = cva([NEUTRAL_ON_STRONG_INTERACTION]);
214
+
215
+ export const toastCloseIconVariants = cva([
216
+ 'text-content-neutral-on-strong', // color.component.toast.neutral.content
217
+ ]);
218
+
191
219
  export const toastStyleSheet = StyleSheet.create({
192
220
  root: {
193
221
  borderCurve: 'continuous',
@@ -228,7 +228,7 @@ export interface ToastDescriptionProps {
228
228
  /**
229
229
  * Props for the Toast.Icon component
230
230
  */
231
- export interface ToastIconProps extends Omit<IconProps, 'children' | 'as'> {
231
+ export interface ToastIconProps extends Omit<IconProps, 'children' | 'as' | 'color'> {
232
232
  asChild?: boolean;
233
233
  /**
234
234
  * Forge icon component to render. Required unless `asChild` is set.
@@ -157,7 +157,7 @@ ToggleButtonLabel.displayName = 'ToggleButton.Label';
157
157
  // STYLED ICON COMPONENT
158
158
  // =============================================================================
159
159
 
160
- export interface ToggleButtonIconProps extends Omit<IconProps, 'children' | 'as'> {
160
+ export interface ToggleButtonIconProps extends Omit<IconProps, 'children' | 'as' | 'color'> {
161
161
  /** Render a custom element instead of the default icon. */
162
162
  asChild?: boolean;
163
163
  /** Forge icon component to render. */
@@ -333,14 +333,16 @@ const ToggleButtonGroup = forwardRef<View, ToggleButtonGroupProps>(
333
333
  },
334
334
  );
335
335
 
336
- ToggleButtonGroup.displayName = 'ToggleButtonGroup';
336
+ ToggleButtonGroup.displayName = 'ToggleButton.Group';
337
337
 
338
- export const ToggleButton = Object.assign(ToggleButtonRoot, {
339
- Label: ToggleButtonLabel,
340
- Icon: ToggleButtonIcon,
341
- }) as typeof ToggleButtonRoot & {
338
+ type ToggleButtonCompoundComponent = typeof ToggleButtonRoot & {
342
339
  Label: typeof ToggleButtonLabel;
343
340
  Icon: typeof ToggleButtonIcon;
341
+ Group: typeof ToggleButtonGroup;
344
342
  };
345
343
 
346
- export { ToggleButtonGroup };
344
+ export const ToggleButton = Object.assign(ToggleButtonRoot, {
345
+ Label: ToggleButtonLabel,
346
+ Icon: ToggleButtonIcon,
347
+ Group: ToggleButtonGroup,
348
+ }) as ToggleButtonCompoundComponent;
@@ -10,6 +10,12 @@ export * from './Card';
10
10
  export * from './Carousel';
11
11
  export * from './Checkbox';
12
12
  export * from './Chip';
13
+ export * from './ColorArea';
14
+ export * from './ColorField';
15
+ export * from './ColorPicker';
16
+ export * from './ColorSlider';
17
+ export { ColorSwatch, type ColorSwatchProps, type ColorSwatchVariantProps } from './ColorSwatch';
18
+ export * from './ColorSwatchPicker';
13
19
  export * from './CurrencyInput';
14
20
  export * from './DateField';
15
21
  export * from './Calendar';
@@ -2,10 +2,12 @@ import { useCallback, useEffect, useRef, useState, type ReactNode, type RefObjec
2
2
  import { ScrollView, View } from 'react-native';
3
3
  import { FadeIn, FadeOut } from 'react-native-reanimated';
4
4
  import {
5
+ dataAttributes,
5
6
  OverlayContainer,
6
7
  useAnchoredOverlay,
7
8
  useDismissOverlay,
8
9
  useEscapeKey,
10
+ type OverlayWidthPolicy,
9
11
  } from '@cdx-ui/primitives';
10
12
  import { cn, mergeRefs } from '@cdx-ui/utils';
11
13
  import { Dialog } from '../Dialog';
@@ -107,6 +109,9 @@ interface PickerPopoverSurfaceProps {
107
109
  triggerRef?: RefObject<View | null>;
108
110
  children: ReactNode;
109
111
  className?: string;
112
+ contentClassName?: string;
113
+ dataSlot?: string;
114
+ width?: OverlayWidthPolicy;
110
115
  }
111
116
 
112
117
  export function PickerPopoverSurface({
@@ -117,6 +122,9 @@ export function PickerPopoverSurface({
117
122
  triggerRef,
118
123
  children,
119
124
  className,
125
+ contentClassName,
126
+ dataSlot,
127
+ width = 'anchor',
120
128
  }: PickerPopoverSurfaceProps) {
121
129
  const contentRef = useRef<View>(null);
122
130
  const [dismissEnabled, setDismissEnabled] = useState(false);
@@ -144,7 +152,7 @@ export function PickerPopoverSurface({
144
152
  placement: 'bottom-start',
145
153
  offset: 4,
146
154
  collisionBehavior: 'flip-shift',
147
- width: 'anchor',
155
+ width,
148
156
  });
149
157
 
150
158
  const excludeRefs = triggerRef ? [anchorRef, triggerRef] : [anchorRef];
@@ -168,8 +176,13 @@ export function PickerPopoverSurface({
168
176
  className={cn(pickerPopoverContentVariants(), className)}
169
177
  style={style}
170
178
  accessibilityViewIsModal
179
+ {...dataAttributes({ slot: dataSlot })}
171
180
  >
172
- <ScrollView scrollEventThrottle={16} showsVerticalScrollIndicator={false}>
181
+ <ScrollView
182
+ contentContainerClassName={contentClassName}
183
+ scrollEventThrottle={16}
184
+ showsVerticalScrollIndicator={false}
185
+ >
173
186
  {children}
174
187
  </ScrollView>
175
188
  </View>
@@ -1,12 +1,21 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import { useCallback, useContext, useEffect, useMemo, useRef } from 'react';
3
- import { Platform, View } from 'react-native';
3
+ import { Platform, StyleSheet, View } from 'react-native';
4
4
  import { SafeAreaInsetsContext, type EdgeInsets } from 'react-native-safe-area-context';
5
5
  import { FullWindowOverlay, NOTIFICATION_OVERLAY_Z_INDEX } from '@cdx-ui/primitives';
6
6
  import type { ToastInsets } from './types';
7
7
 
8
8
  const ZERO_INSETS: EdgeInsets = { top: 0, bottom: 0, left: 0, right: 0 };
9
9
 
10
+ /**
11
+ * The viewport spans the whole window, so every full-size layer in it must let
12
+ * pointer events through to the page. React Native Web only expands `box-none`
13
+ * for `StyleSheet.create` styles, not inline style objects.
14
+ */
15
+ export const passThroughStyles = StyleSheet.create({
16
+ boxNone: { pointerEvents: 'box-none' },
17
+ });
18
+
10
19
  interface InsetsContainerProps {
11
20
  /**
12
21
  * When true, uses a regular View instead of FullWindowOverlay on iOS.
@@ -41,6 +50,8 @@ interface InsetsContainerProps {
41
50
  * Custom wrapper function to wrap the toast content
42
51
  * Receives children and should return a component that wraps them
43
52
  * The wrapper should apply flex: 1 (via className or style) to ensure proper layout
53
+ * and `pointerEvents: 'box-none'` (from a `StyleSheet.create` style) so it does not block
54
+ * interaction with the page behind
44
55
  * Can be any component wrapper - KeyboardAvoidingView, View, or any custom component
45
56
  */
46
57
  contentWrapper?: (children: ReactNode) => React.ReactElement;
@@ -199,20 +210,23 @@ export function InsetsContainer({
199
210
  const content = (
200
211
  <View
201
212
  ref={containerRef}
202
- className="absolute web:fixed inset-0 pointer-events-box-none"
213
+ className="absolute web:fixed inset-0"
203
214
  role="region"
204
215
  aria-label={announceLabel}
205
216
  {...(Platform.OS === 'web' && {
206
217
  'aria-live': 'polite',
207
218
  'aria-atomic': false,
208
219
  })}
209
- style={{
210
- ...(Platform.OS === 'web' ? { zIndex: NOTIFICATION_OVERLAY_Z_INDEX } : {}),
211
- paddingTop: finalInsets.top,
212
- paddingBottom: finalInsets.bottom,
213
- paddingLeft: finalInsets.left,
214
- paddingRight: finalInsets.right,
215
- }}
220
+ style={[
221
+ passThroughStyles.boxNone,
222
+ {
223
+ ...(Platform.OS === 'web' ? { zIndex: NOTIFICATION_OVERLAY_Z_INDEX } : {}),
224
+ paddingTop: finalInsets.top,
225
+ paddingBottom: finalInsets.bottom,
226
+ paddingLeft: finalInsets.left,
227
+ paddingRight: finalInsets.right,
228
+ },
229
+ ]}
216
230
  >
217
231
  {contentWrapper ? contentWrapper(children) : children}
218
232
  </View>
@@ -12,7 +12,7 @@ import { useSharedValue } from 'react-native-reanimated';
12
12
  import { createPortalFn, useOverlayStackRegistration } from '@cdx-ui/primitives';
13
13
  import { DefaultToast } from '../../components/Toast';
14
14
  import type { ToastPlacement } from '../../components/Toast/types';
15
- import { InsetsContainer } from './insets-container';
15
+ import { InsetsContainer, passThroughStyles } from './insets-container';
16
16
  import { ToastLifecycleContext, type ToastLifecycleContextValue } from './lifecycle.context';
17
17
  import { toastReducer } from './reducer';
18
18
  import { ToastConfigContext } from './toast-config.context';
@@ -628,7 +628,7 @@ export function ToastProvider({
628
628
  resumeAll={resumeAll}
629
629
  hide={hide}
630
630
  >
631
- <View className="flex-1">
631
+ <View className="flex-1" style={passThroughStyles.boxNone}>
632
632
  {toasts.map((toastItem) => {
633
633
  const placement = toastItem.placement;
634
634
  const index = placementIndexes[placement];
@@ -79,16 +79,21 @@ export interface ToastProviderProps {
79
79
  * Custom wrapper function to wrap the toast content
80
80
  * Receives children and should return a component that wraps them
81
81
  * The wrapper should apply flex: 1 (via className or style) to ensure proper layout
82
+ * and `pointerEvents: 'box-none'` so it does not block interaction with the page behind.
83
+ * On web, `box-none` only takes effect from a `StyleSheet.create` style, not an inline object.
82
84
  * Can be any component wrapper - KeyboardAvoidingView, View, or any custom component
83
85
  *
84
86
  * @example
85
87
  * ```tsx
88
+ * const styles = StyleSheet.create({ passThrough: { pointerEvents: 'box-none' } });
89
+ *
86
90
  * <ToastProvider
87
91
  * contentWrapper={(children) => (
88
92
  * <KeyboardAvoidingView
89
93
  * behavior="padding"
90
94
  * keyboardVerticalOffset={24}
91
95
  * className="flex-1"
96
+ * style={styles.passThrough}
92
97
  * >
93
98
  * {children}
94
99
  * </KeyboardAvoidingView>
@@ -9,6 +9,19 @@ export const DISABLED_OPACITY = 'data-[disabled=true]:opacity-50';
9
9
  export const DISABLED_CURSOR =
10
10
  'data-[disabled=true]:cursor-not-allowed data-[disabled=true]:pointer-events-none';
11
11
 
12
+ // ─── Content color ───────────────────────────────────────
13
+ // The `color` variant shared by `Text` and `Icon`.
14
+ export const CONTENT_COLOR = {
15
+ primary: 'text-content-primary',
16
+ secondary: 'text-content-secondary',
17
+ tertiary: 'text-content-tertiary',
18
+ action: 'text-content-action',
19
+ danger: 'text-content-danger',
20
+ warning: 'text-content-warning',
21
+ success: 'text-content-success',
22
+ info: 'text-content-info',
23
+ } as const;
24
+
12
25
  // Web-only iOS Safari focus-zoom guard. Figma Viewport=Narrow (<600px) uses body/lg
13
26
  // (16px / 24px); Viewport=Wide (≥600px) keeps the size variant's original px size.
14
27
  export const WEB_NARROW_FIELD_TEXT = 'web:max-[600px]:text-base web:max-[600px]:leading-normal';