@telus-uds/components-base 0.0.2-prerelease.7 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (445) hide show
  1. package/.eslintrc.js +9 -0
  2. package/.ultra.cache.json +1 -1
  3. package/CHANGELOG.md +71 -0
  4. package/README.md +4 -2
  5. package/__fixtures__/Accessible.js +33 -0
  6. package/__fixtures__/Accessible.native.js +32 -0
  7. package/__fixtures__/test-utils.js +25 -0
  8. package/__fixtures__/testTheme.js +438 -31
  9. package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +1 -1
  10. package/__tests__/Button/ButtonGroup.test.jsx +6 -7
  11. package/__tests__/Checkbox/Checkbox.test.jsx +2 -2
  12. package/__tests__/Checkbox/CheckboxGroup.test.jsx +246 -0
  13. package/__tests__/ExpandCollapse/ExpandCollapse.test.jsx +2 -2
  14. package/__tests__/HorizontalScroll/HorizontalScroll.test.jsx +164 -0
  15. package/__tests__/Icon/Icon.test.jsx +3 -3
  16. package/__tests__/IconButton/IconButton.test.jsx +52 -0
  17. package/__tests__/Link/LinkBase.test.jsx +0 -14
  18. package/__tests__/Modal/Modal.test.jsx +47 -0
  19. package/__tests__/Notification/Notification.test.jsx +20 -0
  20. package/__tests__/Pagination/Pagination.test.jsx +2 -2
  21. package/__tests__/Progress/Progress.test.jsx +79 -0
  22. package/__tests__/Radio/Radio.test.jsx +2 -2
  23. package/__tests__/Radio/RadioGroup.test.jsx +220 -0
  24. package/__tests__/RadioCard/RadioCard.test.jsx +87 -0
  25. package/__tests__/RadioCard/RadioCardGroup.test.jsx +246 -0
  26. package/__tests__/Search/Search.test.jsx +73 -0
  27. package/__tests__/Select/Select.test.jsx +3 -2
  28. package/__tests__/Skeleton/Skeleton.test.jsx +1 -1
  29. package/__tests__/StepTracker/StepTracker.test.jsx +94 -0
  30. package/__tests__/Tabs/Tabs.test.jsx +40 -0
  31. package/__tests__/Tags/Tags.test.jsx +5 -6
  32. package/__tests__/TextInput/TextArea.test.jsx +3 -2
  33. package/__tests__/TextInput/TextInputBase.test.jsx +10 -5
  34. package/__tests__/ThemeProvider/ThemeProvider.test.jsx +77 -0
  35. package/__tests__/ThemeProvider/useThemeTokens.test.jsx +9 -5
  36. package/__tests__/ThemeProvider/utils/theme-tokens.test.js +41 -0
  37. package/__tests__/ToggleSwitch/ToggleSwitch.test.jsx +3 -2
  38. package/__tests__/utils/children.test.jsx +128 -0
  39. package/__tests__/utils/input.test.js +59 -1
  40. package/__tests__/utils/semantics.test.jsx +43 -0
  41. package/__tests__/utils/useCopy.test.js +14 -3
  42. package/babel.config.js +20 -0
  43. package/jest.config.js +6 -3
  44. package/lib/A11yInfoProvider/index.js +54 -26
  45. package/lib/A11yText/index.js +45 -17
  46. package/lib/ActivityIndicator/Spinner.js +81 -0
  47. package/lib/ActivityIndicator/Spinner.native.js +129 -91
  48. package/lib/ActivityIndicator/index.js +28 -12
  49. package/lib/ActivityIndicator/shared.js +27 -12
  50. package/lib/BaseProvider/index.js +34 -11
  51. package/lib/Box/Box.js +153 -35
  52. package/lib/Box/index.js +13 -2
  53. package/lib/Button/Button.js +38 -16
  54. package/lib/Button/ButtonBase.js +93 -79
  55. package/lib/Button/ButtonGroup.js +112 -73
  56. package/lib/Button/ButtonLink.js +45 -19
  57. package/lib/Button/index.js +31 -4
  58. package/lib/Button/propTypes.js +32 -9
  59. package/lib/Card/Card.js +38 -41
  60. package/lib/Card/CardBase.js +86 -0
  61. package/lib/Card/PressableCardBase.js +141 -0
  62. package/lib/Card/index.js +40 -2
  63. package/lib/Checkbox/Checkbox.js +158 -111
  64. package/lib/Checkbox/CheckboxGroup.js +241 -0
  65. package/lib/Checkbox/CheckboxInput.js +74 -0
  66. package/lib/Checkbox/CheckboxInput.native.js +9 -1
  67. package/lib/Checkbox/index.js +21 -2
  68. package/lib/Divider/Divider.js +59 -28
  69. package/lib/Divider/index.js +13 -2
  70. package/lib/ExpandCollapse/Accordion.js +26 -7
  71. package/lib/ExpandCollapse/Control.js +60 -31
  72. package/lib/ExpandCollapse/ExpandCollapse.js +50 -28
  73. package/lib/ExpandCollapse/Panel.js +83 -44
  74. package/lib/ExpandCollapse/index.js +25 -7
  75. package/lib/Feedback/Feedback.js +77 -43
  76. package/lib/Feedback/index.js +13 -2
  77. package/lib/Fieldset/Fieldset.js +165 -0
  78. package/lib/Fieldset/FieldsetContainer.js +46 -0
  79. package/lib/Fieldset/FieldsetContainer.native.js +38 -0
  80. package/lib/Fieldset/Legend.js +38 -0
  81. package/lib/Fieldset/Legend.native.js +48 -0
  82. package/lib/Fieldset/cssReset.js +21 -0
  83. package/lib/Fieldset/index.js +13 -0
  84. package/lib/FlexGrid/Col/Col.js +73 -41
  85. package/lib/FlexGrid/Col/index.js +13 -2
  86. package/lib/FlexGrid/FlexGrid.js +99 -49
  87. package/lib/FlexGrid/Row/Row.js +58 -30
  88. package/lib/FlexGrid/Row/index.js +13 -2
  89. package/lib/FlexGrid/helpers/index.js +9 -1
  90. package/lib/FlexGrid/index.js +13 -2
  91. package/lib/FlexGrid/providers/GutterContext.js +15 -3
  92. package/lib/HorizontalScroll/HorizontalScroll.js +200 -0
  93. package/lib/HorizontalScroll/HorizontalScrollButton.js +127 -0
  94. package/lib/HorizontalScroll/ScrollViewEnd.js +66 -0
  95. package/lib/HorizontalScroll/ScrollViewEnd.native.js +41 -0
  96. package/lib/HorizontalScroll/dictionary.js +18 -0
  97. package/lib/HorizontalScroll/index.js +35 -0
  98. package/lib/HorizontalScroll/itemPositions.js +128 -0
  99. package/lib/Icon/Icon.js +57 -48
  100. package/lib/Icon/IconText.js +54 -25
  101. package/lib/Icon/index.js +31 -4
  102. package/lib/IconButton/IconButton.js +140 -0
  103. package/lib/IconButton/index.js +13 -0
  104. package/lib/InputLabel/InputLabel.js +102 -40
  105. package/lib/InputLabel/LabelContent.js +41 -0
  106. package/lib/InputLabel/LabelContent.native.js +32 -6
  107. package/lib/InputLabel/index.js +13 -2
  108. package/lib/InputSupports/InputSupports.js +71 -52
  109. package/lib/InputSupports/index.js +13 -2
  110. package/lib/InputSupports/propTypes.js +19 -8
  111. package/lib/InputSupports/useInputSupports.js +41 -0
  112. package/lib/Link/ChevronLink.js +44 -20
  113. package/lib/Link/InlinePressable.js +56 -0
  114. package/lib/Link/InlinePressable.native.js +39 -15
  115. package/lib/Link/Link.js +36 -13
  116. package/lib/Link/LinkBase.js +98 -61
  117. package/lib/Link/TextButton.js +41 -17
  118. package/lib/Link/index.js +39 -5
  119. package/lib/List/List.js +55 -26
  120. package/lib/List/ListItem.js +79 -41
  121. package/lib/List/index.js +13 -2
  122. package/lib/Modal/Modal.js +231 -0
  123. package/lib/Modal/dictionary.js +16 -0
  124. package/lib/Modal/index.js +13 -0
  125. package/lib/Notification/Notification.js +216 -0
  126. package/lib/Notification/dictionary.js +15 -0
  127. package/lib/Notification/index.js +13 -0
  128. package/lib/Pagination/PageButton.js +61 -28
  129. package/lib/Pagination/Pagination.js +78 -43
  130. package/lib/Pagination/SideButton.js +73 -42
  131. package/lib/Pagination/dictionary.js +9 -2
  132. package/lib/Pagination/index.js +13 -2
  133. package/lib/Pagination/usePagination.js +12 -2
  134. package/lib/Progress/Progress.js +104 -0
  135. package/lib/Progress/ProgressBar.js +157 -0
  136. package/lib/Progress/ProgressBarBackground.js +61 -0
  137. package/lib/Progress/index.js +16 -0
  138. package/lib/Radio/Radio.js +116 -114
  139. package/lib/Radio/RadioButton.js +152 -0
  140. package/lib/Radio/RadioGroup.js +244 -0
  141. package/lib/Radio/RadioInput.js +76 -0
  142. package/lib/Radio/RadioInput.native.js +9 -1
  143. package/lib/Radio/index.js +21 -2
  144. package/lib/RadioCard/RadioCard.js +244 -0
  145. package/lib/RadioCard/RadioCardGroup.js +252 -0
  146. package/lib/RadioCard/index.js +21 -0
  147. package/lib/Search/Search.js +254 -0
  148. package/lib/Search/dictionary.js +19 -0
  149. package/lib/Search/index.js +13 -0
  150. package/lib/Select/Group.js +33 -0
  151. package/lib/Select/Group.native.js +16 -5
  152. package/lib/Select/Item.js +29 -0
  153. package/lib/Select/Item.native.js +14 -4
  154. package/lib/Select/Picker.js +84 -0
  155. package/lib/Select/Picker.native.js +73 -30
  156. package/lib/Select/Select.js +155 -85
  157. package/lib/Select/index.js +19 -6
  158. package/lib/SideNav/Item.js +63 -37
  159. package/lib/SideNav/ItemContent.js +41 -15
  160. package/lib/SideNav/ItemsGroup.js +55 -31
  161. package/lib/SideNav/SideNav.js +100 -73
  162. package/lib/SideNav/index.js +15 -1
  163. package/lib/Skeleton/Skeleton.js +64 -46
  164. package/lib/Skeleton/index.js +13 -2
  165. package/lib/Skeleton/skeleton.constant.js +12 -0
  166. package/lib/Skeleton/skeletonWebAnimation.js +27 -0
  167. package/lib/Skeleton/useSkeletonNativeAnimation.js +37 -0
  168. package/lib/Spacer/Spacer.js +49 -18
  169. package/lib/Spacer/index.js +13 -2
  170. package/lib/StackView/StackView.js +72 -31
  171. package/lib/StackView/StackWrap.js +43 -13
  172. package/lib/StackView/StackWrap.native.js +13 -2
  173. package/lib/StackView/StackWrapBox.js +77 -29
  174. package/lib/StackView/StackWrapGap.js +56 -26
  175. package/lib/StackView/common.js +23 -6
  176. package/lib/StackView/getStackedContent.js +47 -17
  177. package/lib/StackView/index.js +29 -5
  178. package/lib/StepTracker/Step.js +245 -0
  179. package/lib/StepTracker/StepTracker.js +202 -0
  180. package/lib/StepTracker/dictionary.js +17 -0
  181. package/lib/StepTracker/index.js +13 -0
  182. package/lib/Tabs/Tabs.js +124 -0
  183. package/lib/Tabs/TabsItem.js +238 -0
  184. package/lib/Tabs/index.js +13 -0
  185. package/lib/Tags/Tags.js +148 -99
  186. package/lib/Tags/index.js +13 -2
  187. package/lib/TextInput/TextArea.js +57 -28
  188. package/lib/TextInput/TextInput.js +50 -23
  189. package/lib/TextInput/TextInputBase.js +90 -63
  190. package/lib/TextInput/index.js +23 -3
  191. package/lib/TextInput/propTypes.js +18 -7
  192. package/lib/ThemeProvider/ThemeProvider.js +46 -18
  193. package/lib/ThemeProvider/index.js +61 -6
  194. package/lib/ThemeProvider/useSetTheme.js +19 -5
  195. package/lib/ThemeProvider/useTheme.js +13 -4
  196. package/lib/ThemeProvider/useThemeTokens.js +32 -16
  197. package/lib/ThemeProvider/utils/index.js +31 -2
  198. package/lib/ThemeProvider/utils/styles.js +50 -14
  199. package/lib/ThemeProvider/utils/theme-tokens.js +121 -12
  200. package/lib/ToggleSwitch/ToggleSwitch.js +85 -56
  201. package/lib/ToggleSwitch/index.js +13 -2
  202. package/lib/Tooltip/{Backdrop.web.js → Backdrop.js} +20 -8
  203. package/lib/Tooltip/Backdrop.native.js +39 -15
  204. package/lib/Tooltip/Tooltip.js +117 -74
  205. package/lib/Tooltip/dictionary.js +9 -2
  206. package/lib/Tooltip/getTooltipPosition.js +9 -1
  207. package/lib/Tooltip/index.js +13 -2
  208. package/lib/TooltipButton/TooltipButton.js +57 -38
  209. package/lib/TooltipButton/index.js +13 -2
  210. package/lib/Typography/Typography.js +87 -41
  211. package/lib/Typography/index.js +13 -2
  212. package/lib/ViewportProvider/ViewportProvider.js +34 -13
  213. package/lib/ViewportProvider/index.js +28 -3
  214. package/lib/ViewportProvider/useViewport.js +15 -3
  215. package/lib/ViewportProvider/useViewportListener.js +24 -10
  216. package/lib/index.js +539 -33
  217. package/lib/utils/a11y/index.js +31 -1
  218. package/lib/utils/a11y/semantics.js +173 -0
  219. package/lib/utils/a11y/textSize.js +23 -7
  220. package/lib/utils/animation/index.js +15 -2
  221. package/lib/utils/animation/useVerticalExpandAnimation.js +27 -10
  222. package/lib/utils/children.js +134 -0
  223. package/lib/utils/index.js +163 -10
  224. package/lib/utils/info/index.js +18 -6
  225. package/lib/utils/info/platform/index.js +19 -7
  226. package/lib/utils/info/platform/platform.android.js +8 -1
  227. package/lib/utils/info/platform/platform.ios.js +8 -1
  228. package/lib/utils/info/platform/platform.js +8 -0
  229. package/lib/utils/info/platform/platform.native.js +8 -1
  230. package/lib/utils/info/versions.js +15 -4
  231. package/lib/utils/input.js +53 -25
  232. package/lib/utils/pressability.js +38 -10
  233. package/lib/utils/propTypes.js +287 -141
  234. package/lib/utils/useCopy.js +40 -5
  235. package/lib/utils/useHash.js +52 -0
  236. package/lib/utils/useHash.native.js +15 -0
  237. package/lib/utils/useResponsiveProp.js +21 -9
  238. package/lib/utils/useSpacingScale.js +19 -9
  239. package/lib/utils/useUniqueId.js +12 -3
  240. package/package.json +14 -9
  241. package/release-context.json +4 -4
  242. package/src/A11yText/index.jsx +6 -4
  243. package/src/ActivityIndicator/{Spinner.web.jsx → Spinner.jsx} +5 -3
  244. package/src/ActivityIndicator/Spinner.native.jsx +5 -3
  245. package/src/Box/Box.jsx +132 -39
  246. package/src/Button/Button.jsx +10 -6
  247. package/src/Button/ButtonBase.jsx +99 -99
  248. package/src/Button/ButtonGroup.jsx +81 -69
  249. package/src/Button/ButtonLink.jsx +21 -15
  250. package/src/Button/propTypes.js +12 -2
  251. package/src/Card/Card.jsx +5 -31
  252. package/src/Card/CardBase.jsx +59 -0
  253. package/src/Card/PressableCardBase.jsx +119 -0
  254. package/src/Card/index.js +3 -0
  255. package/src/Checkbox/Checkbox.jsx +121 -112
  256. package/src/Checkbox/CheckboxGroup.jsx +206 -0
  257. package/src/Checkbox/{CheckboxInput.web.jsx → CheckboxInput.jsx} +0 -0
  258. package/src/Checkbox/index.js +2 -0
  259. package/src/Divider/Divider.jsx +7 -4
  260. package/src/ExpandCollapse/Accordion.jsx +3 -2
  261. package/src/ExpandCollapse/Control.jsx +40 -43
  262. package/src/ExpandCollapse/ExpandCollapse.jsx +26 -23
  263. package/src/ExpandCollapse/Panel.jsx +69 -63
  264. package/src/Feedback/Feedback.jsx +36 -33
  265. package/src/Fieldset/Fieldset.jsx +136 -0
  266. package/src/Fieldset/FieldsetContainer.jsx +31 -0
  267. package/src/Fieldset/FieldsetContainer.native.jsx +19 -0
  268. package/src/Fieldset/Legend.jsx +21 -0
  269. package/src/Fieldset/Legend.native.jsx +27 -0
  270. package/src/Fieldset/cssReset.js +14 -0
  271. package/src/Fieldset/index.js +3 -0
  272. package/src/FlexGrid/Col/Col.jsx +139 -132
  273. package/src/FlexGrid/FlexGrid.jsx +79 -51
  274. package/src/FlexGrid/Row/Row.jsx +55 -48
  275. package/src/HorizontalScroll/HorizontalScroll.jsx +168 -0
  276. package/src/HorizontalScroll/HorizontalScrollButton.jsx +105 -0
  277. package/src/HorizontalScroll/ScrollViewEnd.jsx +53 -0
  278. package/src/HorizontalScroll/ScrollViewEnd.native.jsx +24 -0
  279. package/src/HorizontalScroll/dictionary.js +11 -0
  280. package/src/HorizontalScroll/index.js +17 -0
  281. package/src/HorizontalScroll/itemPositions.js +101 -0
  282. package/src/Icon/Icon.jsx +43 -50
  283. package/src/Icon/IconText.jsx +23 -18
  284. package/src/Icon/index.js +2 -2
  285. package/src/IconButton/IconButton.jsx +114 -0
  286. package/src/IconButton/index.js +3 -0
  287. package/src/InputLabel/InputLabel.jsx +57 -35
  288. package/src/InputLabel/LabelContent.jsx +21 -0
  289. package/src/InputLabel/LabelContent.native.jsx +11 -2
  290. package/src/InputSupports/InputSupports.jsx +29 -45
  291. package/src/InputSupports/useInputSupports.js +30 -0
  292. package/src/Link/ChevronLink.jsx +26 -16
  293. package/src/Link/{InlinePressable.web.jsx → InlinePressable.jsx} +5 -3
  294. package/src/Link/InlinePressable.native.jsx +5 -3
  295. package/src/Link/Link.jsx +22 -16
  296. package/src/Link/LinkBase.jsx +76 -65
  297. package/src/Link/TextButton.jsx +30 -23
  298. package/src/List/List.jsx +5 -4
  299. package/src/List/ListItem.jsx +77 -82
  300. package/src/Modal/Modal.jsx +190 -0
  301. package/src/Modal/dictionary.js +9 -0
  302. package/src/Modal/index.js +3 -0
  303. package/src/Notification/Notification.jsx +164 -0
  304. package/src/Notification/dictionary.js +8 -0
  305. package/src/Notification/index.js +3 -0
  306. package/src/Pagination/PageButton.jsx +42 -35
  307. package/src/Pagination/Pagination.jsx +88 -92
  308. package/src/Pagination/SideButton.jsx +44 -41
  309. package/src/Progress/Progress.jsx +78 -0
  310. package/src/Progress/ProgressBar.jsx +123 -0
  311. package/src/Progress/ProgressBarBackground.jsx +36 -0
  312. package/src/Progress/index.js +6 -0
  313. package/src/Radio/Radio.jsx +82 -112
  314. package/src/Radio/RadioButton.jsx +142 -0
  315. package/src/Radio/RadioGroup.jsx +209 -0
  316. package/src/Radio/{RadioInput.web.jsx → RadioInput.jsx} +0 -0
  317. package/src/Radio/index.js +2 -0
  318. package/src/RadioCard/RadioCard.jsx +198 -0
  319. package/src/RadioCard/RadioCardGroup.jsx +218 -0
  320. package/src/RadioCard/index.js +5 -0
  321. package/src/Search/Search.jsx +225 -0
  322. package/src/Search/dictionary.js +12 -0
  323. package/src/Search/index.js +3 -0
  324. package/src/Select/{Group.web.jsx → Group.jsx} +0 -0
  325. package/src/Select/{Item.web.jsx → Item.jsx} +0 -0
  326. package/src/Select/Picker.jsx +74 -0
  327. package/src/Select/Picker.native.jsx +56 -49
  328. package/src/Select/Select.jsx +125 -92
  329. package/src/SideNav/Item.jsx +54 -47
  330. package/src/SideNav/ItemsGroup.jsx +50 -43
  331. package/src/SideNav/SideNav.jsx +68 -60
  332. package/src/Skeleton/Skeleton.jsx +25 -32
  333. package/src/Skeleton/skeleton.constant.js +3 -0
  334. package/src/Skeleton/skeletonWebAnimation.js +13 -0
  335. package/src/Skeleton/useSkeletonNativeAnimation.js +27 -0
  336. package/src/Spacer/Spacer.jsx +11 -4
  337. package/src/StackView/StackView.jsx +54 -23
  338. package/src/StackView/StackWrap.jsx +16 -7
  339. package/src/StackView/StackWrapBox.jsx +63 -28
  340. package/src/StackView/StackWrapGap.jsx +46 -24
  341. package/src/StackView/common.jsx +3 -2
  342. package/src/StackView/getStackedContent.jsx +8 -2
  343. package/src/StepTracker/Step.jsx +202 -0
  344. package/src/StepTracker/StepTracker.jsx +174 -0
  345. package/src/StepTracker/dictionary.js +10 -0
  346. package/src/StepTracker/index.js +3 -0
  347. package/src/Tabs/Tabs.jsx +97 -0
  348. package/src/Tabs/TabsItem.jsx +212 -0
  349. package/src/Tabs/index.js +3 -0
  350. package/src/Tags/Tags.jsx +115 -102
  351. package/src/TextInput/TextArea.jsx +5 -4
  352. package/src/TextInput/TextInput.jsx +5 -4
  353. package/src/TextInput/TextInputBase.jsx +95 -98
  354. package/src/ThemeProvider/ThemeProvider.jsx +11 -7
  355. package/src/ThemeProvider/useSetTheme.js +4 -0
  356. package/src/ThemeProvider/useThemeTokens.js +2 -2
  357. package/src/ThemeProvider/utils/styles.js +18 -5
  358. package/src/ThemeProvider/utils/theme-tokens.js +74 -5
  359. package/src/ToggleSwitch/ToggleSwitch.jsx +50 -52
  360. package/src/Tooltip/{Backdrop.web.jsx → Backdrop.jsx} +0 -0
  361. package/src/Tooltip/Tooltip.jsx +135 -131
  362. package/src/TooltipButton/TooltipButton.jsx +23 -27
  363. package/src/Typography/Typography.jsx +71 -47
  364. package/src/index.js +23 -2
  365. package/src/utils/a11y/index.js +1 -0
  366. package/src/utils/a11y/semantics.js +162 -0
  367. package/src/utils/children.jsx +119 -0
  368. package/src/utils/index.js +3 -0
  369. package/src/utils/info/platform/platform.js +1 -0
  370. package/src/utils/info/versions.js +2 -2
  371. package/src/utils/input.js +36 -25
  372. package/src/utils/pressability.js +4 -0
  373. package/src/utils/propTypes.js +199 -72
  374. package/src/utils/useCopy.js +30 -4
  375. package/src/utils/useHash.js +39 -0
  376. package/src/utils/useHash.native.js +6 -0
  377. package/stories/A11yText/A11yText.stories.jsx +6 -10
  378. package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +1 -1
  379. package/stories/Box/Box.stories.jsx +1 -1
  380. package/stories/Button/Button.stories.jsx +2 -2
  381. package/stories/Button/ButtonGroup.stories.jsx +1 -1
  382. package/stories/Button/ButtonLink.stories.jsx +1 -1
  383. package/stories/Card/Card.stories.jsx +1 -1
  384. package/stories/Checkbox/Checkbox.stories.jsx +24 -1
  385. package/stories/Divider/Divider.stories.jsx +1 -1
  386. package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +2 -2
  387. package/stories/Feedback/Feedback.stories.jsx +1 -1
  388. package/stories/FlexGrid/01 FlexGrid.stories.jsx +1 -1
  389. package/stories/FlexGrid/02 Row.stories.jsx +1 -1
  390. package/stories/FlexGrid/03 Col.stories.jsx +1 -1
  391. package/stories/Icon/Icon.stories.jsx +27 -7
  392. package/stories/IconButton/IconButton.stories.jsx +50 -0
  393. package/stories/InputLabel/InputLabel.stories.jsx +1 -1
  394. package/stories/Link/ChevronLink.stories.jsx +1 -1
  395. package/stories/Link/Link.stories.jsx +17 -21
  396. package/stories/Link/TextButton.stories.jsx +1 -1
  397. package/stories/List/List.stories.jsx +1 -1
  398. package/stories/Modal/Modal.stories.jsx +29 -0
  399. package/stories/Notification/Notification.stories.jsx +82 -0
  400. package/stories/Pagination/Pagination.stories.jsx +1 -1
  401. package/stories/Progress/Progress.stories.jsx +93 -0
  402. package/stories/Radio/Radio.stories.jsx +23 -36
  403. package/stories/RadioCard/RadioCard.stories.jsx +98 -0
  404. package/stories/Search/Search.stories.jsx +16 -0
  405. package/stories/Select/Select.stories.jsx +1 -1
  406. package/stories/SideNav/SideNav.stories.jsx +1 -1
  407. package/stories/SideNav/SideNavItem.stories.jsx +1 -1
  408. package/stories/SideNav/SideNavItemsGroup.stories.jsx +1 -1
  409. package/stories/Skeleton/Skeleton.stories.jsx +2 -2
  410. package/stories/Spacer/Spacer.stories.jsx +1 -1
  411. package/stories/StackView/StackView.stories.jsx +1 -1
  412. package/stories/StackView/StackWrap.stories.jsx +1 -1
  413. package/stories/StepTracker/StepTracker.stories.jsx +71 -0
  414. package/stories/Tabs/Tabs.stories.jsx +97 -0
  415. package/stories/Tags/Tags.stories.jsx +1 -1
  416. package/stories/TextInput/TextArea.stories.jsx +1 -1
  417. package/stories/TextInput/TextInput.stories.jsx +1 -1
  418. package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +1 -1
  419. package/stories/Tooltip/Tooltip.stories.jsx +1 -1
  420. package/stories/TooltipButton/TooltipButton.stories.jsx +1 -1
  421. package/stories/Typography/Typography.stories.jsx +1 -1
  422. package/stories/{platform-supports.web.jsx → platform-supports.jsx} +1 -1
  423. package/stories/supports.jsx +37 -3
  424. package/__fixtures__/accessible.icon.svg +0 -6
  425. package/babel.config.json +0 -8
  426. package/docs/Contributing.stories.mdx +0 -9
  427. package/docs/Fonts.stories.mdx +0 -104
  428. package/docs/Icons.stories.mdx +0 -144
  429. package/docs/Introduction.stories.mdx +0 -9
  430. package/lib/ActivityIndicator/Spinner.web.js +0 -55
  431. package/lib/Checkbox/CheckboxInput.web.js +0 -57
  432. package/lib/InputLabel/LabelContent.web.js +0 -17
  433. package/lib/Link/InlinePressable.web.js +0 -32
  434. package/lib/Radio/RadioInput.web.js +0 -59
  435. package/lib/Select/Group.web.js +0 -18
  436. package/lib/Select/Item.web.js +0 -15
  437. package/lib/Select/Picker.web.js +0 -63
  438. package/lib/config/svgr-icons-web.js +0 -9
  439. package/lib/config/svgr-icons.js +0 -52
  440. package/lib/utils/info/platform/platform.web.js +0 -1
  441. package/src/InputLabel/LabelContent.web.jsx +0 -13
  442. package/src/Select/Picker.web.jsx +0 -67
  443. package/src/config/svgr-icons-web.js +0 -11
  444. package/src/config/svgr-icons.js +0 -46
  445. package/src/utils/info/platform/platform.web.js +0 -1
