@cdx-ui/components 0.1.4 → 0.1.6

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 (270) hide show
  1. package/README.md +1 -1
  2. package/coverage.svg +1 -1
  3. package/lib/commonjs/components/ToggleButton/index.js +249 -0
  4. package/lib/commonjs/components/ToggleButton/index.js.map +1 -0
  5. package/lib/commonjs/components/ToggleButton/styles.js +155 -0
  6. package/lib/commonjs/components/ToggleButton/styles.js.map +1 -0
  7. package/lib/commonjs/components/index.js +12 -0
  8. package/lib/commonjs/components/index.js.map +1 -1
  9. package/lib/commonjs/figma/Calendar.figma.js +28 -0
  10. package/lib/commonjs/figma/Calendar.figma.js.map +1 -0
  11. package/lib/commonjs/figma/Carousel.NextButton.figma.js +27 -0
  12. package/lib/commonjs/figma/Carousel.NextButton.figma.js.map +1 -0
  13. package/lib/commonjs/figma/Carousel.Pagination.figma.js +22 -0
  14. package/lib/commonjs/figma/Carousel.Pagination.figma.js.map +1 -0
  15. package/lib/commonjs/figma/Carousel.PrevButton.figma.js +27 -0
  16. package/lib/commonjs/figma/Carousel.PrevButton.figma.js.map +1 -0
  17. package/lib/commonjs/figma/Carousel.figma.js +37 -0
  18. package/lib/commonjs/figma/Carousel.figma.js.map +1 -0
  19. package/lib/commonjs/figma/Checkbox.Group.figma.js +24 -0
  20. package/lib/commonjs/figma/Checkbox.Group.figma.js.map +1 -0
  21. package/lib/commonjs/figma/CurrencyInput.figma.js +54 -0
  22. package/lib/commonjs/figma/CurrencyInput.figma.js.map +1 -0
  23. package/lib/commonjs/figma/DateField.figma.js +58 -0
  24. package/lib/commonjs/figma/DateField.figma.js.map +1 -0
  25. package/lib/commonjs/figma/DatePicker.figma.js +88 -0
  26. package/lib/commonjs/figma/DatePicker.figma.js.map +1 -0
  27. package/lib/commonjs/figma/DateRangePicker.figma.js +85 -0
  28. package/lib/commonjs/figma/DateRangePicker.figma.js.map +1 -0
  29. package/lib/commonjs/figma/DateTimeField.figma.js +69 -0
  30. package/lib/commonjs/figma/DateTimeField.figma.js.map +1 -0
  31. package/lib/commonjs/figma/Field.Checkbox.figma.js +52 -0
  32. package/lib/commonjs/figma/Field.Checkbox.figma.js.map +1 -0
  33. package/lib/commonjs/figma/Field.DateField.figma.js +57 -0
  34. package/lib/commonjs/figma/Field.DateField.figma.js.map +1 -0
  35. package/lib/commonjs/figma/Field.DateTimeField.figma.js +57 -0
  36. package/lib/commonjs/figma/Field.DateTimeField.figma.js.map +1 -0
  37. package/lib/commonjs/figma/Image.figma.js +22 -0
  38. package/lib/commonjs/figma/Image.figma.js.map +1 -0
  39. package/lib/commonjs/figma/MonthCalendar.figma.js +18 -0
  40. package/lib/commonjs/figma/MonthCalendar.figma.js.map +1 -0
  41. package/lib/commonjs/figma/ProgressBar.figma.js +54 -0
  42. package/lib/commonjs/figma/ProgressBar.figma.js.map +1 -0
  43. package/lib/commonjs/figma/ProgressCircle.figma.js +73 -0
  44. package/lib/commonjs/figma/ProgressCircle.figma.js.map +1 -0
  45. package/lib/commonjs/figma/RangeCalendar.figma.js +36 -0
  46. package/lib/commonjs/figma/RangeCalendar.figma.js.map +1 -0
  47. package/lib/commonjs/figma/Skeleton.figma.js +31 -0
  48. package/lib/commonjs/figma/Skeleton.figma.js.map +1 -0
  49. package/lib/commonjs/figma/Slider.Marker.figma.js +21 -0
  50. package/lib/commonjs/figma/Slider.Marker.figma.js.map +1 -0
  51. package/lib/commonjs/figma/Slider.MarkerGroup.figma.js +22 -0
  52. package/lib/commonjs/figma/Slider.MarkerGroup.figma.js.map +1 -0
  53. package/lib/commonjs/figma/Slider.Thumb.figma.js +22 -0
  54. package/lib/commonjs/figma/Slider.Thumb.figma.js.map +1 -0
  55. package/lib/commonjs/figma/Slider.figma.js +69 -0
  56. package/lib/commonjs/figma/Slider.figma.js.map +1 -0
  57. package/lib/commonjs/figma/Switch.figma.js +36 -0
  58. package/lib/commonjs/figma/Switch.figma.js.map +1 -0
  59. package/lib/commonjs/figma/Tabs.SegmentedControl.Segment.figma.js +34 -0
  60. package/lib/commonjs/figma/Tabs.SegmentedControl.Segment.figma.js.map +1 -0
  61. package/lib/commonjs/figma/Tabs.SegmentedControl.figma.js +43 -0
  62. package/lib/commonjs/figma/Tabs.SegmentedControl.figma.js.map +1 -0
  63. package/lib/commonjs/figma/Tabs.Tab.figma.js +34 -0
  64. package/lib/commonjs/figma/Tabs.Tab.figma.js.map +1 -0
  65. package/lib/commonjs/figma/Tabs.figma.js +39 -0
  66. package/lib/commonjs/figma/Tabs.figma.js.map +1 -0
  67. package/lib/commonjs/figma/Tile.Description.figma.js +23 -0
  68. package/lib/commonjs/figma/Tile.Description.figma.js.map +1 -0
  69. package/lib/commonjs/figma/Tile.Group.figma.js +45 -0
  70. package/lib/commonjs/figma/Tile.Group.figma.js.map +1 -0
  71. package/lib/commonjs/figma/Tile.LeadingSlot.figma.js +23 -0
  72. package/lib/commonjs/figma/Tile.LeadingSlot.figma.js.map +1 -0
  73. package/lib/commonjs/figma/Tile.Title.figma.js +23 -0
  74. package/lib/commonjs/figma/Tile.Title.figma.js.map +1 -0
  75. package/lib/commonjs/figma/Tile.TrailingSlot.figma.js +23 -0
  76. package/lib/commonjs/figma/Tile.TrailingSlot.figma.js.map +1 -0
  77. package/lib/commonjs/figma/Tile.figma.js +57 -0
  78. package/lib/commonjs/figma/Tile.figma.js.map +1 -0
  79. package/lib/commonjs/figma/Toast.Button.figma.js +32 -0
  80. package/lib/commonjs/figma/Toast.Button.figma.js.map +1 -0
  81. package/lib/commonjs/figma/Toast.Close.figma.js +20 -0
  82. package/lib/commonjs/figma/Toast.Close.figma.js.map +1 -0
  83. package/lib/commonjs/figma/Toast.figma.js +81 -0
  84. package/lib/commonjs/figma/Toast.figma.js.map +1 -0
  85. package/lib/commonjs/figma/Tooltip.Content.figma.js +30 -0
  86. package/lib/commonjs/figma/Tooltip.Content.figma.js.map +1 -0
  87. package/lib/commonjs/figma/Tooltip.figma.js +46 -0
  88. package/lib/commonjs/figma/Tooltip.figma.js.map +1 -0
  89. package/lib/commonjs/figma/VirtualizedList.figma.js +31 -0
  90. package/lib/commonjs/figma/VirtualizedList.figma.js.map +1 -0
  91. package/lib/module/components/ToggleButton/index.js +245 -0
  92. package/lib/module/components/ToggleButton/index.js.map +1 -0
  93. package/lib/module/components/ToggleButton/styles.js +152 -0
  94. package/lib/module/components/ToggleButton/styles.js.map +1 -0
  95. package/lib/module/components/index.js +1 -0
  96. package/lib/module/components/index.js.map +1 -1
  97. package/lib/module/figma/Calendar.figma.js +22 -0
  98. package/lib/module/figma/Calendar.figma.js.map +1 -0
  99. package/lib/module/figma/Carousel.NextButton.figma.js +21 -0
  100. package/lib/module/figma/Carousel.NextButton.figma.js.map +1 -0
  101. package/lib/module/figma/Carousel.Pagination.figma.js +18 -0
  102. package/lib/module/figma/Carousel.Pagination.figma.js.map +1 -0
  103. package/lib/module/figma/Carousel.PrevButton.figma.js +21 -0
  104. package/lib/module/figma/Carousel.PrevButton.figma.js.map +1 -0
  105. package/lib/module/figma/Carousel.figma.js +31 -0
  106. package/lib/module/figma/Carousel.figma.js.map +1 -0
  107. package/lib/module/figma/Checkbox.Group.figma.js +18 -0
  108. package/lib/module/figma/Checkbox.Group.figma.js.map +1 -0
  109. package/lib/module/figma/CurrencyInput.figma.js +48 -0
  110. package/lib/module/figma/CurrencyInput.figma.js.map +1 -0
  111. package/lib/module/figma/DateField.figma.js +52 -0
  112. package/lib/module/figma/DateField.figma.js.map +1 -0
  113. package/lib/module/figma/DatePicker.figma.js +82 -0
  114. package/lib/module/figma/DatePicker.figma.js.map +1 -0
  115. package/lib/module/figma/DateRangePicker.figma.js +79 -0
  116. package/lib/module/figma/DateRangePicker.figma.js.map +1 -0
  117. package/lib/module/figma/DateTimeField.figma.js +63 -0
  118. package/lib/module/figma/DateTimeField.figma.js.map +1 -0
  119. package/lib/module/figma/Field.Checkbox.figma.js +46 -0
  120. package/lib/module/figma/Field.Checkbox.figma.js.map +1 -0
  121. package/lib/module/figma/Field.DateField.figma.js +51 -0
  122. package/lib/module/figma/Field.DateField.figma.js.map +1 -0
  123. package/lib/module/figma/Field.DateTimeField.figma.js +51 -0
  124. package/lib/module/figma/Field.DateTimeField.figma.js.map +1 -0
  125. package/lib/module/figma/Image.figma.js +18 -0
  126. package/lib/module/figma/Image.figma.js.map +1 -0
  127. package/lib/module/figma/MonthCalendar.figma.js +14 -0
  128. package/lib/module/figma/MonthCalendar.figma.js.map +1 -0
  129. package/lib/module/figma/ProgressBar.figma.js +48 -0
  130. package/lib/module/figma/ProgressBar.figma.js.map +1 -0
  131. package/lib/module/figma/ProgressCircle.figma.js +67 -0
  132. package/lib/module/figma/ProgressCircle.figma.js.map +1 -0
  133. package/lib/module/figma/RangeCalendar.figma.js +30 -0
  134. package/lib/module/figma/RangeCalendar.figma.js.map +1 -0
  135. package/lib/module/figma/Skeleton.figma.js +25 -0
  136. package/lib/module/figma/Skeleton.figma.js.map +1 -0
  137. package/lib/module/figma/Slider.Marker.figma.js +17 -0
  138. package/lib/module/figma/Slider.Marker.figma.js.map +1 -0
  139. package/lib/module/figma/Slider.MarkerGroup.figma.js +18 -0
  140. package/lib/module/figma/Slider.MarkerGroup.figma.js.map +1 -0
  141. package/lib/module/figma/Slider.Thumb.figma.js +18 -0
  142. package/lib/module/figma/Slider.Thumb.figma.js.map +1 -0
  143. package/lib/module/figma/Slider.figma.js +63 -0
  144. package/lib/module/figma/Slider.figma.js.map +1 -0
  145. package/lib/module/figma/Switch.figma.js +30 -0
  146. package/lib/module/figma/Switch.figma.js.map +1 -0
  147. package/lib/module/figma/Tabs.SegmentedControl.Segment.figma.js +28 -0
  148. package/lib/module/figma/Tabs.SegmentedControl.Segment.figma.js.map +1 -0
  149. package/lib/module/figma/Tabs.SegmentedControl.figma.js +37 -0
  150. package/lib/module/figma/Tabs.SegmentedControl.figma.js.map +1 -0
  151. package/lib/module/figma/Tabs.Tab.figma.js +28 -0
  152. package/lib/module/figma/Tabs.Tab.figma.js.map +1 -0
  153. package/lib/module/figma/Tabs.figma.js +33 -0
  154. package/lib/module/figma/Tabs.figma.js.map +1 -0
  155. package/lib/module/figma/Tile.Description.figma.js +17 -0
  156. package/lib/module/figma/Tile.Description.figma.js.map +1 -0
  157. package/lib/module/figma/Tile.Group.figma.js +39 -0
  158. package/lib/module/figma/Tile.Group.figma.js.map +1 -0
  159. package/lib/module/figma/Tile.LeadingSlot.figma.js +17 -0
  160. package/lib/module/figma/Tile.LeadingSlot.figma.js.map +1 -0
  161. package/lib/module/figma/Tile.Title.figma.js +17 -0
  162. package/lib/module/figma/Tile.Title.figma.js.map +1 -0
  163. package/lib/module/figma/Tile.TrailingSlot.figma.js +17 -0
  164. package/lib/module/figma/Tile.TrailingSlot.figma.js.map +1 -0
  165. package/lib/module/figma/Tile.figma.js +51 -0
  166. package/lib/module/figma/Tile.figma.js.map +1 -0
  167. package/lib/module/figma/Toast.Button.figma.js +26 -0
  168. package/lib/module/figma/Toast.Button.figma.js.map +1 -0
  169. package/lib/module/figma/Toast.Close.figma.js +15 -0
  170. package/lib/module/figma/Toast.Close.figma.js.map +1 -0
  171. package/lib/module/figma/Toast.figma.js +75 -0
  172. package/lib/module/figma/Toast.figma.js.map +1 -0
  173. package/lib/module/figma/Tooltip.Content.figma.js +24 -0
  174. package/lib/module/figma/Tooltip.Content.figma.js.map +1 -0
  175. package/lib/module/figma/Tooltip.figma.js +40 -0
  176. package/lib/module/figma/Tooltip.figma.js.map +1 -0
  177. package/lib/module/figma/VirtualizedList.figma.js +25 -0
  178. package/lib/module/figma/VirtualizedList.figma.js.map +1 -0
  179. package/lib/typescript/components/ToggleButton/index.d.ts +78 -0
  180. package/lib/typescript/components/ToggleButton/index.d.ts.map +1 -0
  181. package/lib/typescript/components/ToggleButton/styles.d.ts +30 -0
  182. package/lib/typescript/components/ToggleButton/styles.d.ts.map +1 -0
  183. package/lib/typescript/components/index.d.ts +1 -0
  184. package/lib/typescript/components/index.d.ts.map +1 -1
  185. package/lib/typescript/figma/Calendar.figma.d.ts +8 -0
  186. package/lib/typescript/figma/Calendar.figma.d.ts.map +1 -0
  187. package/lib/typescript/figma/Carousel.NextButton.figma.d.ts +11 -0
  188. package/lib/typescript/figma/Carousel.NextButton.figma.d.ts.map +1 -0
  189. package/lib/typescript/figma/Carousel.Pagination.figma.d.ts +11 -0
  190. package/lib/typescript/figma/Carousel.Pagination.figma.d.ts.map +1 -0
  191. package/lib/typescript/figma/Carousel.PrevButton.figma.d.ts +11 -0
  192. package/lib/typescript/figma/Carousel.PrevButton.figma.d.ts.map +1 -0
  193. package/lib/typescript/figma/Carousel.figma.d.ts +8 -0
  194. package/lib/typescript/figma/Carousel.figma.d.ts.map +1 -0
  195. package/lib/typescript/figma/Checkbox.Group.figma.d.ts +8 -0
  196. package/lib/typescript/figma/Checkbox.Group.figma.d.ts.map +1 -0
  197. package/lib/typescript/figma/CurrencyInput.figma.d.ts +8 -0
  198. package/lib/typescript/figma/CurrencyInput.figma.d.ts.map +1 -0
  199. package/lib/typescript/figma/DateField.figma.d.ts +8 -0
  200. package/lib/typescript/figma/DateField.figma.d.ts.map +1 -0
  201. package/lib/typescript/figma/DatePicker.figma.d.ts +8 -0
  202. package/lib/typescript/figma/DatePicker.figma.d.ts.map +1 -0
  203. package/lib/typescript/figma/DateRangePicker.figma.d.ts +8 -0
  204. package/lib/typescript/figma/DateRangePicker.figma.d.ts.map +1 -0
  205. package/lib/typescript/figma/DateTimeField.figma.d.ts +8 -0
  206. package/lib/typescript/figma/DateTimeField.figma.d.ts.map +1 -0
  207. package/lib/typescript/figma/Field.Checkbox.figma.d.ts +8 -0
  208. package/lib/typescript/figma/Field.Checkbox.figma.d.ts.map +1 -0
  209. package/lib/typescript/figma/Field.DateField.figma.d.ts +8 -0
  210. package/lib/typescript/figma/Field.DateField.figma.d.ts.map +1 -0
  211. package/lib/typescript/figma/Field.DateTimeField.figma.d.ts +8 -0
  212. package/lib/typescript/figma/Field.DateTimeField.figma.d.ts.map +1 -0
  213. package/lib/typescript/figma/Image.figma.d.ts +11 -0
  214. package/lib/typescript/figma/Image.figma.d.ts.map +1 -0
  215. package/lib/typescript/figma/MonthCalendar.figma.d.ts +8 -0
  216. package/lib/typescript/figma/MonthCalendar.figma.d.ts.map +1 -0
  217. package/lib/typescript/figma/ProgressBar.figma.d.ts +8 -0
  218. package/lib/typescript/figma/ProgressBar.figma.d.ts.map +1 -0
  219. package/lib/typescript/figma/ProgressCircle.figma.d.ts +11 -0
  220. package/lib/typescript/figma/ProgressCircle.figma.d.ts.map +1 -0
  221. package/lib/typescript/figma/RangeCalendar.figma.d.ts +8 -0
  222. package/lib/typescript/figma/RangeCalendar.figma.d.ts.map +1 -0
  223. package/lib/typescript/figma/Skeleton.figma.d.ts +11 -0
  224. package/lib/typescript/figma/Skeleton.figma.d.ts.map +1 -0
  225. package/lib/typescript/figma/Slider.Marker.figma.d.ts +11 -0
  226. package/lib/typescript/figma/Slider.Marker.figma.d.ts.map +1 -0
  227. package/lib/typescript/figma/Slider.MarkerGroup.figma.d.ts +8 -0
  228. package/lib/typescript/figma/Slider.MarkerGroup.figma.d.ts.map +1 -0
  229. package/lib/typescript/figma/Slider.Thumb.figma.d.ts +11 -0
  230. package/lib/typescript/figma/Slider.Thumb.figma.d.ts.map +1 -0
  231. package/lib/typescript/figma/Slider.figma.d.ts +8 -0
  232. package/lib/typescript/figma/Slider.figma.d.ts.map +1 -0
  233. package/lib/typescript/figma/Switch.figma.d.ts +8 -0
  234. package/lib/typescript/figma/Switch.figma.d.ts.map +1 -0
  235. package/lib/typescript/figma/Tabs.SegmentedControl.Segment.figma.d.ts +8 -0
  236. package/lib/typescript/figma/Tabs.SegmentedControl.Segment.figma.d.ts.map +1 -0
  237. package/lib/typescript/figma/Tabs.SegmentedControl.figma.d.ts +8 -0
  238. package/lib/typescript/figma/Tabs.SegmentedControl.figma.d.ts.map +1 -0
  239. package/lib/typescript/figma/Tabs.Tab.figma.d.ts +8 -0
  240. package/lib/typescript/figma/Tabs.Tab.figma.d.ts.map +1 -0
  241. package/lib/typescript/figma/Tabs.figma.d.ts +8 -0
  242. package/lib/typescript/figma/Tabs.figma.d.ts.map +1 -0
  243. package/lib/typescript/figma/Tile.Description.figma.d.ts +11 -0
  244. package/lib/typescript/figma/Tile.Description.figma.d.ts.map +1 -0
  245. package/lib/typescript/figma/Tile.Group.figma.d.ts +8 -0
  246. package/lib/typescript/figma/Tile.Group.figma.d.ts.map +1 -0
  247. package/lib/typescript/figma/Tile.LeadingSlot.figma.d.ts +8 -0
  248. package/lib/typescript/figma/Tile.LeadingSlot.figma.d.ts.map +1 -0
  249. package/lib/typescript/figma/Tile.Title.figma.d.ts +11 -0
  250. package/lib/typescript/figma/Tile.Title.figma.d.ts.map +1 -0
  251. package/lib/typescript/figma/Tile.TrailingSlot.figma.d.ts +8 -0
  252. package/lib/typescript/figma/Tile.TrailingSlot.figma.d.ts.map +1 -0
  253. package/lib/typescript/figma/Tile.figma.d.ts +8 -0
  254. package/lib/typescript/figma/Tile.figma.d.ts.map +1 -0
  255. package/lib/typescript/figma/Toast.Button.figma.d.ts +14 -0
  256. package/lib/typescript/figma/Toast.Button.figma.d.ts.map +1 -0
  257. package/lib/typescript/figma/Toast.Close.figma.d.ts +11 -0
  258. package/lib/typescript/figma/Toast.Close.figma.d.ts.map +1 -0
  259. package/lib/typescript/figma/Toast.figma.d.ts +8 -0
  260. package/lib/typescript/figma/Toast.figma.d.ts.map +1 -0
  261. package/lib/typescript/figma/Tooltip.Content.figma.d.ts +8 -0
  262. package/lib/typescript/figma/Tooltip.Content.figma.d.ts.map +1 -0
  263. package/lib/typescript/figma/Tooltip.figma.d.ts +8 -0
  264. package/lib/typescript/figma/Tooltip.figma.d.ts.map +1 -0
  265. package/lib/typescript/figma/VirtualizedList.figma.d.ts +8 -0
  266. package/lib/typescript/figma/VirtualizedList.figma.d.ts.map +1 -0
  267. package/package.json +6 -6
  268. package/src/components/ToggleButton/index.tsx +346 -0
  269. package/src/components/ToggleButton/styles.ts +191 -0
  270. package/src/components/index.ts +1 -0
