@telus-uds/components-base 0.0.2-prerelease.5 → 0.0.2-prerelease.9

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 (429) hide show
  1. package/.ultra.cache.json +1 -0
  2. package/CHANGELOG.md +65 -0
  3. package/__fixtures__/Accessible.js +33 -0
  4. package/__fixtures__/Accessible.native.js +32 -0
  5. package/__fixtures__/testTheme.js +871 -52
  6. package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +1 -1
  7. package/__tests__/Button/ButtonBase.test.jsx +3 -32
  8. package/__tests__/Button/ButtonGroup.test.jsx +2 -2
  9. package/__tests__/Checkbox/Checkbox.test.jsx +94 -0
  10. package/__tests__/Checkbox/CheckboxGroup.test.jsx +247 -0
  11. package/__tests__/Icon/Icon.test.jsx +3 -3
  12. package/__tests__/IconButton/IconButton.test.jsx +52 -0
  13. package/__tests__/InputSupports/InputSupports.test.jsx +50 -0
  14. package/__tests__/List/List.test.jsx +60 -0
  15. package/__tests__/Modal/Modal.test.jsx +47 -0
  16. package/__tests__/Notification/Notification.test.jsx +20 -0
  17. package/__tests__/Pagination/Pagination.test.jsx +2 -2
  18. package/__tests__/Progress/Progress.test.jsx +79 -0
  19. package/__tests__/Radio/Radio.test.jsx +87 -0
  20. package/__tests__/Radio/RadioGroup.test.jsx +221 -0
  21. package/__tests__/RadioCard/RadioCard.test.jsx +87 -0
  22. package/__tests__/RadioCard/RadioCardGroup.test.jsx +247 -0
  23. package/__tests__/Search/Search.test.jsx +72 -0
  24. package/__tests__/Select/Select.test.jsx +93 -0
  25. package/__tests__/Skeleton/Skeleton.test.jsx +61 -0
  26. package/__tests__/StackView/StackView.test.jsx +0 -26
  27. package/__tests__/StepTracker/StepTracker.test.jsx +94 -0
  28. package/__tests__/Tabs/Tabs.test.jsx +200 -0
  29. package/__tests__/Tags/Tags.test.jsx +328 -0
  30. package/__tests__/TextInput/TextArea.test.jsx +34 -0
  31. package/__tests__/TextInput/{TextInput.test.jsx → TextInputBase.test.jsx} +20 -46
  32. package/__tests__/Tooltip/Tooltip.test.jsx +65 -0
  33. package/__tests__/Tooltip/getTooltipPosition.test.js +79 -0
  34. package/__tests__/utils/input.test.js +58 -0
  35. package/__tests__/utils/useCopy.test.js +42 -0
  36. package/__tests__/utils/useResponsiveProp.test.jsx +202 -0
  37. package/__tests__/utils/{spacing.test.jsx → useSpacingScale.test.jsx} +1 -1
  38. package/babel.config.js +20 -0
  39. package/jest.config.js +13 -4
  40. package/lib/A11yInfoProvider/index.js +54 -26
  41. package/lib/A11yText/index.js +37 -14
  42. package/lib/ActivityIndicator/Spinner.js +78 -0
  43. package/lib/ActivityIndicator/Spinner.native.js +121 -87
  44. package/lib/ActivityIndicator/index.js +28 -12
  45. package/lib/ActivityIndicator/shared.js +27 -12
  46. package/lib/BaseProvider/index.js +34 -11
  47. package/lib/Box/Box.js +54 -31
  48. package/lib/Box/index.js +13 -2
  49. package/lib/Button/Button.js +38 -10
  50. package/lib/Button/ButtonBase.js +115 -94
  51. package/lib/Button/ButtonGroup.js +94 -86
  52. package/lib/Button/ButtonLink.js +41 -13
  53. package/lib/Button/index.js +31 -4
  54. package/lib/Button/propTypes.js +32 -9
  55. package/lib/Card/Card.js +36 -41
  56. package/lib/Card/CardBase.js +78 -0
  57. package/lib/Card/PressableCardBase.js +137 -0
  58. package/lib/Card/index.js +40 -2
  59. package/lib/Checkbox/Checkbox.js +344 -0
  60. package/lib/Checkbox/CheckboxGroup.js +231 -0
  61. package/lib/Checkbox/CheckboxInput.js +74 -0
  62. package/lib/Checkbox/CheckboxInput.native.js +14 -0
  63. package/lib/Checkbox/index.js +21 -0
  64. package/lib/Divider/Divider.js +50 -24
  65. package/lib/Divider/index.js +13 -2
  66. package/lib/ExpandCollapse/Accordion.js +20 -7
  67. package/lib/ExpandCollapse/Control.js +50 -27
  68. package/lib/ExpandCollapse/ExpandCollapse.js +41 -24
  69. package/lib/ExpandCollapse/Panel.js +75 -37
  70. package/lib/ExpandCollapse/index.js +25 -7
  71. package/lib/Feedback/Feedback.js +85 -34
  72. package/lib/Feedback/index.js +13 -2
  73. package/lib/Fieldset/Fieldset.js +160 -0
  74. package/lib/Fieldset/FieldsetContainer.js +41 -0
  75. package/lib/Fieldset/FieldsetContainer.native.js +33 -0
  76. package/lib/Fieldset/Legend.js +33 -0
  77. package/lib/Fieldset/Legend.native.js +43 -0
  78. package/lib/Fieldset/cssReset.js +21 -0
  79. package/lib/Fieldset/index.js +13 -0
  80. package/lib/FlexGrid/Col/Col.js +67 -38
  81. package/lib/FlexGrid/Col/index.js +13 -2
  82. package/lib/FlexGrid/FlexGrid.js +70 -45
  83. package/lib/FlexGrid/Row/Row.js +48 -27
  84. package/lib/FlexGrid/Row/index.js +13 -2
  85. package/lib/FlexGrid/helpers/index.js +9 -1
  86. package/lib/FlexGrid/index.js +13 -2
  87. package/lib/FlexGrid/providers/GutterContext.js +15 -3
  88. package/lib/Icon/Icon.js +52 -47
  89. package/lib/Icon/IconText.js +100 -0
  90. package/lib/Icon/index.js +31 -3
  91. package/lib/IconButton/IconButton.js +135 -0
  92. package/lib/IconButton/index.js +13 -0
  93. package/lib/InputLabel/InputLabel.js +70 -34
  94. package/lib/InputLabel/LabelContent.js +31 -0
  95. package/lib/InputLabel/LabelContent.native.js +9 -1
  96. package/lib/InputLabel/index.js +13 -2
  97. package/lib/InputSupports/InputSupports.js +104 -0
  98. package/lib/InputSupports/index.js +13 -0
  99. package/lib/InputSupports/propTypes.js +66 -0
  100. package/lib/InputSupports/useInputSupports.js +41 -0
  101. package/lib/Link/ChevronLink.js +57 -15
  102. package/lib/Link/InlinePressable.js +50 -0
  103. package/lib/Link/InlinePressable.native.js +101 -0
  104. package/lib/Link/Link.js +30 -13
  105. package/lib/Link/LinkBase.js +114 -145
  106. package/lib/Link/TextButton.js +47 -17
  107. package/lib/Link/index.js +39 -4
  108. package/lib/List/List.js +80 -0
  109. package/lib/List/ListItem.js +237 -0
  110. package/lib/List/index.js +13 -0
  111. package/lib/Modal/Modal.js +226 -0
  112. package/lib/Modal/dictionary.js +16 -0
  113. package/lib/Modal/index.js +13 -0
  114. package/lib/Notification/Notification.js +200 -0
  115. package/lib/Notification/dictionary.js +15 -0
  116. package/lib/Notification/index.js +13 -0
  117. package/lib/Pagination/PageButton.js +45 -46
  118. package/lib/Pagination/Pagination.js +70 -40
  119. package/lib/Pagination/SideButton.js +74 -58
  120. package/lib/Pagination/dictionary.js +9 -2
  121. package/lib/Pagination/index.js +13 -2
  122. package/lib/Pagination/usePagination.js +12 -2
  123. package/lib/Progress/Progress.js +99 -0
  124. package/lib/Progress/ProgressBar.js +146 -0
  125. package/lib/Progress/ProgressBarBackground.js +57 -0
  126. package/lib/Progress/index.js +16 -0
  127. package/lib/Radio/Radio.js +292 -0
  128. package/lib/Radio/RadioButton.js +141 -0
  129. package/lib/Radio/RadioGroup.js +233 -0
  130. package/lib/Radio/RadioInput.js +76 -0
  131. package/lib/Radio/RadioInput.native.js +14 -0
  132. package/lib/Radio/index.js +21 -0
  133. package/lib/RadioCard/RadioCard.js +240 -0
  134. package/lib/RadioCard/RadioCardGroup.js +251 -0
  135. package/lib/RadioCard/index.js +21 -0
  136. package/lib/Search/Search.js +243 -0
  137. package/lib/Search/dictionary.js +19 -0
  138. package/lib/Search/index.js +13 -0
  139. package/lib/Select/Group.js +33 -0
  140. package/lib/Select/Group.native.js +25 -0
  141. package/lib/Select/Item.js +29 -0
  142. package/lib/Select/Item.native.js +19 -0
  143. package/lib/Select/Picker.js +79 -0
  144. package/lib/Select/Picker.native.js +115 -0
  145. package/lib/Select/Select.js +300 -0
  146. package/lib/Select/index.js +19 -0
  147. package/lib/SideNav/Item.js +54 -33
  148. package/lib/SideNav/ItemContent.js +41 -15
  149. package/lib/SideNav/ItemsGroup.js +46 -27
  150. package/lib/SideNav/SideNav.js +92 -69
  151. package/lib/SideNav/index.js +15 -1
  152. package/lib/Skeleton/Skeleton.js +137 -0
  153. package/lib/Skeleton/index.js +13 -0
  154. package/lib/Skeleton/skeleton.constant.js +12 -0
  155. package/lib/Skeleton/skeletonWebAnimation.js +27 -0
  156. package/lib/Skeleton/useSkeletonNativeAnimation.js +37 -0
  157. package/lib/Spacer/Spacer.js +31 -12
  158. package/lib/Spacer/index.js +13 -2
  159. package/lib/StackView/StackView.js +57 -33
  160. package/lib/StackView/StackWrap.js +33 -10
  161. package/lib/StackView/StackWrap.native.js +13 -2
  162. package/lib/StackView/StackWrapBox.js +50 -23
  163. package/lib/StackView/StackWrapGap.js +45 -19
  164. package/lib/StackView/common.js +19 -4
  165. package/lib/StackView/getStackedContent.js +49 -19
  166. package/lib/StackView/index.js +29 -5
  167. package/lib/StepTracker/Step.js +245 -0
  168. package/lib/StepTracker/StepTracker.js +197 -0
  169. package/lib/StepTracker/dictionary.js +17 -0
  170. package/lib/StepTracker/index.js +13 -0
  171. package/lib/Tabs/HorizontalScroll.js +199 -0
  172. package/lib/Tabs/ScrollViewEnd.js +66 -0
  173. package/lib/Tabs/ScrollViewEnd.native.js +41 -0
  174. package/lib/Tabs/Tabs.js +117 -0
  175. package/lib/Tabs/TabsItem.js +234 -0
  176. package/lib/Tabs/TabsScrollButton.js +121 -0
  177. package/lib/Tabs/dictionary.js +18 -0
  178. package/lib/Tabs/index.js +13 -0
  179. package/lib/Tabs/itemPositions.js +128 -0
  180. package/lib/Tags/Tags.js +250 -0
  181. package/lib/Tags/index.js +13 -0
  182. package/lib/TextInput/TextArea.js +109 -0
  183. package/lib/TextInput/TextInput.js +41 -303
  184. package/lib/TextInput/TextInputBase.js +252 -0
  185. package/lib/TextInput/index.js +23 -2
  186. package/lib/TextInput/propTypes.js +42 -0
  187. package/lib/ThemeProvider/ThemeProvider.js +38 -14
  188. package/lib/ThemeProvider/index.js +61 -6
  189. package/lib/ThemeProvider/useSetTheme.js +14 -5
  190. package/lib/ThemeProvider/useTheme.js +13 -4
  191. package/lib/ThemeProvider/useThemeTokens.js +86 -19
  192. package/lib/ThemeProvider/utils/index.js +31 -2
  193. package/lib/ThemeProvider/utils/styles.js +52 -16
  194. package/lib/ThemeProvider/utils/theme-tokens.js +94 -16
  195. package/lib/ToggleSwitch/ToggleSwitch.js +76 -52
  196. package/lib/ToggleSwitch/index.js +13 -2
  197. package/lib/Tooltip/Backdrop.js +56 -0
  198. package/lib/Tooltip/Backdrop.native.js +59 -0
  199. package/lib/Tooltip/Tooltip.js +357 -0
  200. package/lib/Tooltip/dictionary.js +15 -0
  201. package/lib/Tooltip/getTooltipPosition.js +172 -0
  202. package/lib/Tooltip/index.js +13 -0
  203. package/lib/TooltipButton/TooltipButton.js +83 -0
  204. package/lib/TooltipButton/index.js +13 -0
  205. package/lib/Typography/Typography.js +58 -43
  206. package/lib/Typography/index.js +13 -2
  207. package/lib/ViewportProvider/ViewportProvider.js +46 -0
  208. package/lib/ViewportProvider/index.js +22 -38
  209. package/lib/ViewportProvider/useViewport.js +15 -0
  210. package/lib/ViewportProvider/useViewportListener.js +57 -0
  211. package/lib/index.js +518 -24
  212. package/lib/utils/a11y/index.js +18 -0
  213. package/lib/utils/a11y/textSize.js +49 -0
  214. package/lib/utils/animation/index.js +15 -2
  215. package/lib/utils/animation/useVerticalExpandAnimation.js +28 -11
  216. package/lib/utils/children.js +87 -0
  217. package/lib/utils/index.js +163 -4
  218. package/lib/utils/info/index.js +19 -0
  219. package/lib/utils/info/platform/index.js +23 -0
  220. package/lib/utils/info/platform/platform.android.js +8 -0
  221. package/lib/utils/info/platform/platform.ios.js +8 -0
  222. package/lib/utils/info/platform/platform.js +8 -0
  223. package/lib/utils/info/platform/platform.native.js +11 -0
  224. package/lib/utils/info/versions.js +16 -0
  225. package/lib/utils/input.js +51 -33
  226. package/lib/utils/pressability.js +120 -0
  227. package/lib/utils/propTypes.js +269 -116
  228. package/lib/utils/useCopy.js +51 -0
  229. package/lib/utils/useHash.js +48 -0
  230. package/lib/utils/useHash.native.js +15 -0
  231. package/lib/utils/useResponsiveProp.js +59 -0
  232. package/lib/utils/{spacing/useSpacingScale.js → useSpacingScale.js} +45 -12
  233. package/lib/utils/useUniqueId.js +13 -4
  234. package/package.json +12 -9
  235. package/release-context.json +4 -4
  236. package/src/ActivityIndicator/{Spinner.web.jsx → Spinner.jsx} +0 -0
  237. package/src/Box/Box.jsx +11 -4
  238. package/src/Button/Button.jsx +9 -5
  239. package/src/Button/ButtonBase.jsx +69 -69
  240. package/src/Button/ButtonGroup.jsx +11 -24
  241. package/src/Button/ButtonLink.jsx +14 -4
  242. package/src/Button/propTypes.js +12 -2
  243. package/src/Card/Card.jsx +4 -30
  244. package/src/Card/CardBase.jsx +57 -0
  245. package/src/Card/PressableCardBase.jsx +112 -0
  246. package/src/Card/index.js +3 -0
  247. package/src/Checkbox/Checkbox.jsx +274 -0
  248. package/src/Checkbox/CheckboxGroup.jsx +196 -0
  249. package/src/Checkbox/CheckboxInput.jsx +55 -0
  250. package/src/Checkbox/CheckboxInput.native.jsx +6 -0
  251. package/src/Checkbox/index.js +5 -0
  252. package/src/ExpandCollapse/Control.jsx +1 -1
  253. package/src/Feedback/Feedback.jsx +31 -22
  254. package/src/Fieldset/Fieldset.jsx +129 -0
  255. package/src/Fieldset/FieldsetContainer.jsx +22 -0
  256. package/src/Fieldset/FieldsetContainer.native.jsx +16 -0
  257. package/src/Fieldset/Legend.jsx +16 -0
  258. package/src/Fieldset/Legend.native.jsx +22 -0
  259. package/src/Fieldset/cssReset.js +14 -0
  260. package/src/Fieldset/index.js +3 -0
  261. package/src/Icon/Icon.jsx +21 -26
  262. package/src/Icon/IconText.jsx +63 -0
  263. package/src/Icon/index.js +3 -2
  264. package/src/IconButton/IconButton.jsx +107 -0
  265. package/src/IconButton/index.js +3 -0
  266. package/src/InputLabel/InputLabel.jsx +11 -4
  267. package/src/InputLabel/{LabelContent.web.jsx → LabelContent.jsx} +0 -0
  268. package/src/InputSupports/InputSupports.jsx +75 -0
  269. package/src/InputSupports/index.js +3 -0
  270. package/src/InputSupports/propTypes.js +44 -0
  271. package/src/InputSupports/useInputSupports.js +30 -0
  272. package/src/Link/ChevronLink.jsx +28 -7
  273. package/src/Link/InlinePressable.jsx +37 -0
  274. package/src/Link/InlinePressable.native.jsx +73 -0
  275. package/src/Link/Link.jsx +17 -13
  276. package/src/Link/LinkBase.jsx +67 -148
  277. package/src/Link/TextButton.jsx +25 -11
  278. package/src/Link/index.js +2 -1
  279. package/src/List/List.jsx +47 -0
  280. package/src/List/ListItem.jsx +187 -0
  281. package/src/List/index.js +3 -0
  282. package/src/Modal/Modal.jsx +185 -0
  283. package/src/Modal/dictionary.js +9 -0
  284. package/src/Modal/index.js +3 -0
  285. package/src/Notification/Notification.jsx +149 -0
  286. package/src/Notification/dictionary.js +8 -0
  287. package/src/Notification/index.js +3 -0
  288. package/src/Pagination/PageButton.jsx +3 -17
  289. package/src/Pagination/SideButton.jsx +27 -38
  290. package/src/Progress/Progress.jsx +77 -0
  291. package/src/Progress/ProgressBar.jsx +110 -0
  292. package/src/Progress/ProgressBarBackground.jsx +34 -0
  293. package/src/Progress/index.js +6 -0
  294. package/src/Radio/Radio.jsx +233 -0
  295. package/src/Radio/RadioButton.jsx +131 -0
  296. package/src/Radio/RadioGroup.jsx +198 -0
  297. package/src/Radio/RadioInput.jsx +57 -0
  298. package/src/Radio/RadioInput.native.jsx +6 -0
  299. package/src/Radio/index.js +5 -0
  300. package/src/RadioCard/RadioCard.jsx +191 -0
  301. package/src/RadioCard/RadioCardGroup.jsx +211 -0
  302. package/src/RadioCard/index.js +5 -0
  303. package/src/Search/Search.jsx +204 -0
  304. package/src/Search/dictionary.js +12 -0
  305. package/src/Search/index.js +3 -0
  306. package/src/Select/Group.jsx +15 -0
  307. package/src/Select/Group.native.jsx +14 -0
  308. package/src/Select/Item.jsx +11 -0
  309. package/src/Select/Item.native.jsx +10 -0
  310. package/src/Select/Picker.jsx +67 -0
  311. package/src/Select/Picker.native.jsx +95 -0
  312. package/src/Select/Select.jsx +255 -0
  313. package/src/Select/index.js +8 -0
  314. package/src/SideNav/Item.jsx +2 -2
  315. package/src/Skeleton/Skeleton.jsx +98 -0
  316. package/src/Skeleton/index.js +3 -0
  317. package/src/Skeleton/skeleton.constant.js +3 -0
  318. package/src/Skeleton/skeletonWebAnimation.js +13 -0
  319. package/src/Skeleton/useSkeletonNativeAnimation.js +27 -0
  320. package/src/StackView/StackView.jsx +25 -17
  321. package/src/StackView/StackWrap.jsx +9 -1
  322. package/src/StackView/StackWrapBox.jsx +19 -7
  323. package/src/StackView/StackWrapGap.jsx +15 -5
  324. package/src/StackView/getStackedContent.jsx +8 -2
  325. package/src/StepTracker/Step.jsx +202 -0
  326. package/src/StepTracker/StepTracker.jsx +163 -0
  327. package/src/StepTracker/dictionary.js +10 -0
  328. package/src/StepTracker/index.js +3 -0
  329. package/src/Tabs/HorizontalScroll.jsx +165 -0
  330. package/src/Tabs/ScrollViewEnd.jsx +53 -0
  331. package/src/Tabs/ScrollViewEnd.native.jsx +24 -0
  332. package/src/Tabs/Tabs.jsx +89 -0
  333. package/src/Tabs/TabsItem.jsx +204 -0
  334. package/src/Tabs/TabsScrollButton.jsx +100 -0
  335. package/src/Tabs/dictionary.js +11 -0
  336. package/src/Tabs/index.js +3 -0
  337. package/src/Tabs/itemPositions.js +101 -0
  338. package/src/Tags/Tags.jsx +207 -0
  339. package/src/Tags/index.js +3 -0
  340. package/src/TextInput/TextArea.jsx +78 -0
  341. package/src/TextInput/TextInput.jsx +17 -290
  342. package/src/TextInput/TextInputBase.jsx +210 -0
  343. package/src/TextInput/index.js +2 -1
  344. package/src/TextInput/propTypes.js +29 -0
  345. package/src/ThemeProvider/useThemeTokens.js +56 -5
  346. package/src/ThemeProvider/utils/styles.js +18 -5
  347. package/src/ThemeProvider/utils/theme-tokens.js +46 -5
  348. package/src/ToggleSwitch/ToggleSwitch.jsx +3 -4
  349. package/src/Tooltip/Backdrop.jsx +60 -0
  350. package/src/Tooltip/Backdrop.native.jsx +33 -0
  351. package/src/Tooltip/Tooltip.jsx +294 -0
  352. package/src/Tooltip/dictionary.js +8 -0
  353. package/src/Tooltip/getTooltipPosition.js +161 -0
  354. package/src/Tooltip/index.js +3 -0
  355. package/src/TooltipButton/TooltipButton.jsx +49 -0
  356. package/src/TooltipButton/index.js +3 -0
  357. package/src/Typography/Typography.jsx +10 -20
  358. package/src/ViewportProvider/ViewportProvider.jsx +21 -0
  359. package/src/ViewportProvider/index.jsx +2 -41
  360. package/src/ViewportProvider/useViewport.js +5 -0
  361. package/src/ViewportProvider/useViewportListener.js +43 -0
  362. package/src/index.js +31 -3
  363. package/src/utils/a11y/index.js +1 -0
  364. package/src/utils/a11y/textSize.js +30 -0
  365. package/src/utils/children.jsx +66 -0
  366. package/src/utils/index.js +11 -1
  367. package/src/utils/info/index.js +8 -0
  368. package/src/utils/info/platform/index.js +11 -0
  369. package/src/utils/info/platform/platform.android.js +1 -0
  370. package/src/utils/info/platform/platform.ios.js +1 -0
  371. package/src/utils/info/platform/platform.js +1 -0
  372. package/src/utils/info/platform/platform.native.js +4 -0
  373. package/src/utils/info/versions.js +6 -0
  374. package/src/utils/input.js +20 -12
  375. package/src/utils/pressability.js +96 -0
  376. package/src/utils/propTypes.js +195 -56
  377. package/src/utils/useCopy.js +39 -0
  378. package/src/utils/useHash.js +34 -0
  379. package/src/utils/useHash.native.js +6 -0
  380. package/src/utils/useResponsiveProp.js +50 -0
  381. package/src/utils/{spacing/useSpacingScale.js → useSpacingScale.js} +25 -10
  382. package/stories/A11yText/A11yText.stories.jsx +4 -8
  383. package/stories/Button/Button.stories.jsx +5 -0
  384. package/stories/Card/Card.stories.jsx +1 -1
  385. package/stories/Checkbox/Checkbox.stories.jsx +94 -0
  386. package/stories/Feedback/Feedback.stories.jsx +5 -6
  387. package/stories/Icon/Icon.stories.jsx +27 -7
  388. package/stories/IconButton/IconButton.stories.jsx +50 -0
  389. package/stories/InputLabel/InputLabel.stories.jsx +8 -3
  390. package/stories/Link/ChevronLink.stories.jsx +3 -3
  391. package/stories/Link/Link.stories.jsx +28 -18
  392. package/stories/List/List.stories.jsx +117 -0
  393. package/stories/Modal/Modal.stories.jsx +29 -0
  394. package/stories/Notification/Notification.stories.jsx +82 -0
  395. package/stories/Progress/Progress.stories.jsx +93 -0
  396. package/stories/Radio/Radio.stories.jsx +100 -0
  397. package/stories/RadioCard/RadioCard.stories.jsx +98 -0
  398. package/stories/Search/Search.stories.jsx +16 -0
  399. package/stories/Select/Select.stories.jsx +55 -0
  400. package/stories/Skeleton/Skeleton.stories.jsx +36 -0
  401. package/stories/Spacer/Spacer.stories.jsx +7 -2
  402. package/stories/StackView/StackView.stories.jsx +10 -0
  403. package/stories/StackView/StackWrap.stories.jsx +12 -0
  404. package/stories/StepTracker/StepTracker.stories.jsx +71 -0
  405. package/stories/Tabs/Tabs.stories.jsx +97 -0
  406. package/stories/Tags/Tags.stories.jsx +69 -0
  407. package/stories/TextInput/TextArea.stories.jsx +100 -0
  408. package/stories/Tooltip/Tooltip.stories.jsx +81 -0
  409. package/stories/TooltipButton/TooltipButton.stories.jsx +11 -0
  410. package/stories/{platform-supports.web.jsx → platform-supports.jsx} +0 -0
  411. package/stories/supports.jsx +36 -2
  412. package/__fixtures__/accessible.icon.svg +0 -6
  413. package/babel.config.json +0 -8
  414. package/docs/Contributing.stories.mdx +0 -9
  415. package/docs/Fonts.stories.mdx +0 -104
  416. package/docs/Icons.stories.mdx +0 -144
  417. package/docs/Introduction.stories.mdx +0 -9
  418. package/lib/ActivityIndicator/Spinner.web.js +0 -55
  419. package/lib/InputLabel/LabelContent.web.js +0 -17
  420. package/lib/Pagination/useCopy.js +0 -10
  421. package/lib/config/svgr-icons-web.js +0 -9
  422. package/lib/config/svgr-icons.js +0 -52
  423. package/lib/utils/spacing/index.js +0 -2
  424. package/lib/utils/spacing/utils.js +0 -32
  425. package/src/Pagination/useCopy.js +0 -7
  426. package/src/config/svgr-icons-web.js +0 -11
  427. package/src/config/svgr-icons.js +0 -46
  428. package/src/utils/spacing/index.js +0 -3
  429. package/src/utils/spacing/utils.js +0 -28