@@ -1,8 +1,8 @@
1
- import React, { useState } from 'react'
1
+ import React, { forwardRef, useState } from 'react'
2
2
 
3
3
  import { View, Platform, StyleSheet } from 'react-native'
4
4
  import PropTypes from 'prop-types'
5
- import { applyTextStyles, useThemeTokens } from '../ThemeProvider'
5
+ import { applyTextStyles, useThemeTokens, applyOuterBorder } from '../ThemeProvider'
6
6
  import { componentPropType, getTokensPropType, useInputValue, variantProp } from '../utils'
7
7
  import Picker from './Picker'
8
8
  import InputSupports from '../InputSupports'
@@ -78,27 +78,17 @@ const selectInputStyles = (
78
78
 
79
79
  const selectOuterBorderStyles = ({
80
80
  outerBackgroundColor,
81
- outerBorderWidth = 0,
81
+ outerBorderWidth,
82
82
  outerBorderColor,
83
- outerBorderRadius = 0
84
- }) => {
85
- // Use negative margins so that the outer border doesn't expand the input's bounding box
86
- const margin = -1 * outerBorderWidth
87
-
88
- // Account for the border width since we style it as an outline
89
- const borderRadius = outerBorderRadius + outerBorderWidth
90
-
91
- return {
92
- background: outerBackgroundColor,
93
- borderWidth: outerBorderWidth,
94
- borderColor: outerBorderColor,
95
- borderRadius,
96
- marginTop: margin,
97
- marginBottom: margin,
98
- marginLeft: margin,
99
- marginRight: margin
100
- }
101
- }
83
+ borderRadius
84
+ }) => ({
85
+ background: outerBackgroundColor,
86
+ ...applyOuterBorder({
87
+ outerBorderColor,
88
+ outerBorderWidth,
89
+ borderRadius
90
+ })
91
+ })
102
92
 