@@ -0,0 +1,346 @@
1
+ import React, { forwardRef, useMemo, type ReactElement, type ReactNode } from 'react';
2
+ import { Text, View, type StyleProp, type TextProps, type ViewStyle } from 'react-native';
3
+ import {
4
+ Slot,
5
+ ToggleButtonGroup as ToggleButtonGroupPrimitive,
6
+ ToggleButtonRoot as ToggleButtonRootPrimitive,
7
+ dataAttributes,
8
+ mergeDataAttributes,
9
+ useToggleButtonContext,
10
+ type IToggleButtonGroupMultipleProps,
11
+ type IToggleButtonGroupSingleProps,
12
+ type IToggleButtonProps,
13
+ } from '@cdx-ui/primitives';
14
+ import {
15
+ cn,
16
+ flattenChildren,
17
+ ParentContext,
18
+ useParentContext,
19
+ useStyleContext,
20
+ } from '@cdx-ui/utils';
21
+ import { Icon, type IconProps } from '../Icon';
22
+ import { positionToDataIcon, type IconSlotPosition } from '../../utils/positionToDataIcon';
23
+ import {
24
+ toggleButtonAttachedVariants,
25
+ toggleButtonGroupVariants,
26
+ toggleButtonIconVariants,
27
+ toggleButtonLabelVariants,
28
+ toggleButtonRootVariants,
29
+ type ToggleButtonAttachedPosition,
30
+ type ToggleButtonGroupVariantProps,
31
+ type ToggleButtonVariantProps,
32
+ } from './styles';
33
+
34
+ const SCOPE = 'TOGGLE_BUTTON';
35
+
36
+ const useToggleButtonStyleContext = () => useStyleContext(SCOPE) as ToggleButtonVariantProps;
37
+
38
+ // =============================================================================
39
+ // STYLED ROOT COMPONENT
40
+ // =============================================================================
41
+
42
+ export type ToggleButtonVariant = 'default' | 'outline' | 'ghost';
43
+ export type ToggleButtonShape = NonNullable<ToggleButtonVariantProps['shape']>;
44
+
45
+ export interface ToggleButtonProps extends IToggleButtonProps {
46
+ /**
47
+ * Visual style. `default` is a muted filled surface; `outline` adds a border; `ghost` is transparent.
48
+ * @default 'default'
49
+ */
50
+ variant?: ToggleButtonVariant;
51
+ /**
52
+ * Corner geometry — mirrors `Avatar.shape`.
53
+ * @default 'circle'
54
+ */
55
+ shape?: ToggleButtonShape;
56
+ /**
57
+ * Height and padding scale.
58
+ * @default 'default'
59
+ */
60
+ size?: 'small' | 'default' | 'large';
61
+ className?: string;
62
+ children?: ReactNode;
63
+ }
64
+
65
+ const ToggleButtonRoot = forwardRef<View, ToggleButtonProps>(
66
+ (
67
+ {
68
+ variant = 'default',
69
+ shape = 'circle',
70
+ size = 'default',
71
+ className,
72
+ children,
73
+ style,
74
+ isDisabled,
75
+ ...props
76
+ },
77
+ ref,
78
+ ) => {
79
+ const content = flattenChildren(children);
80
+ const iconOnly =
81
+ content.length === 1 &&
82
+ React.isValidElement(content[0]) &&
83
+ content[0].type === ToggleButtonIcon;
84
+ const computedClassName = cn(
85
+ toggleButtonRootVariants({ variant, shape, size, iconOnly }),
86
+ className,
87
+ );
88
+
89
+ const parent = useParentContext();
90
+ const ctx = useMemo(
91
+ () => ({ ...parent, [SCOPE]: { variant, shape, size } }),
92
+ [parent, variant, shape, size],
93
+ );
94
+
95
+ return (
96
+ <ParentContext.Provider value={ctx}>
97
+ <ToggleButtonRootPrimitive
98
+ ref={ref}
99
+ className={computedClassName}
100
+ style={style}
101
+ isDisabled={isDisabled}
102
+ {...props}
103
+ {...mergeDataAttributes(props, dataAttributes({ slot: 'toggle-button' }))}
104
+ >
105
+ {children}
106
+ </ToggleButtonRootPrimitive>
107
+ </ParentContext.Provider>
108
+ );
109
+ },
110
+ );
111
+
112
+ ToggleButtonRoot.displayName = 'ToggleButton';
113
+
114
+ // =============================================================================
115
+ // STYLED LABEL COMPONENT
116
+ // =============================================================================
117
+
118
+ export interface ToggleButtonLabelProps extends TextProps {
119
+ /** Render the consumer's child in place of the default `Text` host. */
120
+ asChild?: boolean;
121
+ className?: string;
122
+ children?: ReactNode;
123
+ }
124
+
125
+ const ToggleButtonLabel = forwardRef<Text, ToggleButtonLabelProps>(
126
+ ({ asChild, className, children, style, ...props }, ref) => {
127
+ const { size } = useToggleButtonStyleContext();
128
+ const { isSelected, hover, active } = useToggleButtonContext();
129
+ const computedClassName = cn(toggleButtonLabelVariants({ size }), className);
130
+ const Comp = asChild ? Slot : Text;
131
+
132
+ return (
133
+ <Comp
134
+ ref={ref}
135
+ className={computedClassName}
136
+ style={style}
137
+ {...props}
138
+ {...mergeDataAttributes(
139
+ props,
140
+ dataAttributes({
141
+ slot: 'toggle-button-label',
142
+ selected: isSelected,
143
+ hover,
144
+ active,
145
+ }),
146
+ )}
147
+ >
148
+ {children}
149
+ </Comp>
150
+ );
151
+ },
152
+ );
153
+
154
+ ToggleButtonLabel.displayName = 'ToggleButton.Label';
155
+
156
+ // =============================================================================
157
+ // STYLED ICON COMPONENT
158
+ // =============================================================================
159
+
160
+ export interface ToggleButtonIconProps extends Omit<IconProps, 'children' | 'as'> {
161
+ /** Render a custom element instead of the default icon. */
162
+ asChild?: boolean;
163
+ /** Forge icon component to render. */
164
+ as?: IconProps['as'];
165
+ /** Leading or trailing placement relative to the label. */
166
+ position?: IconSlotPosition;
167
+ /**
168
+ * Render the filled icon variant. Defaults to the toggle's selected state.
169
+ * Icons without filled path data stay outlined.
170
+ */
171
+ filled?: boolean;
172
+ }
173
+
174
+ const ToggleButtonIcon = ({
175
+ asChild,
176
+ className,
177
+ style,
178
+ as,
179
+ position,
180
+ filled,
181
+ ...props
182
+ }: ToggleButtonIconProps) => {
183
+ const { size } = useToggleButtonStyleContext();
184
+ const { isSelected, hover, active } = useToggleButtonContext();
185
+ const computedClassName = cn(toggleButtonIconVariants({ size }), className);
186
+ const resolvedFilled = filled ?? isSelected;
187
+ const interactionAttributes = dataAttributes({
188
+ slot: 'toggle-button-icon',
189
+ selected: isSelected,
190
+ hover,
191
+ active,
192
+ });
193
+
194
+ if (asChild) {
195
+ return (
196
+ <Slot
197
+ className={computedClassName}
198
+ style={style}
199
+ filled={resolvedFilled}
200
+ {...props}
201
+ {...mergeDataAttributes(props, interactionAttributes, positionToDataIcon(position))}
202
+ />
203
+ );
204
+ }
205
+
206
+ if (!as) {
207
+ return null;
208
+ }
209
+
210
+ return (
211
+ <Icon
212
+ as={as}
213
+ className={computedClassName}
214
+ style={style}
215
+ filled={resolvedFilled}
216
+ {...props}
217
+ {...mergeDataAttributes(props, interactionAttributes, positionToDataIcon(position))}
218
+ />
219
+ );
220
+ };
221
+
222
+ ToggleButtonIcon.displayName = 'ToggleButton.Icon';
223
+
224
+ // =============================================================================
225
+ // STYLED GROUP COMPONENT
226
+ // =============================================================================
227
+
228
+ type ToggleButtonGroupSingleStyledProps = IToggleButtonGroupSingleProps &
229
+ ToggleButtonGroupVariantProps & {
230
+ className?: string;
231
+ children: ReactElement | ReactElement[];
232
+ /**
233
+ * Collapse gaps and adjoining corners into a single segmented control.
234
+ * @default true
235
+ */
236
+ isAttached?: boolean;
237
+ };
238
+
239
+ type ToggleButtonGroupMultipleStyledProps = IToggleButtonGroupMultipleProps &
240
+ ToggleButtonGroupVariantProps & {
241
+ className?: string;
242
+ children: ReactElement | ReactElement[];
243
+ /**
244
+ * Collapse gaps and adjoining corners into a single segmented control.
245
+ * @default true
246
+ */
247
+ isAttached?: boolean;
248
+ };
249
+
250
+ export type ToggleButtonGroupProps =
251
+ | ToggleButtonGroupSingleStyledProps
252
+ | ToggleButtonGroupMultipleStyledProps;
253
+
254
+ type AttachedOrientation = NonNullable<ToggleButtonGroupVariantProps['orientation']>;
255
+
256
+ const ATTACHED_RADIUS_STYLES: Record<
257
+ AttachedOrientation,
258
+ Record<ToggleButtonAttachedPosition, ViewStyle | undefined>
259
+ > = {
260
+ horizontal: {
261
+ only: undefined,
262
+ first: { borderTopRightRadius: 0, borderBottomRightRadius: 0 },
263
+ middle: { borderRadius: 0 },
264
+ last: { borderTopLeftRadius: 0, borderBottomLeftRadius: 0 },
265
+ },
266
+ vertical: {
267
+ only: undefined,
268
+ first: { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 },
269
+ middle: { borderRadius: 0 },
270
+ last: { borderTopLeftRadius: 0, borderTopRightRadius: 0 },
271
+ },
272
+ };
273
+
274
+ function getAttachedPosition(index: number, count: number): ToggleButtonAttachedPosition {
275
+ if (count <= 1) {
276
+ return 'only';
277
+ }
278
+ if (index === 0) {
279
+ return 'first';
280
+ }
281
+ return index === count - 1 ? 'last' : 'middle';
282
+ }
283
+
284
+ const ToggleButtonGroup = forwardRef<View, ToggleButtonGroupProps>(
285
+ (
286
+ {
287
+ asChild,
288
+ className,
289
+ children,
290
+ style,
291
+ orientation = 'horizontal',
292
+ isAttached = true,
293
+ ...props
294
+ },
295
+ ref,
296
+ ) => {
297
+ const childrenArray = React.Children.toArray(flattenChildren(children));
298
+
299
+ const computedChildren = isAttached
300
+ ? childrenArray.map((child, index) => {
301
+ if (!React.isValidElement<{ className?: string; style?: StyleProp<ViewStyle> }>(child)) {
302
+ return child;
303
+ }
304
+
305
+ const position = getAttachedPosition(index, childrenArray.length);
306
+ const radiusStyle = ATTACHED_RADIUS_STYLES[orientation][position];
307
+
308
+ return React.cloneElement(child, {
309
+ className: cn(
310
+ toggleButtonAttachedVariants({ orientation, position }),
311
+ child.props.className,
312
+ ),
313
+ style: radiusStyle ? [radiusStyle, child.props.style] : child.props.style,
314
+ });
315
+ })
316
+ : childrenArray;
317
+
318
+ const groupClassName = cn(toggleButtonGroupVariants({ orientation, isAttached }), className);
319
+
320
+ return (
321
+ <ToggleButtonGroupPrimitive
322
+ ref={ref}
323
+ asChild={asChild}
324
+ className={groupClassName}
325
+ style={style}
326
+ orientation={orientation}
327
+ {...props}
328
+ {...mergeDataAttributes(props, dataAttributes({ slot: 'toggle-button-group' }))}
329
+ >
330
+ {computedChildren}
331
+ </ToggleButtonGroupPrimitive>
332
+ );
333
+ },
334
+ );
335
+
336
+ ToggleButtonGroup.displayName = 'ToggleButtonGroup';
337
+
338
+ export const ToggleButton = Object.assign(ToggleButtonRoot, {
339
+ Label: ToggleButtonLabel,
340
+ Icon: ToggleButtonIcon,
341
+ }) as typeof ToggleButtonRoot & {
342
+ Label: typeof ToggleButtonLabel;
343
+ Icon: typeof ToggleButtonIcon;
344
+ };
345
+
346
+ export { ToggleButtonGroup };
@@ -0,0 +1,191 @@
1
+ import { Platform } from 'react-native';
2
+ import { cva, type VariantProps } from '@cdx-ui/utils';
3
+ import { DISABLED_CURSOR, TRANSITION_COLORS } from '../../styles/constants';
4
+
5
+ // `data-toggle-state` is a single derived value (see the primitive's `getToggleState`), so these
6
+ // selectors never tie on specificity and match on native, where compound `data-[]` chains don't.
7
+ const selectedTint = [
8
+ 'data-[toggle-state=selected]:bg-surface-action-tint',
9
+ 'data-[toggle-state=selected-active]:bg-surface-action-tint-active',
10
+ Platform.select({
11
+ default: '',
12
+ web: 'data-[toggle-state=selected-hover]:bg-surface-action-tint-hover',
13
+ }),
14
+ ];
15
+
16
+ const unselectedTint = [
17
+ 'data-[toggle-state=active]:bg-surface-action-tint-active',
18
+ Platform.select({
19
+ default: '',
20
+ web: 'data-[toggle-state=hover]:bg-surface-action-tint-hover',
21
+ }),
22
+ ];
23
+
24
+ export const toggleButtonRootVariants = cva(
25
+ [
26
+ 'flex-row items-center justify-center self-start shrink-0 web:inline-flex',
27
+ 'web:outline-none web:focus:outline-none web:focus-visible:outline-none',
28
+ TRANSITION_COLORS,
29
+ 'data-[disabled=true]:opacity-[var(--opacity-disabled)]',
30
+ DISABLED_CURSOR,
31
+ 'web:data-[focus-visible=true]:ring-2 web:data-[focus-visible=true]:ring-stroke-focus web:data-[focus-visible=true]:ring-offset-2',
32
+ ],
33
+ {
34
+ variants: {
35
+ variant: {
36
+ /** Muted filled surface. */
37
+ default: ['bg-surface-secondary', 'border-0'],
38
+ outline: [
39
+ 'bg-transparent',
40
+ 'border border-stroke-primary',
41
+ 'web:border-default native:border-[length:var(--border-width-default)]',
42
+ ],
43
+ ghost: ['bg-transparent', 'border-0'],
44
+ },
45
+ shape: {
46
+ circle: 'rounded-[var(--border-radius-round)]',
47
+ rounded: 'rounded-[var(--border-radius-default)]',
48
+ },
49
+ size: {
50
+ small: 'h-8 min-h-8 px-3 gap-1.5',
51
+ default: 'h-11 min-h-11 px-4 gap-2',
52
+ large: 'h-12 min-h-12 px-5 gap-2.5',
53
+ },
54
+ /** Square footprint when the only content is a single `ToggleButton.Icon`. */
55
+ iconOnly: {
56
+ true: 'px-0',
57
+ false: '',
58
+ },
59
+ },
60
+ compoundVariants: [
61
+ { iconOnly: true, size: 'small', className: 'w-8 min-w-8' },
62
+ { iconOnly: true, size: 'default', className: 'w-11 min-w-11' },
63
+ { iconOnly: true, size: 'large', className: 'w-12 min-w-12' },
64
+ {
65
+ variant: 'default',
66
+ className: [
67
+ ...selectedTint,
68
+ 'data-[toggle-state=active]:bg-surface-secondary-active',
69
+ Platform.select({
70
+ default: '',
71
+ web: 'data-[toggle-state=hover]:bg-surface-secondary-hover',
72
+ }),
73
+ ],
74
+ },
75
+ {
76
+ variant: ['outline', 'ghost'],
77
+ className: [...selectedTint, ...unselectedTint],
78
+ },
79
+ {
80
+ variant: 'outline',
81
+ className: 'data-[selected=true]:border-stroke-action',
82
+ },
83
+ ],
84
+ defaultVariants: {
85
+ variant: 'default',
86
+ shape: 'circle',
87
+ size: 'default',
88
+ iconOnly: false,
89
+ },
90
+ },
91
+ );
92
+
93
+ /**
94
+ * Classes for an item inside an attached group. Every item after the first overlaps its
95
+ * predecessor by one border width so adjoining borders collapse into a single line; the
96
+ * interacted or selected item is raised so its full border stays visible.
97
+ */
98
+ export const toggleButtonAttachedVariants = cva(
99
+ ['relative data-[hover=true]:z-[1] data-[active=true]:z-[1] data-[selected=true]:z-[1]'],
100
+ {
101
+ variants: {
102
+ orientation: {
103
+ horizontal: '',
104
+ vertical: 'self-stretch',
105
+ },
106
+ position: {
107
+ only: '',
108
+ first: '',
109
+ middle: '',
110
+ last: '',
111
+ },
112
+ },
113
+ compoundVariants: [
114
+ {
115
+ orientation: 'horizontal',
116
+ position: ['middle', 'last'],
117
+ className: '-ms-[length:var(--border-width-default)]',
118
+ },
119
+ {
120
+ orientation: 'vertical',
121
+ position: ['middle', 'last'],
122
+ className: '-mt-[length:var(--border-width-default)]',
123
+ },
124
+ ],
125
+ defaultVariants: {
126
+ orientation: 'horizontal',
127
+ position: 'only',
128
+ },
129
+ },
130
+ );
131
+
132
+ export type ToggleButtonAttachedPosition = NonNullable<
133
+ VariantProps<typeof toggleButtonAttachedVariants>['position']
134
+ >;
135
+
136
+ export const toggleButtonGroupVariants = cva(['self-start'], {
137
+ variants: {
138
+ orientation: {
139
+ horizontal: 'flex-row',
140
+ vertical: 'flex-col items-stretch w-max max-w-full',
141
+ },
142
+ isAttached: {
143
+ true: 'gap-0',
144
+ false: 'gap-2',
145
+ },
146
+ },
147
+ defaultVariants: {
148
+ orientation: 'horizontal',
149
+ isAttached: true,
150
+ },
151
+ });
152
+
153
+ // Label and Icon emit their own `data-selected` / `data-active` / `data-hover` because
154
+ // native Uniwind cannot style a child from its parent's data attributes.
155
+ const contentColor = [
156
+ 'text-content-primary',
157
+ 'data-[selected=true]:text-content-action',
158
+ Platform.select({
159
+ default: 'data-[active=true]:text-content-action',
160
+ web: 'data-[hover=true]:text-content-action data-[active=true]:text-content-action',
161
+ }),
162
+ ];
163
+
164
+ export const toggleButtonLabelVariants = cva(['shrink-0 font-medium', ...contentColor], {
165
+ variants: {
166
+ size: {
167
+ small: 'text-sm',
168
+ default: 'text-base',
169
+ large: 'text-lg',
170
+ },
171
+ },
172
+ defaultVariants: {
173
+ size: 'default',
174
+ },
175
+ });
176
+
177
+ export const toggleButtonIconVariants = cva(['shrink-0', ...contentColor], {
178
+ variants: {
179
+ size: {
180
+ small: 'size-4',
181
+ default: 'size-5',
182
+ large: 'size-6',
183
+ },
184
+ },
185
+ defaultVariants: {
186
+ size: 'default',
187
+ },
188
+ });
189
+
190
+ export type ToggleButtonVariantProps = VariantProps<typeof toggleButtonRootVariants>;
191
+ export type ToggleButtonGroupVariantProps = VariantProps<typeof toggleButtonGroupVariants>;
@@ -50,6 +50,7 @@ export * from './Tabs';
50
50
  export * from './Table';
51
51
  export * from './Textarea';
52
52
  export * from './Tile';
53
+ export * from './ToggleButton';
53
54
  export * from './Toast';
54
55
  export * from './Tooltip';
55
56
  export { HStack, VStack } from './Stack';