@@ -58,7 +58,7 @@ const Item = ({
58
58
  accessibilityRole,
59
59
  href,
60
60
  onPress: handlePress,
61
- ...hrefAttrsProp.spread(hrefAttrs),
61
+ hrefAttrs,
62
62
  ...rest
63
63
  })
64
64
 
@@ -105,7 +105,7 @@ Item.propTypes = {
105
105
  href: PropTypes.string,
106
106
  /**
107
107
  * 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.
108
+ * `rel`, `target` and `download` attrs.
109
109
  */
110
110
  hrefAttrs: PropTypes.shape(hrefAttrsProp.types),
111
111
  /**
@@ -0,0 +1,98 @@
1
+ import React from 'react'
2
+ import { Animated, Platform } from 'react-native'
3
+ import propTypes from 'prop-types'
4
+ import StackView from '../StackView'
5
+ import { useThemeTokens } from '../ThemeProvider'
6
+ import { getTokensPropType, useSpacingScale, variantProp } from '../utils'
7
+ import useSkeletonNativeAnimation from './useSkeletonNativeAnimation'
8
+ import skeletonWebAnimation from './skeletonWebAnimation'
9
+
10
+ const selectSkeletonStyles = ({ color, radius, fadeAnimation }) => ({
11
+ backgroundColor: color,
12
+ borderRadius: radius,
13
+ ...fadeAnimation
14
+ })
15
+
16
+ const selectLineStyles = ({ skeletonHeight, lineWidth }) => ({
17
+ width: lineWidth,
18
+ height: skeletonHeight
19
+ })
20
+
21
+ const selectShapeStyles = ({ skeletonHeight }) => ({
22
+ height: skeletonHeight,
23
+ width: skeletonHeight
24
+ })
25
+
26
+ const selectSquareStyles = ({ radius }) => ({
27
+ borderRadius: radius
28
+ })
29
+
30
+ const Skeleton = ({ tokens, variant, size, characters, lines, shape = 'line' }) => {
31
+ const themeTokens = useThemeTokens('Skeleton', tokens, variant)
32
+ const skeletonHeight = useSpacingScale(size || themeTokens.size)
33
+ const nativeAnimation = useSkeletonNativeAnimation()
34
+
35
+ const getAnimationBaseOnPlatform = () => {
36
+ if (Platform.OS !== 'web') {
37
+ return nativeAnimation
38
+ }
39
+
40
+ return skeletonWebAnimation
41
+ }
42
+
43
+ const getLineWidth = () => {
44
+ if (characters) {
45
+ return characters * themeTokens.baseWidth
46
+ }
47
+
48
+ return themeTokens.characters * themeTokens.baseWidth
49
+ }
50
+
51
+ const getStyledBasedOnShape = () => {
52
+ if (shape === 'circle') {
53
+ return selectShapeStyles({ skeletonHeight })
54
+ }
55
+
56
+ if (shape === 'box') {
57
+ return [
58
+ selectShapeStyles({ skeletonHeight }),
59
+ selectSquareStyles({ radius: themeTokens.squareRadius })
60
+ ]
61
+ }
62
+
63
+ return selectLineStyles({ skeletonHeight, lineWidth: getLineWidth() })
64
+ }
65
+
66
+ const renderSkeleton = (index = 0) => (
67
+ <Animated.View
68
+ testID="skeleton"
69
+ key={`skeleton-${index + 1}`}
70
+ style={[
71
+ selectSkeletonStyles({ ...themeTokens, fadeAnimation: getAnimationBaseOnPlatform() }),
72
+ getStyledBasedOnShape()
73
+ ]}
74
+ />
75
+ )
76
+
77
+ if (lines) {
78
+ const arrayOfSkeletons = [...Array(lines)]
79
+ return (
80
+ <StackView space={themeTokens.spaceBetweenLines}>
81
+ {arrayOfSkeletons.map((_, index) => renderSkeleton(index))}
82
+ </StackView>
83
+ )
84
+ }
85
+
86
+ return renderSkeleton()
87
+ }
88
+
89
+ Skeleton.propTypes = {
90
+ tokens: getTokensPropType('Skeleton'),
91
+ variant: variantProp.propType,
92
+ size: propTypes.number,
93
+ characters: propTypes.number,
94
+ lines: propTypes.number,
95
+ shape: propTypes.oneOf(['line', 'circle', 'box'])
96
+ }
97
+
98
+ export default Skeleton
@@ -0,0 +1,3 @@
1
+ import Skeleton from './Skeleton'
2
+
3
+ export default Skeleton
@@ -0,0 +1,3 @@
1
+ export const DEFAULT_OPACITY = 1
2
+ export const OPACITY_STOP = 0.4
3
+ export const ANIMATION_DURATION = 1500
@@ -0,0 +1,13 @@
1
+ import { ANIMATION_DURATION, DEFAULT_OPACITY, OPACITY_STOP } from './skeleton.constant'
2
+
3
+ export default {
4
+ animationDuration: `${ANIMATION_DURATION}ms`,
5
+ animationTimingFunction: 'ease-in-out',
6
+ animationDelay: '0.5s',
7
+ animationIterationCount: 'infinite',
8
+ animationKeyframes: {
9
+ '0%': { opacity: DEFAULT_OPACITY },
10
+ '50%': { opacity: OPACITY_STOP },
11
+ '100%': { opacity: DEFAULT_OPACITY }
12
+ }
13
+ }
@@ -0,0 +1,27 @@
1
+ import { useEffect, useRef } from 'react'
2
+ import { Animated } from 'react-native'
3
+ import { ANIMATION_DURATION, DEFAULT_OPACITY, OPACITY_STOP } from './skeleton.constant'
4
+
5
+ const useSkeletonNativeAnimation = () => {
6
+ const fadeAnimation = useRef(new Animated.Value(DEFAULT_OPACITY)).current
7
+
8
+ useEffect(() => {
9
+ const fade = Animated.sequence([
10
+ Animated.timing(fadeAnimation, {
11
+ toValue: OPACITY_STOP,
12
+ duration: ANIMATION_DURATION,
13
+ useNativeDriver: true
14
+ }),
15
+ Animated.timing(fadeAnimation, {
16
+ toValue: DEFAULT_OPACITY,
17
+ duration: ANIMATION_DURATION,
18
+ useNativeDriver: true
19
+ })
20
+ ])
21
+ Animated.loop(fade).start()
22
+ }, [fadeAnimation])
23
+
24
+ return { opacity: fadeAnimation }
25
+ }
26
+
27
+ export default useSkeletonNativeAnimation
@@ -3,8 +3,16 @@ import PropTypes from 'prop-types'
3
3
  import { View } from 'react-native'
4
4
 
5
5
  import Divider from '../Divider'
6
- import { spacingProps, a11yProps } from '../utils'
6
+ import {
7
+ spacingProps,
8
+ a11yProps,
9
+ responsiveProps,
10
+ variantProp,
11
+ viewProps,
12
+ useResponsiveProp
13
+ } from '../utils'
7
14
  import { useThemeTokens } from '../ThemeProvider'
15
+ import { useViewport } from '../ViewportProvider'
8
16
  import getStackedContent from './getStackedContent'
9
17
  import { staticStyles, selectFlexStyles } from './common'
10
18
 
@@ -25,10 +33,14 @@ import { staticStyles, selectFlexStyles } from './common'
25
33
  * - `'column-reverse'` acts the same as `'column'`, but reverses the direction.
26
34
  * - `'row-reverse'` acts the same as `'row'`, but reverses the direction.
27
35
  *
36
+ * `direction` is an optionally responsive prop and may be an object keyed by viewports. For example,
37
+ * `{ xs: 'column', md: 'row' } stacks as a column on `xs` and `sm` viewports and a row at 'md' and above.
38
+ *
28
39
  * ## Theming, alignment and justification
29
40
  *
30
41
  * `StackView` is a pure layout component and has no theme styles beyond a small set of layout styles
31
- * (`alignItems`, `justifyContent`, `flexGrow`) which may be set using the `tokens` prop.
42
+ * (`alignItems`, `justifyContent`, `flexGrow`) which may be set using the `tokens` prop. If the
43
+ * tokens prop is a function it will recieve the current viewport.
32
44
  *
33
45
  * All other styling such as borders, background colours, padding etc should be applied by wrapping
34
46
  * the `StackView` in other components. For example, a `StackView` may be the child of a `Card`.
@@ -49,22 +61,21 @@ import { staticStyles, selectFlexStyles } from './common'
49
61
  const StackView = ({
50
62
  space = 1,
51
63
  divider,
52
- direction = 'column',
53
- inherit,
64
+ direction: directionProp = 'column',
54
65
  children,
55
66
  variant,
56
67
  tokens,
57
68
  ...rest
58
69
  }) => {
59
- const a11y = a11yProps.select({ ...rest })
70
+ const viewport = useViewport()
71
+ const direction = useResponsiveProp(directionProp, 'column')
72
+ const props = { ...a11yProps.select(rest), ...viewProps.select(rest) }
60
73
  const content = getStackedContent(children, { direction, divider, space })
61
- const themeTokens = useThemeTokens('StackView', tokens, variant)
74
+ const themeTokens = useThemeTokens('StackView', tokens, variant, { viewport })
62
75
  const flexStyles = selectFlexStyles(themeTokens)
63
76
 
64
- return inherit ? (
65
- content
66
- ) : (
67
- <View {...a11y} style={[flexStyles, staticStyles[direction]]}>
77
+ return (
78
+ <View {...props} style={[flexStyles, staticStyles[direction]]}>
68
79
  {content}
69
80
  </View>
70
81
  )
@@ -72,21 +83,18 @@ const StackView = ({
72
83
 
73
84
  StackView.propTypes = {
74
85
  ...a11yProps.propTypes,
86
+ variant: variantProp.propType,
75
87
  /**
76
88
  * Sets the `flexDirection` of the container and, if `divider` is used, gives the Divider the appropriate direction.
77
89
  */
78
- direction: PropTypes.oneOf(['column', 'row', 'column-reverse', 'row-reverse']),
90
+ direction: responsiveProps.getTypeOptionallyByViewport(
91
+ PropTypes.oneOf(['column', 'row', 'column-reverse', 'row-reverse'])
92
+ ),
79
93
  /**
80
94
  * If true, renders a UDS `Divider` component between each item. If an object is passed,
81
95
  * this object is passes as props to each Divider.
82
96
  */
83
97
  divider: PropTypes.oneOfType([PropTypes.bool, PropTypes.shape(Divider.propTypes)]),
84
- /**
85
- * If true, does not render any container and returns an array of spaced children, inheriting
86
- * flex styles from the StackView's parent. That parent must have a `flexDirection` style corresponding
87
- * to the StackView's `direction` prop for `divider` prop to behave correctly.
88
- */
89
- inherit: PropTypes.bool,
90
98
  /**
91
99
  * The size of the spacer according to the theme's spacing scale.
92
100
  * Either a number corresponding to a position on the theme's spacing scale (1 is smallest, 2 is second smallest, etc),
@@ -1,4 +1,5 @@
1
1
  import React from 'react'
2
+ import { Platform } from 'react-native'
2
3
 
3
4
  import StackWrapBox from './StackWrapBox'
4
5
  import StackWrapGap from './StackWrapGap'
@@ -20,7 +21,14 @@ const StackWrap = (props) => {
20
21
  // eslint-disable-next-line react/destructuring-assignment
21
22
  const gap = props.gap ?? space
22
23
 
23
- return gap === space && CSS?.supports('gap', exampleGapValue) ? (
24
+ const canUseCSSGap =
25
+ Platform.OS === 'web' &&
26
+ gap === space &&
27
+ // In Jest/CI, global CSS isn't always available and doesn't always have .supports method
28
+ typeof CSS?.supports === 'function' &&
29
+ CSS.supports('gap', exampleGapValue)
30
+
31
+ return canUseCSSGap ? (
24
32
  // If possible, use the cleaner implementation that applies CSS `gap` styles to the container.
25
33
  <StackWrapGap {...props} />
26
34
  ) : (
@@ -2,8 +2,16 @@ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { View } from 'react-native'
4
4
 
5
- import { spacingProps, a11yProps, useSpacingScale } from '../utils'
5
+ import {
6
+ spacingProps,
7
+ a11yProps,
8
+ responsiveProps,
9
+ useSpacingScale,
10
+ useResponsiveProp,
11
+ viewProps
12
+ } from '../utils'
6
13
  import { useThemeTokens } from '../ThemeProvider'
14
+ import { useViewport } from '../ViewportProvider'
7
15
  import getStackedContent from './getStackedContent'
8
16
  import { staticStyles, selectFlexStyles } from './common'
9
17
 
@@ -37,15 +45,17 @@ const spaceSides = {
37
45
  const StackWrapBox = ({
38
46
  space = 1,
39
47
  gap = space,
40
- direction = 'row',
48
+ direction: directionProp = 'row',
41
49
  children,
42
50
  tokens,
43
51
  variant,
44
52
  ...rest
45
53
  }) => {
46
- const themeTokens = useThemeTokens('StackView', tokens, variant)
54
+ const viewport = useViewport()
55
+ const direction = useResponsiveProp(directionProp, 'row')
56
+ const themeTokens = useThemeTokens('StackView', tokens, variant, { viewport })
47
57
  const flexStyles = selectFlexStyles(themeTokens)
48
- const a11y = a11yProps.select({ ...rest })
58
+ const props = { ...a11yProps.select(rest), ...viewProps.select(rest) }
49
59
 
50
60
  // Mimic CSS `gap` using box spacing on the side after a wrapped row then offsetting it on the last row.
51
61
  const gapSize = useSpacingScale(gap)
@@ -54,7 +64,7 @@ const StackWrapBox = ({
54
64
  const content = getStackedContent(children, { direction, space: 0, box: boxProps })
55
65
 
56
66
  return (
57
- <View {...a11y} style={[flexStyles, staticStyles.wrap, staticStyles[direction], offsetStyle]}>
67
+ <View {...props} style={[flexStyles, staticStyles.wrap, staticStyles[direction], offsetStyle]}>
58
68
  {content}
59
69
  </View>
60
70
  )
@@ -63,9 +73,11 @@ const StackWrapBox = ({
63
73
  StackWrapBox.propTypes = {
64
74
  ...a11yProps.propTypes,
65
75
  /**
66
- * Sets the `flexDirection` of the container, or if 'inherit' returns spaced children as an array.
76
+ * Sets the `flexDirection` of the container
67
77
  */
68
- direction: PropTypes.oneOf(['column', 'row']),
78
+ direction: responsiveProps.getTypeOptionallyByViewport(
79
+ PropTypes.oneOf(['column', 'row', 'row-reverse', 'column-reverse'])
80
+ ),
69
81
  /**
70
82
  * The size of the spacer according to the theme's spacing scale.
71
83
  * Either a number corresponding to a position on the theme's spacing scale (1 is smallest, 2 is second smallest, etc),
@@ -2,8 +2,9 @@ import React from 'react'
2
2
  import { View } from 'react-native'
3
3
 
4
4
  import StackWrapBox from './StackWrapBox'
5
- import { a11yProps, useSpacingScale } from '../utils'
5
+ import { a11yProps, useSpacingScale, useResponsiveProp, viewProps } from '../utils'
6
6
  import { useThemeTokens } from '../ThemeProvider'
7
+ import { useViewport } from '../ViewportProvider'
7
8
  import getStackedContent from './getStackedContent'
8
9
  import { staticStyles, selectFlexStyles } from './common'
9
10
 
@@ -17,10 +18,19 @@ import { staticStyles, selectFlexStyles } from './common'
17
18
  * - The `space` between items is the same as the `gap` between wrapped rows (this is the
18
19
  * default if `gap` prop is undefined)
19
20
  */
20
- const StackWrapGap = ({ space = 1, tokens, variant, direction = 'row', children, ...rest }) => {
21
- const themeTokens = useThemeTokens('StackView', tokens, variant)
21
+ const StackWrapGap = ({
22
+ space = 1,
23
+ tokens,
24
+ variant,
25
+ direction: directionProp = 'row',
26
+ children,
27
+ ...rest
28
+ }) => {
29
+ const viewport = useViewport()
30
+ const direction = useResponsiveProp(directionProp, 'row')
31
+ const themeTokens = useThemeTokens('StackView', tokens, variant, { viewport })
22
32
  const flexStyles = selectFlexStyles(themeTokens)
23
- const a11y = a11yProps.select({ ...rest })
33
+ const props = { ...a11yProps.select(rest), ...viewProps.select(rest) }
24
34
 
25
35
  const size = useSpacingScale(space)
26
36
  const gapStyle = { gap: size }
@@ -28,7 +38,7 @@ const StackWrapGap = ({ space = 1, tokens, variant, direction = 'row', children,
28
38
  const content = getStackedContent(children, { direction, space: 0 })
29
39
 
30
40
  return (
31
- <View {...a11y} style={[flexStyles, staticStyles.wrap, staticStyles[direction], gapStyle]}>
41
+ <View {...props} style={[flexStyles, staticStyles.wrap, staticStyles[direction], gapStyle]}>
32
42
  {content}
33
43
  </View>
34
44
  )
@@ -23,17 +23,23 @@ import Spacer from '../Spacer'
23
23
  * - `direction`: if 'row' or 'row-reverse', applies space horizontally, if 'column' or 'column-reverse', applies space vertically
24
24
  * - `box`: if truthy, wraps each valid child in a Box component; if an object, passes it to Box as props
25
25
  * - `divider`: if truthy, inserts Divider components; if an object, passes it to Divider as props
26
+ * - `preserveFragments`: if true, adds no space between top-level elements that were passed inside a nested fragment
26
27
  * @param {SpacingValue} [options.space]
27
28
  * @param {boolean | object} [options.divider]
28
29
  * @param {"row" | "column" | "row-reverse" | "column-reverse"} [options.direction]
30
+ * @param {boolean} [options.preserveFragments]
29
31
  * @returns {ReactElement[]}
30
32
  */
31
- const getStackedContent = (children, { divider, space, direction = 'column', box }) => {
33
+ const getStackedContent = (
34
+ children,
35
+ { divider, space, direction = 'column', box, preserveFragments = false }
36
+ ) => {
32
37
  const boxProps = box && typeof box === 'object' ? box : { space }
33
38
  const dividerProps = divider && typeof divider === 'object' ? divider : {}
34
39
 
35
40
  // Avoid surprises if children contains comments, nulls, or is a variable wrapped as a fragment
36
- const validChildren = Children.toArray(unpackFragment(children)).filter(Boolean)
41
+ const topLevelChildren = preserveFragments ? children : unpackFragment(children)
42
+ const validChildren = Children.toArray(topLevelChildren).filter(Boolean)
37
43
  const content = validChildren.reduce((newChildren, child, index) => {
38
44
  const boxID = `Stack-Box-${index}`
39
45
  const item = box ? (
@@ -0,0 +1,202 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { StyleSheet, Text, View } from 'react-native'
4
+
5
+ import StackView from '../StackView'
6
+ import Icon from '../Icon'
7
+ import { getTokensPropType, variantProp } from '../utils'
8
+ import { applyTextStyles } from '../ThemeProvider'
9
+
10
+ const selectCompletedIconTokens = ({ completedIconColor, completedIconSize }) => ({
11
+ size: completedIconSize,
12
+ color: completedIconColor
13
+ })
14
+ const selectConnectorStyles = (
15
+ {
16
+ connectorColor,
17
+ connectorHeight,
18
+ connectorMinWidth,
19
+ connectorCompletedHeight,
20
+ connectorCompletedColor
21
+ },
22
+ isCompleted
23
+ ) => ({
24
+ backgroundColor: connectorColor,
25
+ height: connectorHeight,
26
+ minWidth: connectorMinWidth,
27
+ ...(isCompleted && { height: connectorCompletedHeight, backgroundColor: connectorCompletedColor })
28
+ })
29
+ const selectCurrentInnerStyles = ({ knobCurrentInnerColor, knobCurrentInnerSize }) => ({
30
+ backgroundColor: knobCurrentInnerColor,
31
+ borderRadius: knobCurrentInnerSize / 2,
32
+ height: knobCurrentInnerSize,
33
+ width: knobCurrentInnerSize
34
+ })
35
+ const selectKnobStyles = (
36
+ {
37
+ knobBackgroundColor,
38
+ knobBorderColor,
39
+ knobBorderWidth,
40
+ knobCompletedBackgroundColor,
41
+ knobCompletedBorderColor,
42
+ knobCompletedPaddingLeft,
43
+ knobCompletedPaddingTop,
44
+ knobCurrentBackgroundColor,
45
+ knobCurrentBorderColor,
46
+ knobCurrentBorderWidth,
47
+ knobCurrentPaddingLeft,
48
+ knobCurrentPaddingTop,
49
+ knobSize
50
+ },
51
+ isCompleted,
52
+ isCurrent
53
+ ) => ({
54
+ backgroundColor: knobBackgroundColor,
55
+ borderColor: knobBorderColor,
56
+ borderRadius: knobSize / 2,
57
+ borderWidth: knobBorderWidth,
58
+ height: knobSize,
59
+ width: knobSize,
60
+ ...(isCompleted && {
61
+ backgroundColor: knobCompletedBackgroundColor,
62
+ borderColor: knobCompletedBorderColor,
63
+ paddingLeft: knobCompletedPaddingLeft,
64
+ paddingTop: knobCompletedPaddingTop
65
+ }),
66
+ ...(isCurrent && {
67
+ backgroundColor: knobCurrentBackgroundColor,
68
+ borderColor: knobCurrentBorderColor,
69
+ borderWidth: knobCurrentBorderWidth,
70
+ paddingLeft: knobCurrentPaddingLeft,
71
+ paddingTop: knobCurrentPaddingTop
72
+ })
73
+ })
74
+ const selectLabelContainerStyles = ({
75
+ labelDirection,
76
+ labelGap,
77
+ labelMarginTop,
78
+ labelPaddingLeft,
79
+ labelPaddingRight
80
+ }) => ({
81
+ marginTop: labelMarginTop,
82
+ paddingLeft: labelPaddingLeft,
83
+ paddingRight: labelPaddingRight,
84
+ flexDirection: labelDirection,
85
+ gap: labelGap
86
+ })
87
+ const selectLabelStyles = (
88
+ {
89
+ labelColor,
90
+ labelCurrentColor,
91
+ labelCurrentFontWeight,
92
+ labelFontSize,
93
+ labelFontWeight,
94
+ labelFontName,
95
+ labelLineHeight
96
+ },
97
+ isCurrent
98
+ ) =>
99
+ applyTextStyles({
100
+ color: isCurrent ? labelCurrentColor : labelColor,
101
+ fontSize: labelFontSize,
102
+ lineHeight: labelLineHeight,
103
+ fontWeight: isCurrent ? labelCurrentFontWeight : labelFontWeight,
104
+ fontName: labelFontName
105
+ })
106
+ const getStepTestID = (isCompleted, isCurrent) => {
107
+ let testID = 'StepTracker-Step'
108
+ if (isCompleted) {
109
+ testID += '-Completed'
110
+ } else if (isCurrent) {
111
+ testID += '-Current'
112
+ }
113
+
114
+ return testID
115
+ }
116
+
117
+ /**
118
+ * A single step of a StepTracker.
119
+ */
120
+ const Step = ({ label, name, status = 0, stepCount = 0, stepIndex = 0, tokens }) => {
121
+ const { completedIcon, showStepLabel, showStepName, ...themeTokens } = tokens
122
+ const isFirst = stepIndex === 0
123
+ const isLast = stepIndex === stepCount - 1
124
+ const isCompleted = status > stepIndex
125
+ const isCurrent = status === stepIndex
126
+ const isActive = isCompleted || isCurrent
127
+
128
+ return (
129
+ <StackView
130
+ space={0}
131
+ tokens={{ alignItems: 'stretch', flexGrow: 1 }}
132
+ accessibilityLabel={label}
133
+ accessibilityLevel={2}
134
+ accessibilityCurrent={status === stepIndex ? 'true' : 'false'}
135
+ >
136
+ <StackView direction="row" space={0} tokens={{ alignItems: 'center', flexGrow: 0 }}>
137
+ <View
138
+ style={[staticStyles.connector, !isFirst && selectConnectorStyles(themeTokens, isActive)]}
139
+ />
140
+ <View
141
+ style={[staticStyles.knob, selectKnobStyles(themeTokens, isCompleted, isCurrent)]}
142
+ testID={getStepTestID(isCompleted, isCurrent)}
143
+ >
144
+ {isCompleted && completedIcon && (
145
+ <Icon icon={completedIcon} tokens={selectCompletedIconTokens(themeTokens)} />
146
+ )}
147
+ {isCurrent && <View style={selectCurrentInnerStyles(themeTokens)} />}
148
+ </View>
149
+ <View
150
+ style={[
151
+ staticStyles.connector,
152
+ !isLast && selectConnectorStyles(themeTokens, isCompleted)
153
+ ]}
154
+ />
155
+ </StackView>
156
+ {showStepLabel && (
157
+ <View style={[staticStyles.stepLabelContainer, selectLabelContainerStyles(tokens)]}>
158
+ {showStepName && (
159
+ <Text style={[staticStyles.centeredText, selectLabelStyles(tokens, isCurrent)]}>
160
+ {name}
161
+ </Text>
162
+ )}
163
+ <StackView direction="row">
164
+ <Text
165
+ style={[
166
+ staticStyles.centeredText,
167
+ tokens.labelDirection === 'column' && staticStyles.wrappingLabel,
168
+ selectLabelStyles(tokens, isCurrent)
169
+ ]}
170
+ >
171
+ {label}
172
+ </Text>
173
+ </StackView>
174
+ </View>
175
+ )}
176
+ </StackView>
177
+ )
178
+ }
179
+
180
+ Step.propTypes = {
181
+ label: PropTypes.string.isRequired,
182
+ name: PropTypes.string.isRequired,
183
+ status: PropTypes.number.isRequired,
184
+ stepCount: PropTypes.number.isRequired,
185
+ stepIndex: PropTypes.number.isRequired,
186
+ tokens: getTokensPropType('StepTracker'),
187
+ variant: variantProp.propType
188
+ }
189
+
190
+ export default Step
191
+
192
+ const staticStyles = StyleSheet.create({
193
+ centeredText: { textAlign: 'center' },
194
+ connector: { flex: 1, height: 1 },
195
+ completedKnob: {
196
+ backgroundColor: 'transparent',
197
+ textAlign: 'center'
198
+ },
199
+ knob: { borderWidth: 1 },
200
+ stepLabelContainer: { justifyContent: 'center' },
201
+ wrappingLabel: { width: 0, flex: 1 }
202
+ })