@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
@@ -0,0 +1,31 @@
1
+ import { View, type ViewStyle } from 'react-native';
2
+ import { useColorAreaContext } from '@cdx-ui/primitives';
3
+ import { colorAreaPaintVariants } from './styles';
4
+
5
+ export function ColorAreaPaint() {
6
+ const { value, isRTL } = useColorAreaContext();
7
+ const hue = value
8
+ .withChannel('hsb', 'saturation', 100)
9
+ .withChannel('hsb', 'brightness', 100)
10
+ .toString('hex');
11
+ const direction = isRTL ? 'to left' : 'to right';
12
+ const paintStyle = {
13
+ backgroundImage: [
14
+ 'linear-gradient(to bottom, transparent, #000000)',
15
+ `linear-gradient(${direction}, #FFFFFF, ${hue})`,
16
+ ].join(', '),
17
+ pointerEvents: 'none',
18
+ } as unknown as ViewStyle;
19
+
20
+ return (
21
+ <View
22
+ className={colorAreaPaintVariants()}
23
+ style={paintStyle}
24
+ accessible={false}
25
+ accessibilityElementsHidden
26
+ importantForAccessibility="no-hide-descendants"
27
+ />
28
+ );
29
+ }
30
+
31
+ ColorAreaPaint.displayName = 'ColorAreaPaint';
@@ -0,0 +1,71 @@
1
+ import { forwardRef, type ReactNode } from 'react';
2
+ import { View } from 'react-native';
3
+ import {
4
+ ColorAreaRoot as ColorAreaRootPrimitive,
5
+ ColorAreaThumb as ColorAreaThumbPrimitive,
6
+ dataAttributes,
7
+ mergeDataAttributes,
8
+ useColorAreaContext,
9
+ type IColorAreaProps,
10
+ type IColorAreaThumbProps,
11
+ } from '@cdx-ui/primitives';
12
+ import { cn } from '@cdx-ui/utils';
13
+ import { ColorAreaPaint } from './ColorAreaPaint';
14
+ import { colorAreaThumbVariants, colorAreaVariants } from './styles';
15
+
16
+ export interface ColorAreaProps extends IColorAreaProps {
17
+ readonly asChild?: boolean;
18
+ readonly className?: string;
19
+ readonly children?: ReactNode;
20
+ }
21
+
22
+ const ColorAreaRoot = forwardRef<View, ColorAreaProps>(
23
+ ({ asChild, className, style, children, ...props }, ref) => (
24
+ <ColorAreaRootPrimitive
25
+ ref={ref}
26
+ asChild={asChild}
27
+ className={cn(colorAreaVariants(), className)}
28
+ style={style}
29
+ {...props}
30
+ {...mergeDataAttributes(props, dataAttributes({ slot: 'color-area' }))}
31
+ >
32
+ <ColorAreaPaint />
33
+ {children}
34
+ </ColorAreaRootPrimitive>
35
+ ),
36
+ );
37
+
38
+ ColorAreaRoot.displayName = 'ColorArea';
39
+
40
+ export interface ColorAreaThumbProps extends IColorAreaThumbProps {
41
+ readonly className?: string;
42
+ readonly children?: ReactNode;
43
+ }
44
+
45
+ const ColorAreaThumb = forwardRef<View, ColorAreaThumbProps>(
46
+ ({ className, style, children, ...props }, ref) => {
47
+ const { value } = useColorAreaContext();
48
+
49
+ return (
50
+ <ColorAreaThumbPrimitive
51
+ ref={ref}
52
+ className={cn(colorAreaThumbVariants(), className)}
53
+ style={[{ backgroundColor: value.toString('hex') }, style]}
54
+ {...props}
55
+ {...mergeDataAttributes(props, dataAttributes({ slot: 'color-area-thumb' }))}
56
+ >
57
+ {children}
58
+ </ColorAreaThumbPrimitive>
59
+ );
60
+ },
61
+ );
62
+
63
+ ColorAreaThumb.displayName = 'ColorArea.Thumb';
64
+
65
+ type ColorAreaCompoundComponent = typeof ColorAreaRoot & {
66
+ Thumb: typeof ColorAreaThumb;
67
+ };
68
+
69
+ export const ColorArea = Object.assign(ColorAreaRoot, {
70
+ Thumb: ColorAreaThumb,
71
+ }) as ColorAreaCompoundComponent;
@@ -0,0 +1,18 @@
1
+ import { cva } from '@cdx-ui/utils';
2
+ import { DISABLED_CURSOR } from '../../styles/constants';
3
+
4
+ export const colorAreaVariants = cva([
5
+ 'relative aspect-square w-full touch-none select-none',
6
+ 'data-[disabled=true]:opacity-[var(--opacity-disabled)]',
7
+ DISABLED_CURSOR,
8
+ ]);
9
+
10
+ export const colorAreaPaintVariants = cva([
11
+ 'absolute inset-0 overflow-hidden rounded-[var(--border-radius-default)]',
12
+ ]);
13
+
14
+ export const colorAreaThumbVariants = cva([
15
+ 'z-2 size-5 rounded-[var(--border-radius-round)]',
16
+ 'border-2 border-surface-primary shadow-md',
17
+ 'transition-none',
18
+ ]);
@@ -0,0 +1,181 @@
1
+ import { forwardRef, useMemo, type ReactNode } from 'react';
2
+ import { TextInput, View, type ViewProps } from 'react-native';
3
+ import {
4
+ ColorFieldInput as ColorFieldInputPrimitive,
5
+ ColorFieldRoot as ColorFieldRootPrimitive,
6
+ InputRoot as InputRootPrimitive,
7
+ Slot,
8
+ dataAttributes,
9
+ mergeDataAttributes,
10
+ useColorFieldContext,
11
+ type ColorFieldInputProps as ColorFieldInputPrimitiveProps,
12
+ type ColorFieldRootProps as ColorFieldRootPrimitiveProps,
13
+ } from '@cdx-ui/primitives';
14
+ import { cn, ParentContext, useParentContext } from '@cdx-ui/utils';
15
+ import { positionToDataIcon, type IconSlotPosition } from '../../utils/positionToDataIcon';
16
+ import {
17
+ colorFieldGroupVariants,
18
+ colorFieldInputPlaceholderVariants,
19
+ colorFieldInputVariants,
20
+ colorFieldSlotVariants,
21
+ colorFieldVariants,
22
+ type ColorFieldGroupVariantProps,
23
+ } from './styles';
24
+
25
+ const SCOPE = 'COLOR_FIELD';
26
+
27
+ type ColorFieldStyleContext = ColorFieldGroupVariantProps & {
28
+ readonly fullWidth?: boolean;
29
+ };
30
+
31
+ const useColorFieldStyleContext = (): ColorFieldStyleContext =>
32
+ (useParentContext()[SCOPE] as ColorFieldStyleContext | undefined) ?? {};
33
+
34
+ export type ColorFieldProps = ColorFieldRootPrimitiveProps &
35
+ ColorFieldGroupVariantProps & {
36
+ readonly className?: string;
37
+ /** When true (the default), the group stretches to fill its container. */
38
+ readonly fullWidth?: boolean;
39
+ };
40
+
41
+ const ColorFieldRoot = forwardRef<View, ColorFieldProps>(
42
+ (
43
+ { variant = 'outline', size = 'default', fullWidth, className, children, style, ...props },
44
+ ref,
45
+ ) => {
46
+ const parent = useParentContext();
47
+ const context = useMemo(
48
+ () => ({ ...parent, [SCOPE]: { variant, size, fullWidth } }),
49
+ [fullWidth, parent, size, variant],
50
+ );
51
+
52
+ return (
53
+ <ParentContext.Provider value={context}>
54
+ <ColorFieldRootPrimitive
55
+ ref={ref}
56
+ className={cn(colorFieldVariants(), className)}
57
+ style={style}
58
+ {...props}
59
+ {...mergeDataAttributes(props, dataAttributes({ slot: 'color-field' }))}
60
+ >
61
+ {children}
62
+ </ColorFieldRootPrimitive>
63
+ </ParentContext.Provider>
64
+ );
65
+ },
66
+ );
67
+
68
+ ColorFieldRoot.displayName = 'ColorField';
69
+
70
+ export interface ColorFieldGroupProps extends ViewProps, ColorFieldGroupVariantProps {
71
+ readonly asChild?: boolean;
72
+ readonly className?: string;
73
+ readonly children?: ReactNode;
74
+ readonly fullWidth?: boolean;
75
+ }
76
+
77
+ const ColorFieldGroup = forwardRef<View, ColorFieldGroupProps>(
78
+ ({ asChild, variant, size, fullWidth, className, children, style, ...props }, ref) => {
79
+ const inherited = useColorFieldStyleContext();
80
+ const { disabled, invalid, readOnly, required } = useColorFieldContext();
81
+ const resolvedVariant = variant ?? inherited.variant ?? 'outline';
82
+ const resolvedSize = size ?? inherited.size ?? 'default';
83
+ const resolvedFullWidth = fullWidth ?? inherited.fullWidth ?? true;
84
+
85
+ return (
86
+ <InputRootPrimitive
87
+ ref={ref}
88
+ asChild={asChild}
89
+ isDisabled={disabled}
90
+ isInvalid={invalid}
91
+ isReadOnly={readOnly}
92
+ isRequired={required}
93
+ className={cn(
94
+ colorFieldGroupVariants({
95
+ variant: resolvedVariant,
96
+ size: resolvedSize,
97
+ }),
98
+ !resolvedFullWidth && 'w-auto self-start',
99
+ className,
100
+ )}
101
+ style={style}
102
+ {...props}
103
+ {...mergeDataAttributes(props, dataAttributes({ slot: 'color-field-group' }))}
104
+ >
105
+ {children}
106
+ </InputRootPrimitive>
107
+ );
108
+ },
109
+ );
110
+
111
+ ColorFieldGroup.displayName = 'ColorField.Group';
112
+
113
+ export type ColorFieldInputProps = ColorFieldInputPrimitiveProps & {
114
+ readonly className?: string;
115
+ readonly placeholderTextColorClassName?: string;
116
+ };
117
+
118
+ const ColorFieldInput = forwardRef<TextInput, ColorFieldInputProps>(
119
+ ({ className, placeholderTextColorClassName, style, ...props }, ref) => {
120
+ const { size } = useColorFieldStyleContext();
121
+
122
+ return (
123
+ <ColorFieldInputPrimitive
124
+ ref={ref}
125
+ className={cn(colorFieldInputVariants({ size: size ?? 'default' }), className)}
126
+ placeholderTextColorClassName={cn(
127
+ colorFieldInputPlaceholderVariants(),
128
+ placeholderTextColorClassName,
129
+ )}
130
+ style={style}
131
+ {...props}
132
+ {...mergeDataAttributes(props, dataAttributes({ slot: 'color-field-input' }))}
133
+ />
134
+ );
135
+ },
136
+ );
137
+
138
+ ColorFieldInput.displayName = 'ColorField.Input';
139
+
140
+ export interface ColorFieldSlotProps extends ViewProps {
141
+ readonly asChild?: boolean;
142
+ readonly className?: string;
143
+ readonly children?: ReactNode;
144
+ readonly position?: IconSlotPosition;
145
+ }
146
+
147
+ const ColorFieldSlot = forwardRef<View, ColorFieldSlotProps>(
148
+ ({ asChild, position, className, children, style, ...props }, ref) => {
149
+ const Comp = asChild ? Slot : View;
150
+
151
+ return (
152
+ <Comp
153
+ ref={ref}
154
+ className={cn(colorFieldSlotVariants(), className)}
155
+ style={style}
156
+ {...props}
157
+ {...mergeDataAttributes(
158
+ props,
159
+ dataAttributes({ slot: 'color-field-slot' }),
160
+ positionToDataIcon(position),
161
+ )}
162
+ >
163
+ {children}
164
+ </Comp>
165
+ );
166
+ },
167
+ );
168
+
169
+ ColorFieldSlot.displayName = 'ColorField.Slot';
170
+
171
+ type ColorFieldCompoundComponent = typeof ColorFieldRoot & {
172
+ Group: typeof ColorFieldGroup;
173
+ Input: typeof ColorFieldInput;
174
+ Slot: typeof ColorFieldSlot;
175
+ };
176
+
177
+ export const ColorField = Object.assign(ColorFieldRoot, {
178
+ Group: ColorFieldGroup,
179
+ Input: ColorFieldInput,
180
+ Slot: ColorFieldSlot,
181
+ }) as ColorFieldCompoundComponent;
@@ -0,0 +1,20 @@
1
+ import { cva } from '@cdx-ui/utils';
2
+ import {
3
+ inputFieldPlaceholderVariants,
4
+ inputFieldVariants,
5
+ inputRootVariants,
6
+ inputSlotVariants,
7
+ type InputVariantProps,
8
+ } from '../Input/styles';
9
+
10
+ export const colorFieldVariants = cva('gap-1.5');
11
+
12
+ export const colorFieldGroupVariants = inputRootVariants;
13
+
14
+ export const colorFieldInputVariants = inputFieldVariants;
15
+
16
+ export const colorFieldInputPlaceholderVariants = inputFieldPlaceholderVariants;
17
+
18
+ export const colorFieldSlotVariants = inputSlotVariants;
19
+
20
+ export type ColorFieldGroupVariantProps = InputVariantProps;
@@ -0,0 +1,110 @@
1
+ import { forwardRef, type ReactNode } from 'react';
2
+ import { View } from 'react-native';
3
+ import {
4
+ ColorPickerProvider,
5
+ ColorPickerRoot as ColorPickerRootPrimitive,
6
+ ColorPickerRootProvider,
7
+ ColorPickerTrigger as ColorPickerTriggerPrimitive,
8
+ dataAttributes,
9
+ mergeDataAttributes,
10
+ useColorPickerRootContext,
11
+ type ColorPickerRootProps as ColorPickerRootPrimitiveProps,
12
+ type ColorPickerTriggerProps as ColorPickerTriggerPrimitiveProps,
13
+ } from '@cdx-ui/primitives';
14
+ import { cn } from '@cdx-ui/utils';
15
+ import { PickerPopoverSurface } from '../picker/surfaces';
16
+ import {
17
+ colorPickerPopoverContentVariants,
18
+ colorPickerPopoverVariants,
19
+ colorPickerTriggerVariants,
20
+ colorPickerVariants,
21
+ } from './styles';
22
+
23
+ export interface ColorPickerProps extends ColorPickerRootPrimitiveProps {
24
+ readonly className?: string;
25
+ }
26
+
27
+ const ColorPickerRoot = forwardRef<View, ColorPickerProps>(
28
+ ({ asChild, className, style, children, ...props }, ref) => (
29
+ <ColorPickerRootPrimitive
30
+ ref={ref}
31
+ asChild={asChild}
32
+ className={cn(colorPickerVariants(), className)}
33
+ style={style}
34
+ {...props}
35
+ {...mergeDataAttributes(props, dataAttributes({ slot: 'color-picker' }))}
36
+ >
37
+ {children}
38
+ </ColorPickerRootPrimitive>
39
+ ),
40
+ );
41
+
42
+ ColorPickerRoot.displayName = 'ColorPicker';
43
+
44
+ export interface ColorPickerTriggerProps extends ColorPickerTriggerPrimitiveProps {
45
+ readonly className?: string;
46
+ }
47
+
48
+ const ColorPickerTrigger = forwardRef<View, ColorPickerTriggerProps>(
49
+ ({ asChild, className, style, children, ...props }, ref) => (
50
+ <ColorPickerTriggerPrimitive
51
+ ref={ref}
52
+ asChild={asChild}
53
+ className={asChild ? className : cn(colorPickerTriggerVariants(), className)}
54
+ style={style}
55
+ {...props}
56
+ {...mergeDataAttributes(props, dataAttributes({ slot: 'color-picker-trigger' }))}
57
+ >
58
+ {children}
59
+ </ColorPickerTriggerPrimitive>
60
+ ),
61
+ );
62
+
63
+ ColorPickerTrigger.displayName = 'ColorPicker.Trigger';
64
+
65
+ export interface ColorPickerPopoverProps {
66
+ readonly className?: string;
67
+ readonly contentClassName?: string;
68
+ readonly children: ReactNode;
69
+ }
70
+
71
+ const registerPopoverSurface = (type: 'popover') => {
72
+ void type;
73
+ };
74
+
75
+ function ColorPickerPopover({ className, contentClassName, children }: ColorPickerPopoverProps) {
76
+ const context = useColorPickerRootContext();
77
+
78
+ return (
79
+ <PickerPopoverSurface
80
+ open={context.open}
81
+ setOpen={context.setOpen}
82
+ registerSurface={registerPopoverSurface}
83
+ anchorRef={context.anchorRef}
84
+ triggerRef={context.triggerRef}
85
+ className={cn(colorPickerPopoverVariants(), className)}
86
+ contentClassName={cn(colorPickerPopoverContentVariants(), contentClassName)}
87
+ dataSlot="color-picker-popover"
88
+ width="content"
89
+ >
90
+ <ColorPickerRootProvider value={context}>
91
+ <ColorPickerProvider value={context}>{children}</ColorPickerProvider>
92
+ </ColorPickerRootProvider>
93
+ </PickerPopoverSurface>
94
+ );
95
+ }
96
+
97
+ ColorPickerPopover.displayName = 'ColorPicker.Popover';
98
+
99
+ type ColorPickerCompoundComponent = typeof ColorPickerRoot & {
100
+ Trigger: typeof ColorPickerTrigger;
101
+ Popover: typeof ColorPickerPopover;
102
+ };
103
+
104
+ export const ColorPicker = Object.assign(ColorPickerRoot, {
105
+ Trigger: ColorPickerTrigger,
106
+ Popover: ColorPickerPopover,
107
+ }) as ColorPickerCompoundComponent;
108
+
109
+ export { parseColor } from '@cdx-ui/primitives';
110
+ export type { Color } from '@cdx-ui/primitives';
@@ -0,0 +1,33 @@
1
+ import { Platform } from 'react-native';
2
+ import { cva } from '@cdx-ui/utils';
3
+ import { DISABLED_CURSOR, TRANSITION_COLORS } from '../../styles/constants';
4
+
5
+ export const colorPickerVariants = cva(['items-start gap-2']);
6
+
7
+ export const colorPickerTriggerVariants = cva([
8
+ 'h-10 self-start flex-row items-center justify-center gap-2 px-3',
9
+ 'rounded-[var(--border-radius-button)]',
10
+ 'border border-stroke-action bg-transparent',
11
+ TRANSITION_COLORS,
12
+ 'data-[disabled=true]:opacity-[var(--opacity-disabled)]',
13
+ DISABLED_CURSOR,
14
+ 'web:outline-none web:focus:outline-none web:focus-visible:outline-none',
15
+ 'web:data-[focus-visible=true]:ring-2',
16
+ 'web:data-[focus-visible=true]:ring-stroke-focus',
17
+ 'web:data-[focus-visible=true]:ring-offset-2',
18
+ Platform.select({
19
+ default: 'data-[active=true]:bg-surface-action-tint-active',
20
+ web: [
21
+ 'data-[hover=true]:bg-surface-action-tint-hover',
22
+ 'data-[active=true]:data-[hover=true]:bg-surface-action-tint-active',
23
+ ].join(' '),
24
+ }),
25
+ ]);
26
+
27
+ /**
28
+ * Padding lives on the scroll content, not the popover: the popover's `ScrollView` clips at its
29
+ * own bounds, and slider/area thumbs overhang their track ends by half a thumb plus shadow.
30
+ */
31
+ export const colorPickerPopoverVariants = cva(['w-80 p-0']);
32
+
33
+ export const colorPickerPopoverContentVariants = cva(['gap-3 p-4']);
@@ -0,0 +1,60 @@
1
+ import { useId } from 'react';
2
+ import { StyleSheet, View } from 'react-native';
3
+ import { Defs, LinearGradient, Rect, Stop, Svg } from 'react-native-svg';
4
+ import { useColorSliderContext } from '@cdx-ui/primitives';
5
+ import { colorSliderRailPaintVariants } from './styles';
6
+
7
+ function getStopOffset(index: number, count: number, railSize: number, endCap: number): string {
8
+ const ratio = index / (count - 1);
9
+ if (railSize <= 0 || endCap <= 0) {
10
+ return `${String(ratio * 100)}%`;
11
+ }
12
+ return `${String(((endCap + ratio * railSize) / (railSize + 2 * endCap)) * 100)}%`;
13
+ }
14
+
15
+ export function ColorSliderRailPaint() {
16
+ const { gradientColors, orientation, layout, thumbSize } = useColorSliderContext();
17
+ const gradientId = useId();
18
+ const isVertical = orientation === 'vertical';
19
+ const railSize = (isVertical ? layout?.height : layout?.width) ?? 0;
20
+ const endCap = (isVertical ? thumbSize.height : thumbSize.width) / 2;
21
+
22
+ return (
23
+ <View
24
+ className={colorSliderRailPaintVariants({ orientation })}
25
+ style={styles.paint}
26
+ accessible={false}
27
+ accessibilityElementsHidden
28
+ importantForAccessibility="no-hide-descendants"
29
+ >
30
+ <Svg width="100%" height="100%">
31
+ <Defs>
32
+ <LinearGradient
33
+ id={gradientId}
34
+ x1="0%"
35
+ y1={orientation === 'vertical' ? '100%' : '0%'}
36
+ x2={orientation === 'horizontal' ? '100%' : '0%'}
37
+ y2="0%"
38
+ >
39
+ {gradientColors.map((color, index) => (
40
+ <Stop
41
+ key={`${color}-${String(index)}`}
42
+ offset={getStopOffset(index, gradientColors.length, railSize, endCap)}
43
+ stopColor={color}
44
+ />
45
+ ))}
46
+ </LinearGradient>
47
+ </Defs>
48
+ <Rect width="100%" height="100%" fill={`url(#${gradientId})`} />
49
+ </Svg>
50
+ </View>
51
+ );
52
+ }
53
+
54
+ ColorSliderRailPaint.displayName = 'ColorSliderRailPaint';
55
+
56
+ const styles = StyleSheet.create({
57
+ paint: {
58
+ pointerEvents: 'none',
59
+ },
60
+ });
@@ -0,0 +1,33 @@
1
+ import { View, type ViewStyle } from 'react-native';
2
+ import { useColorSliderContext } from '@cdx-ui/primitives';
3
+ import { colorSliderRailPaintVariants } from './styles';
4
+
5
+ function getGradientStops(colors: readonly string[], endCap: number): string {
6
+ if (endCap <= 0 || colors.length < 2) {
7
+ return colors.join(', ');
8
+ }
9
+ const first = `${colors[0]} ${String(endCap)}px`;
10
+ const last = `${colors[colors.length - 1]} calc(100% - ${String(endCap)}px)`;
11
+ return [first, ...colors.slice(1, -1), last].join(', ');
12
+ }
13
+
14
+ export function ColorSliderRailPaint() {
15
+ const { gradientColors, orientation, thumbSize } = useColorSliderContext();
16
+ const direction = orientation === 'vertical' ? 'to top' : 'to right';
17
+ const endCap = (orientation === 'vertical' ? thumbSize.height : thumbSize.width) / 2;
18
+ const paintStyle = {
19
+ backgroundImage: `linear-gradient(${direction}, ${getGradientStops(gradientColors, endCap)})`,
20
+ } as unknown as ViewStyle;
21
+
22
+ return (
23
+ <View
24
+ className={colorSliderRailPaintVariants({ orientation })}
25
+ style={paintStyle}
26
+ accessible={false}
27
+ accessibilityElementsHidden
28
+ importantForAccessibility="no-hide-descendants"
29
+ />
30
+ );
31
+ }
32
+
33
+ ColorSliderRailPaint.displayName = 'ColorSliderRailPaint';