103
93
  const selectIconTokens = ({ iconSize, iconColor }) => ({
104
94
  size: iconSize,
@@ -157,100 +147,143 @@ const selectValidationIconContainerStyles = ({
157
147
  * NOTE: this does not work on native platforms - the grouped items will be shown at the same level as the non-grouped items.
158
148
  *
159
149
  */
160
- const Select = ({
161
- value,
162
- initialValue,
163
- onChange,
164
- children,
165
- inactive,
166
- readOnly,
167
- placeholder,
168
- validation,
169
- tokens,
170
- variant,
171
- testID,
172
- ...rest
173
- }) => {
174
- const { currentValue, setValue } = useInputValue({
175
- value,
176
- initialValue,
177
- onChange,
178
- readOnly
179
- })
150
+ const Select = forwardRef(
151
+ (
152
+ {
153
+ value,
154
+ initialValue,
155
+ onChange,
156
+ children,
157
+ inactive,
158
+ readOnly,
159
+ placeholder,
160
+ validation,
161
+ tokens,
162
+ variant,
163
+ testID,
164
+ ...rest
165
+ },
166
+ ref
167
+ ) => {
168
+ const { currentValue, setValue } = useInputValue({
169
+ value,
170
+ initialValue,
171
+ onChange,
172
+ readOnly
173
+ })
180
174
 
181
- const [isFocused, setIsFocused] = useState(false)
182
- const handleFocus = () => setIsFocused(true)
183
- const handleBlur = () => setIsFocused(false)
175
+ const [isFocused, setIsFocused] = useState(false)
176
+ const handleFocus = () => setIsFocused(true)
177
+ const handleBlur = () => setIsFocused(false)
184
178
 
185
- const [isHovered, setIsHovered] = useState(false)
186
- const handleMouseOver = () => setIsHovered(true)
187
- const handleMouseOut = () => setIsHovered(false)
179
+ const [isHovered, setIsHovered] = useState(false)
180
+ const handleMouseOver = () => setIsHovered(true)
181
+ const handleMouseOut = () => setIsHovered(false)
188
182
 
189
- const { props: supportsProps } = inputSupportsProps.select(rest)
183
+ const { props: supportsProps } = inputSupportsProps.select(rest)
190
184
 
191
- const themeTokens = useThemeTokens('Select', tokens, variant, {
192
- focus: isFocused,
193
- hover: isHovered,
194
- inactive,
195
- validation
196
- })
185
+ const themeTokens = useThemeTokens('Select', tokens, variant, {
186
+ focus: isFocused,
187
+ hover: isHovered,
188
+ inactive,
189
+ validation
190
+ })
197
191
 
198
- const { icon: IconComponent, validationIcon: ValidationIconComponent } = themeTokens
192
+ const { icon: IconComponent, validationIcon: ValidationIconComponent } = themeTokens
199
193
 
200
- return (
201
- <InputSupports {...supportsProps}>
202
- {({ a11yProps, inputId }) => (
203
- <View style={selectOuterBorderStyles(themeTokens)}>
204
- <Picker
205
- style={selectInputStyles(themeTokens, inactive)}
206
- onFocus={handleFocus}
207
- onBlur={handleBlur}
208
- onMouseOver={handleMouseOver}
209
- onMouseOut={handleMouseOut}
210
- onChange={setValue}
211
- value={currentValue}
212
- inactive={inactive}
213
- placeholder={placeholder !== undefined ? { label: placeholder, value: '' } : undefined}
214
- {...a11yProps}
215
- nativeID={inputId}
216
- testID={testID}
217
- >
218
- {children}
219
- </Picker>
220
- {ValidationIconComponent && (
221
- <View
222
- pointerEvents="none"
223
- style={[staticStyles.iconContainer, selectValidationIconContainerStyles(themeTokens)]}
194
+ return (
195
+ <InputSupports {...supportsProps}>
196
+ {({ a11yProps, inputId }) => (
197
+ <View style={selectOuterBorderStyles(themeTokens)}>
198
+ <Picker
199
+ ref={ref}
200
+ style={selectInputStyles(themeTokens, inactive)}
201
+ onFocus={handleFocus}
202
+ onBlur={handleBlur}
203
+ onMouseOver={handleMouseOver}
204
+ onMouseOut={handleMouseOut}
205
+ onChange={setValue}
206
+ value={currentValue}
207
+ inactive={inactive}
208
+ placeholder={
209
+ placeholder !== undefined ? { label: placeholder, value: '' } : undefined
210
+ }
211
+ {...a11yProps}
212
+ nativeID={inputId}
213
+ testID={testID}
224
214
  >
225
- <ValidationIconComponent tokens={selectValidationIconTokens(themeTokens)} />
226
- </View>
227
- )}
228
- {IconComponent &&
229
- Platform.OS !== 'android' && ( // we can't hide the default caret of a native picker on android
215
+ {children}
216
+ </Picker>
217
+ {ValidationIconComponent && (
230
218
  <View
231
219
  pointerEvents="none"
232
- style={[staticStyles.iconContainer, selectIconContainerStyles(themeTokens)]}
220
+ style={[
221
+ staticStyles.iconContainer,
222
+ selectValidationIconContainerStyles(themeTokens)
223
+ ]}
233
224
  >
234
- <IconComponent tokens={selectIconTokens(themeTokens)} />
225
+ <ValidationIconComponent tokens={selectValidationIconTokens(themeTokens)} />
235
226
  </View>
236
227
  )}
237
- </View>
238
- )}
239
- </InputSupports>
240
- )
241
- }
228
+ {IconComponent &&
229
+ Platform.OS !== 'android' && ( // we can't hide the default caret of a native picker on android
230
+ <View
231
+ pointerEvents="none"
232
+ style={[staticStyles.iconContainer, selectIconContainerStyles(themeTokens)]}
233
+ >
234
+ <IconComponent {...selectIconTokens(themeTokens)} />
235
+ </View>
236
+ )}
237
+ </View>
238
+ )}
239
+ </InputSupports>
240
+ )
241
+ }
242
+ )
243
+ Select.displayName = 'Select'
242
244
 
243
245
  Select.propTypes = {
244
246
  ...inputSupportsProps.types,
247
+ /**
248
+ * Initial value for the uncontrolled version.
249
+ */
245
250
  initialValue: PropTypes.string,
251
+ /**
252
+ * Current value to be set as selected.
253
+ */
246
254
  value: PropTypes.string,
255
+ /**
256
+ * Callback to be called when the value changes.
257
+ */
247
258
  onChange: PropTypes.func,
259
+ /**
260
+ * An array of items or item groups to be used as options.
261
+ */
248
262
  children: componentPropType(['Item', 'Group']),
263
+ /**
264
+ * Whether the select is disabled.
265
+ */
249
266
  inactive: PropTypes.bool,
267
+ /**
268
+ * Whether the select is read-only.
269
+ */
250
270
  readOnly: PropTypes.bool,
271
+ /**
272
+ * A placeholder to provide instructions (such as "Please select...")
273
+ * as an unselectable option
274
+ */
251
275
  placeholder: PropTypes.string,
276
+ /**
277
+ * Select tokens.
278
+ */
252
279
  tokens: getTokensPropType('Select'),
280
+ /**
281
+ * Select variant.
282
+ */
253
283
  variant: variantProp.propType,
284
+ /**
285
+ * Dedicated ID for testing.
286
+ */
254
287
  testID: PropTypes.string
255
288
  }
256
289
 
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import { Pressable } from 'react-native'
3
3
  import PropTypes from 'prop-types'
4
4
 
@@ -37,54 +37,61 @@ function selectItemStyles({
37
37
 
38
38
  This component can only be accessed as a name-spaced component: `SideNav.Item`.
39
39
  */
40
- const Item = ({
41
- children,
42
- itemId,
43
- groupId,
44
- onPress,
45
- isActive = false,
46
- isExpanded = false,
47
- tokens,
48
- variant,
49
- href,
50
- accessibilityRole = 'link',
51
- testID,
52
- ...props
53
- }) => {
54
- const handlePress = () => onPress(itemId, groupId)
40
+ const Item = forwardRef(
41
+ (
42
+ {
43
+ children,
44
+ itemId,
45
+ groupId,
46
+ onPress,
47
+ isActive = false,
48
+ isExpanded = false,
49
+ tokens,
50
+ variant,
51
+ href,
52
+ accessibilityRole = 'link',
53
+ testID,
54
+ ...props
55
+ },
56
+ ref
57
+ ) => {
58
+ const handlePress = () => onPress(itemId, groupId)
55
59
 
56
- const { hrefAttrs, rest } = hrefAttrsProp.bundle(props)
57
- const linkPropSet = linkProps.select({
58
- accessibilityRole,
59
- href,
60
- onPress: handlePress,
61
- ...hrefAttrsProp.spread(hrefAttrs),
62
- ...rest
63
- })
60
+ const { hrefAttrs, rest } = hrefAttrsProp.bundle(props)
61
+ const linkPropSet = linkProps.select({
62
+ accessibilityRole,
63
+ href,
64
+ onPress: handlePress,
65
+ hrefAttrs,
66
+ ...rest
67
+ })
64
68
 
65
- const getTokens = useThemeTokensCallback('SideNavItem', tokens, variant)
66
- const getAppearanceState = ({ hovered }) => ({
67
- hover: hovered,
68
- active: isActive,
69
- expanded: isExpanded
70
- })
71
- const getPressableStyle = (pressableState) =>
72
- selectItemStyles(getTokens(getAppearanceState(pressableState)))
69
+ const getTokens = useThemeTokensCallback('SideNavItem', tokens, variant)
70
+ const getAppearanceState = ({ hovered }) => ({
71
+ hover: hovered,
72
+ active: isActive,
73
+ expanded: isExpanded
74
+ })
75
+ const getPressableStyle = (pressableState) =>
76
+ selectItemStyles(getTokens(getAppearanceState(pressableState)))
73
77
 
74
- return (
75
- <Pressable
76
- style={getPressableStyle}
77
- {...linkPropSet}
78
- accessibilityState={{ selected: isActive }}
79
- testID={testID}
80
- >
81
- {(pressableState) => {
82
- const themeTokens = getTokens(getAppearanceState(pressableState))
83
- return <ItemContent tokens={themeTokens}>{children}</ItemContent>
84
- }}
85
- </Pressable>
86
- )
87
- }
78
+ return (
79
+ <Pressable
80
+ ref={ref}
81
+ style={getPressableStyle}
82
+ {...linkPropSet}
83
+ accessibilityState={{ selected: isActive }}
84
+ testID={testID}
85
+ >
86
+ {(pressableState) => {
87
+ const themeTokens = getTokens(getAppearanceState(pressableState))
88
+ return <ItemContent tokens={themeTokens}>{children}</ItemContent>
89
+ }}
90
+ </Pressable>
91
+ )
92
+ }
93
+ )
94
+ Item.displayName = 'Item'
88
95
 
89
96
  Item.propTypes = {
90
97
  /**
@@ -105,7 +112,7 @@ Item.propTypes = {
105
112
  href: PropTypes.string,
106
113
  /**
107
114
  * On Web if href is passed, React Native Web maps this object's props to
108
- * `rel`, `target` and (>= RNW 0.15.0) `download` attrs.
115
+ * `rel`, `target` and `download` attrs.
109
116
  */
110
117
  hrefAttrs: PropTypes.shape(hrefAttrsProp.types),
111
118
  /**
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
 
4
4
  import ItemContent from './ItemContent'
@@ -16,52 +16,59 @@ import { useThemeTokensCallback } from '../ThemeProvider'
16
16
  ## Usage Criteria
17
17
  - Use `SideNav.ItemsGroup` with large pages that have multiple sections
18
18
  */
19
- const ItemsGroup = ({
20
- children,
21
- label,
22
- openGroups,
23
- groupId,
24
- isActive = false,
25
- variant,
26
- tokens,
27
- itemTokens,
28
- onToggle
29
- }) => {
30
- // A SideNav control uses the same style and theme as SideNavItem, with a 'parent' variant,
31
- // plus control-specific tokens from the SideNavItemsGroup theme (e.g. open/close icon, etc).
32
- const getAppearance = (appearance) => ({ ...variant, ...appearance, active: isActive })
33
- const getItemAppearance = (appearance) => ({ ...getAppearance(appearance), type: 'parent' })
19
+ const ItemsGroup = forwardRef(
20
+ (
21
+ {
22
+ children,
23
+ label,
24
+ openGroups,
25
+ groupId,
26
+ isActive = false,
27
+ variant,
28
+ tokens,
29
+ itemTokens,
30
+ onToggle
31
+ },
32
+ ref
33
+ ) => {
34
+ // A SideNav control uses the same style and theme as SideNavItem, with a 'parent' variant,
35
+ // plus control-specific tokens from the SideNavItemsGroup theme (e.g. open/close icon, etc).
36
+ const getAppearance = (appearance) => ({ ...variant, ...appearance, active: isActive })
37
+ const getItemAppearance = (appearance) => ({ ...getAppearance(appearance), type: 'parent' })
34
38
 
35
- const getGroupTokens = useThemeTokensCallback('SideNavItemsGroup', tokens, variant)
36
- const getPanelTokens = (appearance) =>
37
- selectTokens('ExpandCollapsePanel', getGroupTokens(getAppearance(appearance)))
39
+ const getGroupTokens = useThemeTokensCallback('SideNavItemsGroup', tokens, variant)
40
+ const getPanelTokens = (appearance) =>
41
+ selectTokens('ExpandCollapsePanel', getGroupTokens(getAppearance(appearance)))
38
42
 
39
- const getItemTokens = useThemeTokensCallback('SideNavItem', itemTokens, variant)
40
- const getControlTokens = (appearance) =>
41
- selectTokens('ExpandCollapseControl', {
42
- ...getItemTokens(getItemAppearance(appearance)), // main style from SideNavItem
43
- ...getGroupTokens(getAppearance(appearance)) // control-specific tokens like icon etc
44
- })
43
+ const getItemTokens = useThemeTokensCallback('SideNavItem', itemTokens, variant)
44
+ const getControlTokens = (appearance) =>
45
+ selectTokens('ExpandCollapseControl', {
46
+ ...getItemTokens(getItemAppearance(appearance)), // main style from SideNavItem
47
+ ...getGroupTokens(getAppearance(appearance)) // control-specific tokens like icon etc
48
+ })
45
49
 
46
- const controlContent = (controlState) => {
47
- const currentItemTokens = getItemTokens(getItemAppearance(controlState))
48
- return <ItemContent tokens={currentItemTokens}>{label}</ItemContent>
49
- }
50
+ const controlContent = (controlState) => {
51
+ const currentItemTokens = getItemTokens(getItemAppearance(controlState))
52
+ return <ItemContent tokens={currentItemTokens}>{label}</ItemContent>
53
+ }
50
54
 
51
- return (
52
- <ExpandCollapse.Panel
53
- openIds={openGroups}
54
- panelId={groupId}
55
- onToggle={onToggle}
56
- tokens={getPanelTokens}
57
- controlTokens={getControlTokens}
58
- control={controlContent}
59
- accessibilityState={{ active: isActive }} // ExpandCollapse.Panel handles expanded state
60
- >
61
- {children}
62
- </ExpandCollapse.Panel>
63
- )
64
- }
55
+ return (
56
+ <ExpandCollapse.Panel
57
+ ref={ref}
58
+ openIds={openGroups}
59
+ panelId={groupId}
60
+ onToggle={onToggle}
61
+ tokens={getPanelTokens}
62
+ controlTokens={getControlTokens}
63
+ control={controlContent}
64
+ accessibilityState={{ active: isActive }} // ExpandCollapse.Panel handles expanded state
65
+ >
66
+ {children}
67
+ </ExpandCollapse.Panel>
68
+ )
69
+ }
70
+ )
71
+ ItemsGroup.displayName = 'ItemsGroup'
65
72
 
66
73
  ItemsGroup.propTypes = {
67
74
  /**
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react'
1
+ import React, { forwardRef, useState } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
 
4
4
  import ExpandCollapse from '../ExpandCollapse'
@@ -20,73 +20,81 @@ function selectBorderStyles(tokens) {
20
20
  - Use in conjunction with a large amount of educational / informational content
21
21
  - Allow the user to navigate between options frequently and efficiently
22
22
  */
23
- const SideNav = ({ children, variant = {}, tokens, accordion = true, itemTokens, groupTokens }) => {
24
- const themeTokens = useThemeTokens('SideNav', tokens, variant)
25
- const [active, setActive] = useState({ groupId: undefined, itemId: undefined })
23
+ const SideNav = forwardRef(
24
+ ({ children, variant = {}, tokens, accordion = true, itemTokens, groupTokens }, ref) => {
25
+ const themeTokens = useThemeTokens('SideNav', tokens, variant)
26
+ const [active, setActive] = useState({ groupId: undefined, itemId: undefined })
26
27
 
27
- const onItemPress = (itemId, groupId) => {
28
- setActive({ itemId, groupId })
29
- }
30
-
31
- const isItemActive = (itemId, groupId) => {
32
- return active.groupId === groupId && active.itemId === itemId
33
- }
34
-
35
- return (
36
- <ExpandCollapse maxOpen={accordion ? 1 : null} style={selectBorderStyles(themeTokens)}>
37
- {({ openIds, onToggle }) => {
38
- const renderItem = (item, index, groupId) => {
39
- const { itemId = `item-${index}`, onPress } = item.props
40
- const handlePress = (...args) => {
41
- onItemPress(...args)
42
- if (onPress) onPress(...args)
43
- }
44
- return (
45
- <Item
46
- {...item.props}
47
- key={itemId}
48
- itemId={itemId}
49
- groupId={groupId}
50
- variant={groupId ? { ...variant, type: 'child' } : variant}
51
- tokens={itemTokens}
52
- isActive={isItemActive(itemId, groupId)}
53
- onPress={handlePress}
54
- />
55
- )
56
- }
28
+ const onItemPress = (itemId, groupId) => {
29
+ setActive({ itemId, groupId })
30
+ }
57
31
 
58
- return React.Children.map(children, (child, index) => {
59
- // iterate over children and identify them internally to later reference expanded groups and active items
60
- if (child.type === Item) return renderItem(child, index)
32
+ const isItemActive = (itemId, groupId) => {
33
+ return active.groupId === groupId && active.itemId === itemId
34
+ }
61
35
 
62
- if (child.type === ItemsGroup) {
63
- const { groupId = `group-${index}` } = child.props
64
- const isGroupActive = active.itemId !== undefined && active.groupId === groupId
36
+ return (
37
+ <ExpandCollapse
38
+ ref={ref}
39
+ maxOpen={accordion ? 1 : null}
40
+ style={selectBorderStyles(themeTokens)}
41
+ >
42
+ {({ openIds, onToggle }) => {
43
+ const renderItem = (item, index, groupId) => {
44
+ const { itemId = `item-${index}`, onPress } = item.props
45
+ const handlePress = (...args) => {
46
+ onItemPress(...args)
47
+ if (onPress) onPress(...args)
48
+ }
65
49
  return (
66
- <ItemsGroup
67
- {...child.props}
68
- key={groupId}
50
+ <Item
51
+ {...item.props}
52
+ key={itemId}
53
+ itemId={itemId}
69
54
  groupId={groupId}
70
- variant={variant}
71
- tokens={groupTokens}
72
- itemTokens={itemTokens}
73
- openGroups={openIds}
74
- isActive={isGroupActive}
75
- onToggle={() => onToggle(groupId)}
76
- >
77
- {React.Children.map(child.props.children, (item, itemIndex) =>
78
- renderItem(item, itemIndex, groupId)
79
- )}
80
- </ItemsGroup>
55
+ variant={groupId ? { ...variant, type: 'child' } : variant}
56
+ tokens={itemTokens}
57
+ isActive={isItemActive(itemId, groupId)}
58
+ onPress={handlePress}
59
+ />
81
60
  )
82
61
  }
83
62
 
84
- return null
85
- })
86
- }}
87
- </ExpandCollapse>
88
- )
89
- }
63
+ return React.Children.map(children, (child, index) => {
64
+ // iterate over children and identify them internally to later reference expanded groups and active items
65
+ if (child.type === Item) return renderItem(child, index)
66
+
67
+ if (child.type === ItemsGroup) {
68
+ const { groupId = `group-${index}` } = child.props
69
+ const isGroupActive = active.itemId !== undefined && active.groupId === groupId
70
+ const handleToggle = (event) => onToggle(groupId, event)
71
+ return (
72
+ <ItemsGroup
73
+ {...child.props}
74
+ key={groupId}
75
+ groupId={groupId}
76
+ variant={variant}
77
+ tokens={groupTokens}
78
+ itemTokens={itemTokens}
79
+ openGroups={openIds}
80
+ isActive={isGroupActive}
81
+ onToggle={handleToggle}
82
+ >
83
+ {React.Children.map(child.props.children, (item, itemIndex) =>
84
+ renderItem(item, itemIndex, groupId)
85
+ )}
86
+ </ItemsGroup>
87
+ )
88
+ }
89
+
90
+ return null
91
+ })
92
+ }}
93
+ </ExpandCollapse>
94
+ )
95
+ }
96
+ )
97
+ SideNav.displayName = 'SideNav'
90
98
 
91
99
  SideNav.propTypes = {
92
100
  /**