@telus-uds/components-base 0.0.2-prerelease.6 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (458) hide show
  1. package/.eslintrc.js +9 -0
  2. package/.ultra.cache.json +1 -1
  3. package/CHANGELOG.md +85 -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 +851 -57
  9. package/__tests__/ActivityIndicator/ActivityIndicator.test.jsx +1 -1
  10. package/__tests__/Button/ButtonBase.test.jsx +2 -31
  11. package/__tests__/Button/ButtonGroup.test.jsx +6 -7
  12. package/__tests__/Checkbox/Checkbox.test.jsx +94 -0
  13. package/__tests__/Checkbox/CheckboxGroup.test.jsx +246 -0
  14. package/__tests__/ExpandCollapse/ExpandCollapse.test.jsx +2 -2
  15. package/__tests__/HorizontalScroll/HorizontalScroll.test.jsx +164 -0
  16. package/__tests__/Icon/Icon.test.jsx +3 -3
  17. package/__tests__/IconButton/IconButton.test.jsx +52 -0
  18. package/__tests__/InputSupports/InputSupports.test.jsx +50 -0
  19. package/__tests__/Link/LinkBase.test.jsx +0 -14
  20. package/__tests__/List/List.test.jsx +60 -0
  21. package/__tests__/Modal/Modal.test.jsx +47 -0
  22. package/__tests__/Notification/Notification.test.jsx +20 -0
  23. package/__tests__/Pagination/Pagination.test.jsx +2 -2
  24. package/__tests__/Progress/Progress.test.jsx +79 -0
  25. package/__tests__/Radio/Radio.test.jsx +87 -0
  26. package/__tests__/Radio/RadioGroup.test.jsx +220 -0
  27. package/__tests__/RadioCard/RadioCard.test.jsx +87 -0
  28. package/__tests__/RadioCard/RadioCardGroup.test.jsx +246 -0
  29. package/__tests__/Search/Search.test.jsx +73 -0
  30. package/__tests__/Select/Select.test.jsx +94 -0
  31. package/__tests__/Skeleton/Skeleton.test.jsx +61 -0
  32. package/__tests__/StepTracker/StepTracker.test.jsx +94 -0
  33. package/__tests__/Tabs/Tabs.test.jsx +40 -0
  34. package/__tests__/Tags/Tags.test.jsx +327 -0
  35. package/__tests__/TextInput/TextArea.test.jsx +35 -0
  36. package/__tests__/TextInput/{TextInput.test.jsx → TextInputBase.test.jsx} +29 -50
  37. package/__tests__/ThemeProvider/ThemeProvider.test.jsx +77 -0
  38. package/__tests__/ThemeProvider/useThemeTokens.test.jsx +9 -5
  39. package/__tests__/ThemeProvider/utils/theme-tokens.test.js +41 -0
  40. package/__tests__/ToggleSwitch/ToggleSwitch.test.jsx +3 -2
  41. package/__tests__/utils/children.test.jsx +128 -0
  42. package/__tests__/utils/input.test.js +59 -1
  43. package/__tests__/utils/semantics.test.jsx +43 -0
  44. package/__tests__/utils/useCopy.test.js +14 -3
  45. package/babel.config.js +20 -0
  46. package/jest.config.js +8 -3
  47. package/lib/A11yInfoProvider/index.js +54 -26
  48. package/lib/A11yText/index.js +45 -17
  49. package/lib/ActivityIndicator/Spinner.js +81 -0
  50. package/lib/ActivityIndicator/Spinner.native.js +129 -91
  51. package/lib/ActivityIndicator/index.js +28 -12
  52. package/lib/ActivityIndicator/shared.js +27 -12
  53. package/lib/BaseProvider/index.js +34 -11
  54. package/lib/Box/Box.js +152 -35
  55. package/lib/Box/index.js +13 -2
  56. package/lib/Button/Button.js +41 -12
  57. package/lib/Button/ButtonBase.js +125 -97
  58. package/lib/Button/ButtonGroup.js +112 -89
  59. package/lib/Button/ButtonLink.js +48 -17
  60. package/lib/Button/index.js +31 -4
  61. package/lib/Button/propTypes.js +32 -9
  62. package/lib/Card/Card.js +38 -41
  63. package/lib/Card/CardBase.js +85 -0
  64. package/lib/Card/PressableCardBase.js +141 -0
  65. package/lib/Card/index.js +40 -2
  66. package/lib/Checkbox/Checkbox.js +355 -0
  67. package/lib/Checkbox/CheckboxGroup.js +241 -0
  68. package/lib/Checkbox/CheckboxInput.js +74 -0
  69. package/lib/Checkbox/CheckboxInput.native.js +14 -0
  70. package/lib/Checkbox/index.js +21 -0
  71. package/lib/Divider/Divider.js +59 -28
  72. package/lib/Divider/index.js +13 -2
  73. package/lib/ExpandCollapse/Accordion.js +26 -7
  74. package/lib/ExpandCollapse/Control.js +60 -31
  75. package/lib/ExpandCollapse/ExpandCollapse.js +50 -28
  76. package/lib/ExpandCollapse/Panel.js +83 -44
  77. package/lib/ExpandCollapse/index.js +25 -7
  78. package/lib/Feedback/Feedback.js +90 -39
  79. package/lib/Feedback/index.js +13 -2
  80. package/lib/Fieldset/Fieldset.js +165 -0
  81. package/lib/Fieldset/FieldsetContainer.js +46 -0
  82. package/lib/Fieldset/FieldsetContainer.native.js +38 -0
  83. package/lib/Fieldset/Legend.js +38 -0
  84. package/lib/Fieldset/Legend.native.js +48 -0
  85. package/lib/Fieldset/cssReset.js +21 -0
  86. package/lib/Fieldset/index.js +13 -0
  87. package/lib/FlexGrid/Col/Col.js +73 -41
  88. package/lib/FlexGrid/Col/index.js +13 -2
  89. package/lib/FlexGrid/FlexGrid.js +99 -49
  90. package/lib/FlexGrid/Row/Row.js +58 -30
  91. package/lib/FlexGrid/Row/index.js +13 -2
  92. package/lib/FlexGrid/helpers/index.js +9 -1
  93. package/lib/FlexGrid/index.js +13 -2
  94. package/lib/FlexGrid/providers/GutterContext.js +15 -3
  95. package/lib/HorizontalScroll/HorizontalScroll.js +200 -0
  96. package/lib/HorizontalScroll/HorizontalScrollButton.js +127 -0
  97. package/lib/HorizontalScroll/ScrollViewEnd.js +66 -0
  98. package/lib/HorizontalScroll/ScrollViewEnd.native.js +41 -0
  99. package/lib/HorizontalScroll/dictionary.js +18 -0
  100. package/lib/HorizontalScroll/index.js +35 -0
  101. package/lib/HorizontalScroll/itemPositions.js +128 -0
  102. package/lib/Icon/Icon.js +62 -50
  103. package/lib/Icon/IconText.js +101 -0
  104. package/lib/Icon/index.js +31 -3
  105. package/lib/IconButton/IconButton.js +140 -0
  106. package/lib/IconButton/index.js +13 -0
  107. package/lib/InputLabel/InputLabel.js +102 -40
  108. package/lib/InputLabel/LabelContent.js +41 -0
  109. package/lib/InputLabel/LabelContent.native.js +32 -6
  110. package/lib/InputLabel/index.js +13 -2
  111. package/lib/InputSupports/InputSupports.js +109 -0
  112. package/lib/InputSupports/index.js +13 -0
  113. package/lib/InputSupports/propTypes.js +66 -0
  114. package/lib/InputSupports/useInputSupports.js +41 -0
  115. package/lib/Link/ChevronLink.js +58 -31
  116. package/lib/Link/InlinePressable.js +56 -0
  117. package/lib/Link/InlinePressable.native.js +102 -0
  118. package/lib/Link/Link.js +39 -15
  119. package/lib/Link/LinkBase.js +126 -150
  120. package/lib/Link/TextButton.js +53 -18
  121. package/lib/Link/index.js +39 -4
  122. package/lib/List/List.js +81 -0
  123. package/lib/List/ListItem.js +245 -0
  124. package/lib/List/index.js +13 -0
  125. package/lib/Modal/Modal.js +231 -0
  126. package/lib/Modal/dictionary.js +16 -0
  127. package/lib/Modal/index.js +13 -0
  128. package/lib/Notification/Notification.js +216 -0
  129. package/lib/Notification/dictionary.js +15 -0
  130. package/lib/Notification/index.js +13 -0
  131. package/lib/Pagination/PageButton.js +58 -48
  132. package/lib/Pagination/Pagination.js +78 -43
  133. package/lib/Pagination/SideButton.js +79 -58
  134. package/lib/Pagination/dictionary.js +9 -2
  135. package/lib/Pagination/index.js +13 -2
  136. package/lib/Pagination/usePagination.js +12 -2
  137. package/lib/Progress/Progress.js +104 -0
  138. package/lib/Progress/ProgressBar.js +157 -0
  139. package/lib/Progress/ProgressBarBackground.js +61 -0
  140. package/lib/Progress/index.js +16 -0
  141. package/lib/Radio/Radio.js +293 -0
  142. package/lib/Radio/RadioButton.js +152 -0
  143. package/lib/Radio/RadioGroup.js +244 -0
  144. package/lib/Radio/RadioInput.js +76 -0
  145. package/lib/Radio/RadioInput.native.js +14 -0
  146. package/lib/Radio/index.js +21 -0
  147. package/lib/RadioCard/RadioCard.js +244 -0
  148. package/lib/RadioCard/RadioCardGroup.js +252 -0
  149. package/lib/RadioCard/index.js +21 -0
  150. package/lib/Search/Search.js +254 -0
  151. package/lib/Search/dictionary.js +19 -0
  152. package/lib/Search/index.js +13 -0
  153. package/lib/Select/Group.js +33 -0
  154. package/lib/Select/Group.native.js +25 -0
  155. package/lib/Select/Item.js +29 -0
  156. package/lib/Select/Item.native.js +19 -0
  157. package/lib/Select/Picker.js +84 -0
  158. package/lib/Select/Picker.native.js +130 -0
  159. package/lib/Select/Select.js +342 -0
  160. package/lib/Select/index.js +19 -0
  161. package/lib/SideNav/Item.js +63 -37
  162. package/lib/SideNav/ItemContent.js +41 -15
  163. package/lib/SideNav/ItemsGroup.js +55 -31
  164. package/lib/SideNav/SideNav.js +100 -73
  165. package/lib/SideNav/index.js +15 -1
  166. package/lib/Skeleton/Skeleton.js +137 -0
  167. package/lib/Skeleton/index.js +13 -0
  168. package/lib/Skeleton/skeleton.constant.js +12 -0
  169. package/lib/Skeleton/skeletonWebAnimation.js +27 -0
  170. package/lib/Skeleton/useSkeletonNativeAnimation.js +37 -0
  171. package/lib/Spacer/Spacer.js +49 -18
  172. package/lib/Spacer/index.js +13 -2
  173. package/lib/StackView/StackView.js +71 -31
  174. package/lib/StackView/StackWrap.js +43 -13
  175. package/lib/StackView/StackWrap.native.js +13 -2
  176. package/lib/StackView/StackWrapBox.js +76 -29
  177. package/lib/StackView/StackWrapGap.js +56 -26
  178. package/lib/StackView/common.js +23 -6
  179. package/lib/StackView/getStackedContent.js +47 -17
  180. package/lib/StackView/index.js +29 -5
  181. package/lib/StepTracker/Step.js +245 -0
  182. package/lib/StepTracker/StepTracker.js +202 -0
  183. package/lib/StepTracker/dictionary.js +17 -0
  184. package/lib/StepTracker/index.js +13 -0
  185. package/lib/Tabs/Tabs.js +124 -0
  186. package/lib/Tabs/TabsItem.js +238 -0
  187. package/lib/Tabs/index.js +13 -0
  188. package/lib/Tags/Tags.js +266 -0
  189. package/lib/Tags/index.js +13 -0
  190. package/lib/TextInput/TextArea.js +111 -0
  191. package/lib/TextInput/TextInput.js +50 -304
  192. package/lib/TextInput/TextInputBase.js +256 -0
  193. package/lib/TextInput/index.js +23 -2
  194. package/lib/TextInput/propTypes.js +42 -0
  195. package/lib/ThemeProvider/ThemeProvider.js +46 -18
  196. package/lib/ThemeProvider/index.js +61 -6
  197. package/lib/ThemeProvider/useSetTheme.js +19 -5
  198. package/lib/ThemeProvider/useTheme.js +13 -4
  199. package/lib/ThemeProvider/useThemeTokens.js +86 -19
  200. package/lib/ThemeProvider/utils/index.js +31 -2
  201. package/lib/ThemeProvider/utils/styles.js +50 -14
  202. package/lib/ThemeProvider/utils/theme-tokens.js +121 -12
  203. package/lib/ToggleSwitch/ToggleSwitch.js +86 -57
  204. package/lib/ToggleSwitch/index.js +13 -2
  205. package/lib/Tooltip/{Backdrop.web.js → Backdrop.js} +20 -8
  206. package/lib/Tooltip/Backdrop.native.js +39 -15
  207. package/lib/Tooltip/Tooltip.js +117 -74
  208. package/lib/Tooltip/dictionary.js +9 -2
  209. package/lib/Tooltip/getTooltipPosition.js +9 -1
  210. package/lib/Tooltip/index.js +13 -2
  211. package/lib/TooltipButton/TooltipButton.js +57 -38
  212. package/lib/TooltipButton/index.js +13 -2
  213. package/lib/Typography/Typography.js +86 -55
  214. package/lib/Typography/index.js +13 -2
  215. package/lib/ViewportProvider/ViewportProvider.js +34 -13
  216. package/lib/ViewportProvider/index.js +28 -3
  217. package/lib/ViewportProvider/useViewport.js +15 -3
  218. package/lib/ViewportProvider/useViewportListener.js +24 -10
  219. package/lib/index.js +539 -26
  220. package/lib/utils/a11y/index.js +31 -0
  221. package/lib/utils/a11y/semantics.js +173 -0
  222. package/lib/utils/a11y/textSize.js +49 -0
  223. package/lib/utils/animation/index.js +15 -2
  224. package/lib/utils/animation/useVerticalExpandAnimation.js +27 -10
  225. package/lib/utils/children.js +134 -0
  226. package/lib/utils/index.js +163 -7
  227. package/lib/utils/info/index.js +19 -0
  228. package/lib/utils/info/platform/index.js +23 -0
  229. package/lib/utils/info/platform/platform.android.js +8 -0
  230. package/lib/utils/info/platform/platform.ios.js +8 -0
  231. package/lib/utils/info/platform/platform.js +8 -0
  232. package/lib/utils/info/platform/platform.native.js +11 -0
  233. package/lib/utils/info/versions.js +16 -0
  234. package/lib/utils/input.js +53 -25
  235. package/lib/utils/pressability.js +120 -0
  236. package/lib/utils/propTypes.js +338 -132
  237. package/lib/utils/useCopy.js +40 -5
  238. package/lib/utils/useHash.js +52 -0
  239. package/lib/utils/useHash.native.js +15 -0
  240. package/lib/utils/useResponsiveProp.js +21 -9
  241. package/lib/utils/useSpacingScale.js +19 -9
  242. package/lib/utils/useUniqueId.js +12 -3
  243. package/package.json +16 -10
  244. package/release-context.json +4 -4
  245. package/src/A11yText/index.jsx +6 -4
  246. package/src/ActivityIndicator/{Spinner.web.jsx → Spinner.jsx} +5 -3
  247. package/src/ActivityIndicator/Spinner.native.jsx +5 -3
  248. package/src/Box/Box.jsx +131 -39
  249. package/src/Button/Button.jsx +13 -6
  250. package/src/Button/ButtonBase.jsx +134 -125
  251. package/src/Button/ButtonGroup.jsx +85 -86
  252. package/src/Button/ButtonLink.jsx +22 -7
  253. package/src/Button/propTypes.js +12 -2
  254. package/src/Card/Card.jsx +5 -31
  255. package/src/Card/CardBase.jsx +58 -0
  256. package/src/Card/PressableCardBase.jsx +119 -0
  257. package/src/Card/index.js +3 -0
  258. package/src/Checkbox/Checkbox.jsx +284 -0
  259. package/src/Checkbox/CheckboxGroup.jsx +206 -0
  260. package/src/Checkbox/CheckboxInput.jsx +55 -0
  261. package/src/Checkbox/CheckboxInput.native.jsx +6 -0
  262. package/src/Checkbox/index.js +5 -0
  263. package/src/Divider/Divider.jsx +7 -4
  264. package/src/ExpandCollapse/Accordion.jsx +3 -2
  265. package/src/ExpandCollapse/Control.jsx +40 -43
  266. package/src/ExpandCollapse/ExpandCollapse.jsx +26 -23
  267. package/src/ExpandCollapse/Panel.jsx +69 -63
  268. package/src/Feedback/Feedback.jsx +42 -30
  269. package/src/Fieldset/Fieldset.jsx +136 -0
  270. package/src/Fieldset/FieldsetContainer.jsx +31 -0
  271. package/src/Fieldset/FieldsetContainer.native.jsx +19 -0
  272. package/src/Fieldset/Legend.jsx +21 -0
  273. package/src/Fieldset/Legend.native.jsx +27 -0
  274. package/src/Fieldset/cssReset.js +14 -0
  275. package/src/Fieldset/index.js +3 -0
  276. package/src/FlexGrid/Col/Col.jsx +139 -132
  277. package/src/FlexGrid/FlexGrid.jsx +79 -51
  278. package/src/FlexGrid/Row/Row.jsx +55 -48
  279. package/src/HorizontalScroll/HorizontalScroll.jsx +168 -0
  280. package/src/HorizontalScroll/HorizontalScrollButton.jsx +105 -0
  281. package/src/HorizontalScroll/ScrollViewEnd.jsx +53 -0
  282. package/src/HorizontalScroll/ScrollViewEnd.native.jsx +24 -0
  283. package/src/HorizontalScroll/dictionary.js +11 -0
  284. package/src/HorizontalScroll/index.js +17 -0
  285. package/src/HorizontalScroll/itemPositions.js +101 -0
  286. package/src/Icon/Icon.jsx +46 -49
  287. package/src/Icon/IconText.jsx +68 -0
  288. package/src/Icon/index.js +3 -2
  289. package/src/IconButton/IconButton.jsx +114 -0
  290. package/src/IconButton/index.js +3 -0
  291. package/src/InputLabel/InputLabel.jsx +57 -35
  292. package/src/InputLabel/LabelContent.jsx +21 -0
  293. package/src/InputLabel/LabelContent.native.jsx +11 -2
  294. package/src/InputSupports/InputSupports.jsx +70 -0
  295. package/src/InputSupports/index.js +3 -0
  296. package/src/InputSupports/propTypes.js +44 -0
  297. package/src/InputSupports/useInputSupports.js +30 -0
  298. package/src/Link/ChevronLink.jsx +34 -21
  299. package/src/Link/InlinePressable.jsx +39 -0
  300. package/src/Link/InlinePressable.native.jsx +75 -0
  301. package/src/Link/Link.jsx +23 -13
  302. package/src/Link/LinkBase.jsx +98 -170
  303. package/src/Link/TextButton.jsx +37 -16
  304. package/src/Link/index.js +2 -1
  305. package/src/List/List.jsx +48 -0
  306. package/src/List/ListItem.jsx +182 -0
  307. package/src/List/index.js +3 -0
  308. package/src/Modal/Modal.jsx +190 -0
  309. package/src/Modal/dictionary.js +9 -0
  310. package/src/Modal/index.js +3 -0
  311. package/src/Notification/Notification.jsx +164 -0
  312. package/src/Notification/dictionary.js +8 -0
  313. package/src/Notification/index.js +3 -0
  314. package/src/Pagination/PageButton.jsx +42 -49
  315. package/src/Pagination/Pagination.jsx +88 -92
  316. package/src/Pagination/SideButton.jsx +58 -66
  317. package/src/Progress/Progress.jsx +78 -0
  318. package/src/Progress/ProgressBar.jsx +123 -0
  319. package/src/Progress/ProgressBarBackground.jsx +36 -0
  320. package/src/Progress/index.js +6 -0
  321. package/src/Radio/Radio.jsx +240 -0
  322. package/src/Radio/RadioButton.jsx +142 -0
  323. package/src/Radio/RadioGroup.jsx +209 -0
  324. package/src/Radio/RadioInput.jsx +57 -0
  325. package/src/Radio/RadioInput.native.jsx +6 -0
  326. package/src/Radio/index.js +5 -0
  327. package/src/RadioCard/RadioCard.jsx +198 -0
  328. package/src/RadioCard/RadioCardGroup.jsx +218 -0
  329. package/src/RadioCard/index.js +5 -0
  330. package/src/Search/Search.jsx +225 -0
  331. package/src/Search/dictionary.js +12 -0
  332. package/src/Search/index.js +3 -0
  333. package/src/Select/Group.jsx +15 -0
  334. package/src/Select/Group.native.jsx +14 -0
  335. package/src/Select/Item.jsx +11 -0
  336. package/src/Select/Item.native.jsx +10 -0
  337. package/src/Select/Picker.jsx +74 -0
  338. package/src/Select/Picker.native.jsx +102 -0
  339. package/src/Select/Select.jsx +298 -0
  340. package/src/Select/index.js +8 -0
  341. package/src/SideNav/Item.jsx +54 -47
  342. package/src/SideNav/ItemsGroup.jsx +50 -43
  343. package/src/SideNav/SideNav.jsx +68 -60
  344. package/src/Skeleton/Skeleton.jsx +94 -0
  345. package/src/Skeleton/index.js +3 -0
  346. package/src/Skeleton/skeleton.constant.js +3 -0
  347. package/src/Skeleton/skeletonWebAnimation.js +13 -0
  348. package/src/Skeleton/useSkeletonNativeAnimation.js +27 -0
  349. package/src/Spacer/Spacer.jsx +11 -4
  350. package/src/StackView/StackView.jsx +53 -23
  351. package/src/StackView/StackWrap.jsx +16 -7
  352. package/src/StackView/StackWrapBox.jsx +62 -28
  353. package/src/StackView/StackWrapGap.jsx +46 -24
  354. package/src/StackView/common.jsx +3 -2
  355. package/src/StackView/getStackedContent.jsx +8 -2
  356. package/src/StepTracker/Step.jsx +202 -0
  357. package/src/StepTracker/StepTracker.jsx +174 -0
  358. package/src/StepTracker/dictionary.js +10 -0
  359. package/src/StepTracker/index.js +3 -0
  360. package/src/Tabs/Tabs.jsx +97 -0
  361. package/src/Tabs/TabsItem.jsx +212 -0
  362. package/src/Tabs/index.js +3 -0
  363. package/src/Tags/Tags.jsx +219 -0
  364. package/src/Tags/index.js +3 -0
  365. package/src/TextInput/TextArea.jsx +79 -0
  366. package/src/TextInput/TextInput.jsx +18 -284
  367. package/src/TextInput/TextInputBase.jsx +217 -0
  368. package/src/TextInput/index.js +2 -1
  369. package/src/TextInput/propTypes.js +29 -0
  370. package/src/ThemeProvider/ThemeProvider.jsx +11 -7
  371. package/src/ThemeProvider/useSetTheme.js +4 -0
  372. package/src/ThemeProvider/useThemeTokens.js +56 -5
  373. package/src/ThemeProvider/utils/styles.js +18 -5
  374. package/src/ThemeProvider/utils/theme-tokens.js +74 -5
  375. package/src/ToggleSwitch/ToggleSwitch.jsx +51 -53
  376. package/src/Tooltip/{Backdrop.web.jsx → Backdrop.jsx} +0 -0
  377. package/src/Tooltip/Tooltip.jsx +135 -131
  378. package/src/TooltipButton/TooltipButton.jsx +23 -27
  379. package/src/Typography/Typography.jsx +72 -59
  380. package/src/index.js +31 -3
  381. package/src/utils/a11y/index.js +2 -0
  382. package/src/utils/a11y/semantics.js +162 -0
  383. package/src/utils/a11y/textSize.js +30 -0
  384. package/src/utils/children.jsx +119 -0
  385. package/src/utils/index.js +6 -0
  386. package/src/utils/info/index.js +8 -0
  387. package/src/utils/info/platform/index.js +11 -0
  388. package/src/utils/info/platform/platform.android.js +1 -0
  389. package/src/utils/info/platform/platform.ios.js +1 -0
  390. package/src/utils/info/platform/platform.js +1 -0
  391. package/src/utils/info/platform/platform.native.js +4 -0
  392. package/src/utils/info/versions.js +6 -0
  393. package/src/utils/input.js +36 -25
  394. package/src/utils/pressability.js +96 -0
  395. package/src/utils/propTypes.js +291 -90
  396. package/src/utils/useCopy.js +30 -4
  397. package/src/utils/useHash.js +39 -0
  398. package/src/utils/useHash.native.js +6 -0
  399. package/stories/A11yText/A11yText.stories.jsx +6 -10
  400. package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +1 -1
  401. package/stories/Box/Box.stories.jsx +1 -1
  402. package/stories/Button/Button.stories.jsx +7 -2
  403. package/stories/Button/ButtonGroup.stories.jsx +1 -1
  404. package/stories/Button/ButtonLink.stories.jsx +1 -1
  405. package/stories/Card/Card.stories.jsx +1 -1
  406. package/stories/Checkbox/Checkbox.stories.jsx +94 -0
  407. package/stories/Divider/Divider.stories.jsx +1 -1
  408. package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +2 -2
  409. package/stories/Feedback/Feedback.stories.jsx +5 -6
  410. package/stories/FlexGrid/01 FlexGrid.stories.jsx +1 -1
  411. package/stories/FlexGrid/02 Row.stories.jsx +1 -1
  412. package/stories/FlexGrid/03 Col.stories.jsx +1 -1
  413. package/stories/Icon/Icon.stories.jsx +27 -7
  414. package/stories/IconButton/IconButton.stories.jsx +50 -0
  415. package/stories/InputLabel/InputLabel.stories.jsx +1 -1
  416. package/stories/Link/ChevronLink.stories.jsx +1 -1
  417. package/stories/Link/Link.stories.jsx +28 -18
  418. package/stories/Link/TextButton.stories.jsx +1 -1
  419. package/stories/List/List.stories.jsx +117 -0
  420. package/stories/Modal/Modal.stories.jsx +29 -0
  421. package/stories/Notification/Notification.stories.jsx +82 -0
  422. package/stories/Pagination/Pagination.stories.jsx +1 -1
  423. package/stories/Progress/Progress.stories.jsx +93 -0
  424. package/stories/Radio/Radio.stories.jsx +100 -0
  425. package/stories/RadioCard/RadioCard.stories.jsx +98 -0
  426. package/stories/Search/Search.stories.jsx +16 -0
  427. package/stories/Select/Select.stories.jsx +55 -0
  428. package/stories/SideNav/SideNav.stories.jsx +1 -1
  429. package/stories/SideNav/SideNavItem.stories.jsx +1 -1
  430. package/stories/SideNav/SideNavItemsGroup.stories.jsx +1 -1
  431. package/stories/Skeleton/Skeleton.stories.jsx +36 -0
  432. package/stories/Spacer/Spacer.stories.jsx +1 -1
  433. package/stories/StackView/StackView.stories.jsx +1 -1
  434. package/stories/StackView/StackWrap.stories.jsx +1 -1
  435. package/stories/StepTracker/StepTracker.stories.jsx +71 -0
  436. package/stories/Tabs/Tabs.stories.jsx +97 -0
  437. package/stories/Tags/Tags.stories.jsx +69 -0
  438. package/stories/TextInput/TextArea.stories.jsx +100 -0
  439. package/stories/TextInput/TextInput.stories.jsx +1 -1
  440. package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +1 -1
  441. package/stories/Tooltip/Tooltip.stories.jsx +1 -1
  442. package/stories/TooltipButton/TooltipButton.stories.jsx +1 -1
  443. package/stories/Typography/Typography.stories.jsx +1 -1
  444. package/stories/{platform-supports.web.jsx → platform-supports.jsx} +1 -1
  445. package/stories/supports.jsx +38 -4
  446. package/__fixtures__/accessible.icon.svg +0 -6
  447. package/babel.config.json +0 -8
  448. package/docs/Contributing.stories.mdx +0 -9
  449. package/docs/Fonts.stories.mdx +0 -104
  450. package/docs/Icons.stories.mdx +0 -144
  451. package/docs/Introduction.stories.mdx +0 -9
  452. package/lib/ActivityIndicator/Spinner.web.js +0 -55
  453. package/lib/InputLabel/LabelContent.web.js +0 -17
  454. package/lib/config/svgr-icons-web.js +0 -9
  455. package/lib/config/svgr-icons.js +0 -52
  456. package/src/InputLabel/LabelContent.web.jsx +0 -13
  457. package/src/config/svgr-icons-web.js +0 -11
  458. package/src/config/svgr-icons.js +0 -46
@@ -1,13 +1,17 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { View } from 'react-native'
4
4
 
5
5
  import {
6
6
  spacingProps,
7
7
  a11yProps,
8
+ getTokensPropType,
8
9
  responsiveProps,
9
10
  useSpacingScale,
10
- useResponsiveProp
11
+ useResponsiveProp,
12
+ viewProps,
13
+ getA11yPropsFromHtmlTag,
14
+ layoutTags
11
15
  } from '../utils'
12
16
  import { useThemeTokens } from '../ThemeProvider'
13
17
  import { useViewport } from '../ViewportProvider'
@@ -41,36 +45,53 @@ const spaceSides = {
41
45
  * Unlike the cleaner and more side-effect-free CSS gap StackWrap implementation, this renders a Box (View)
42
46
  * between the container and the stacked children, and requires a negative margin on the container.
43
47
  */
44
- const StackWrapBox = ({
45
- space = 1,
46
- gap = space,
47
- direction: directionProp = 'row',
48
- children,
49
- tokens,
50
- variant,
51
- ...rest
52
- }) => {
53
- const viewport = useViewport()
54
- const direction = useResponsiveProp(directionProp, 'row')
55
- const themeTokens = useThemeTokens('StackView', tokens, variant, { viewport })
56
- const flexStyles = selectFlexStyles(themeTokens)
57
- const a11y = a11yProps.select({ ...rest })
48
+ const StackWrapBox = forwardRef(
49
+ (
50
+ {
51
+ space = 1,
52
+ gap = space,
53
+ direction: directionProp = 'row',
54
+ children,
55
+ tokens,
56
+ variant,
57
+ tag,
58
+ accessibilityRole,
59
+ ...rest
60
+ },
61
+ ref
62
+ ) => {
63
+ const viewport = useViewport()
64
+ const direction = useResponsiveProp(directionProp, 'row')
65
+ const themeTokens = useThemeTokens('StackView', tokens, variant, { viewport })
66
+ const flexStyles = selectFlexStyles(themeTokens)
67
+ const props = {
68
+ ...getA11yPropsFromHtmlTag(tag, accessibilityRole),
69
+ ...a11yProps.select(rest),
70
+ ...viewProps.select(rest)
71
+ }
58
72
 
59
- // Mimic CSS `gap` using box spacing on the side after a wrapped row then offsetting it on the last row.
60
- const gapSize = useSpacingScale(gap)
61
- const offsetStyle = { [offsetSides[direction]]: -1 * gapSize }
62
- const boxProps = { [gapSides[direction]]: gap, [spaceSides[direction]]: space }
63
- const content = getStackedContent(children, { direction, space: 0, box: boxProps })
73
+ // Mimic CSS `gap` using box spacing on the side after a wrapped row then offsetting it on the last row.
74
+ const gapSize = useSpacingScale(gap)
75
+ const offsetStyle = { [offsetSides[direction]]: -1 * gapSize }
76
+ const boxProps = { [gapSides[direction]]: gap, [spaceSides[direction]]: space }
77
+ const content = getStackedContent(children, { direction, space: 0, box: boxProps })
64
78
 
65
- return (
66
- <View {...a11y} style={[flexStyles, staticStyles.wrap, staticStyles[direction], offsetStyle]}>
67
- {content}
68
- </View>
69
- )
70
- }
79
+ return (
80
+ <View
81
+ ref={ref}
82
+ {...props}
83
+ style={[flexStyles, staticStyles.wrap, staticStyles[direction], offsetStyle]}
84
+ >
85
+ {content}
86
+ </View>
87
+ )
88
+ }
89
+ )
90
+ StackWrapBox.displayName = 'StackWrapBox'
71
91
 
72
92
  StackWrapBox.propTypes = {
73
93
  ...a11yProps.propTypes,
94
+ tokens: getTokensPropType('StackView'),
74
95
  /**
75
96
  * Sets the `flexDirection` of the container
76
97
  */
@@ -78,11 +99,24 @@ StackWrapBox.propTypes = {
78
99
  PropTypes.oneOf(['column', 'row', 'row-reverse', 'column-reverse'])
79
100
  ),
80
101
  /**
81
- * The size of the spacer according to the theme's spacing scale.
102
+ * The size of the space between items according to the theme's spacing scale.
82
103
  * Either a number corresponding to a position on the theme's spacing scale (1 is smallest, 2 is second smallest, etc),
83
104
  * or, a SpacingObject with viewport keys and options (see `useSpacingScale` for details).
84
105
  */
85
106
  space: spacingProps.types.spacingValue,
107
+ /**
108
+ * The size of the space between lines of content, according to the theme's spacing scale. By default, matches `space`.
109
+ * Either a number corresponding to a position on the theme's spacing scale (1 is smallest, 2 is second smallest, etc),
110
+ * or, a SpacingObject with viewport keys and options (see `useSpacingScale` for details).
111
+ */
112
+ gap: spacingProps.types.spacingValue,
113
+ /**
114
+ * Optional semantic HTML tag, to apply to the container on web. Does not change styling.
115
+ *
116
+ * In native apps, if a header tag is provided ("h1", "h2" etc) and accessibilityRole prop
117
+ * is not defined, the accessibilityRole will default to "heading".
118
+ */
119
+ tag: PropTypes.oneOf(layoutTags),
86
120
  /**
87
121
  * A StackWrap may take any children, but will have no effect if it is only passed one child or is passed children
88
122
  * wrapped in a component. If necessary, children may be wrapped in one React Fragment.
@@ -1,8 +1,14 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import { View } from 'react-native'
3
3
 
4
4
  import StackWrapBox from './StackWrapBox'
5
- import { a11yProps, useSpacingScale, useResponsiveProp } from '../utils'
5
+ import {
6
+ a11yProps,
7
+ useSpacingScale,
8
+ useResponsiveProp,
9
+ viewProps,
10
+ getA11yPropsFromHtmlTag
11
+ } from '../utils'
6
12
  import { useThemeTokens } from '../ThemeProvider'
7
13
  import { useViewport } from '../ViewportProvider'
8
14
  import getStackedContent from './getStackedContent'
@@ -18,31 +24,47 @@ import { staticStyles, selectFlexStyles } from './common'
18
24
  * - The `space` between items is the same as the `gap` between wrapped rows (this is the
19
25
  * default if `gap` prop is undefined)
20
26
  */
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 })
32
- const flexStyles = selectFlexStyles(themeTokens)
33
- const a11y = a11yProps.select({ ...rest })
27
+ const StackWrapGap = forwardRef(
28
+ (
29
+ {
30
+ space = 1,
31
+ tokens,
32
+ variant,
33
+ direction: directionProp = 'row',
34
+ children,
35
+ tag,
36
+ accessibilityRole,
37
+ ...rest
38
+ },
39
+ ref
40
+ ) => {
41
+ const viewport = useViewport()
42
+ const direction = useResponsiveProp(directionProp, 'row')
43
+ const themeTokens = useThemeTokens('StackView', tokens, variant, { viewport })
44
+ const flexStyles = selectFlexStyles(themeTokens)
45
+ const props = {
46
+ ...getA11yPropsFromHtmlTag(tag, accessibilityRole),
47
+ ...a11yProps.select(rest),
48
+ ...viewProps.select(rest)
49
+ }
34
50
 
35
- const size = useSpacingScale(space)
36
- const gapStyle = { gap: size }
51
+ const size = useSpacingScale(space)
52
+ const gapStyle = { gap: size }
37
53
 
38
- const content = getStackedContent(children, { direction, space: 0 })
54
+ const content = getStackedContent(children, { direction, space: 0 })
39
55
 
40
- return (
41
- <View {...a11y} style={[flexStyles, staticStyles.wrap, staticStyles[direction], gapStyle]}>
42
- {content}
43
- </View>
44
- )
45
- }
56
+ return (
57
+ <View
58
+ ref={ref}
59
+ {...props}
60
+ style={[flexStyles, staticStyles.wrap, staticStyles[direction], gapStyle]}
61
+ >
62
+ {content}
63
+ </View>
64
+ )
65
+ }
66
+ )
67
+ StackWrapGap.displayName = 'StackWrapGap'
46
68
 
47
69
  StackWrapGap.propTypes = StackWrapBox.propTypes
48
70
 
@@ -1,9 +1,10 @@
1
1
  import { StyleSheet } from 'react-native'
2
2
 
3
- export const selectFlexStyles = ({ alignItems, justifyContent, flexGrow }) => ({
3
+ export const selectFlexStyles = ({ alignItems, justifyContent, flexGrow, flexShrink }) => ({
4
4
  alignItems,
5
5
  justifyContent,
6
- flexGrow
6
+ flexGrow,
7
+ flexShrink
7
8
  })
8
9
 
9
10
  export const staticStyles = StyleSheet.create({
@@ -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
+ })
@@ -0,0 +1,174 @@
1
+ import React, { forwardRef } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { StyleSheet, Text, View } from 'react-native'
4
+
5
+ import StackView from '../StackView'
6
+ import { applyTextStyles, useThemeTokens } from '../ThemeProvider'
7
+ import { getTokensPropType, variantProp } from '../utils'
8
+ import { a11yProps } from '../utils/propTypes'
9
+ import { useViewport } from '../ViewportProvider'
10
+ import useCopy from '../utils/useCopy'
11
+
12
+ import Step from './Step'
13
+ import defaultDictionary from './dictionary'
14
+
15
+ const selectContainerStyles = ({
16
+ containerPaddingBottom,
17
+ containerPaddingLeft,
18
+ containerPaddingRight,
19
+ containerPaddingTop
20
+ }) => ({
21
+ paddingBottom: containerPaddingBottom,
22
+ paddingLeft: containerPaddingLeft,
23
+ paddingRight: containerPaddingRight,
24
+ paddingTop: containerPaddingTop
25
+ })
26
+ const selectStepTrackerLabelContainerStyles = ({ labelMarginTop }) => ({
27
+ marginTop: labelMarginTop
28
+ })
29
+ const selectStepTrackerLabelStyles = ({
30
+ labelColor,
31
+ labelFontSize,
32
+ labelFontWeight,
33
+ labelFontName,
34
+ labelLineHeight
35
+ }) =>
36
+ applyTextStyles({
37
+ color: labelColor,
38
+ fontSize: labelFontSize,
39
+ lineHeight: labelLineHeight,
40
+ fontWeight: labelFontWeight,
41
+ fontName: labelFontName
42
+ })
43
+
44
+ /**
45
+ * StepTracker component shows the current position in a sequence of steps.
46
+ *
47
+ * ## Component API
48
+ *
49
+ * - `current` prop allows to control the current step, 0-based number;
50
+ * - use `copy` and `dictionary` props to internationalize the labels;
51
+ * - `steps` is and array of strings defining step titles;
52
+ * - tokens and variant props define the appearance of the `StepTracker`:
53
+ *
54
+ * ## Usability and A11y guidelines
55
+ *
56
+ * Keep in mind that in its current implementation this is not an interactive
57
+ * component and can’t be used to navigate between steps. The application
58
+ * must provide its own navigation mechanism and state control. That is the
59
+ * main reason the component assumes the `progressbar` role in terms of
60
+ * accessibility. This also makes it extremely important to make sure you
61
+ * set a11y on controls used to modify the state of the step tracker.
62
+ *
63
+ * You can pass standard a11y props to the `StepTracker` component, including
64
+ * the ones that are specific to the `progressbar` role. By default the
65
+ * following props are used:
66
+ *
67
+ * - `accessibilityRole` (`role`): `progressbar`,
68
+ * - `accessibilityLabel` (`aria-label`): `Step I of N: <Current Step Label>`,
69
+ * - `accessibilityLevel` (`aria-level`): 1,
70
+ * - `accessibilityValue.min` (`aria-valuemin`): `0`,
71
+ * - `accessibilityValue.max` (`aria-valuemax`): `steps.length - 1`,
72
+ * - `accessibilityValue.now` (`aria-valuenow`): `current`,
73
+ * - `accessibilityValue.text` (`aria-valuetext`): `<Current Step Label>`,
74
+ *
75
+ */
76
+ const StepTracker = forwardRef(
77
+ (
78
+ {
79
+ current = 0,
80
+ copy = 'en',
81
+ dictionary = defaultDictionary,
82
+ steps = [],
83
+ tokens,
84
+ variant,
85
+ ...rest
86
+ },
87
+ ref
88
+ ) => {
89
+ const viewport = useViewport()
90
+ const { showStepTrackerLabel, ...themeTokens } = useThemeTokens(
91
+ 'StepTracker',
92
+ tokens,
93
+ variant,
94
+ {
95
+ viewport
96
+ }
97
+ )
98
+ const getCopy = useCopy({ dictionary, copy })
99
+ const stepTrackerLabel = getCopy('stepTrackerLabel')
100
+ .replace('%{stepNumber}', current < steps.length ? current + 1 : steps.length)
101
+ .replace('%{stepCount}', steps.length)
102
+ .replace('%{stepLabel}', current < steps.length ? steps[current] : steps[steps.length - 1])
103
+ if (!steps.length) return null
104
+ const accessibilityProps = {
105
+ accessibilityLabel: stepTrackerLabel,
106
+ accessibilityLevel: 1,
107
+ accessibilityRole: 'progressbar',
108
+ accessibilityValue: {
109
+ min: 0,
110
+ max: steps.length - 1,
111
+ now: current,
112
+ text: steps[current]
113
+ },
114
+ ...a11yProps.select(rest)
115
+ }
116
+
117
+ return (
118
+ <View ref={ref} style={selectContainerStyles(themeTokens)} {...accessibilityProps}>
119
+ <StackView space={0}>
120
+ <View style={staticStyles.stepsContainer}>
121
+ {steps.map((label, index) => {
122
+ return (
123
+ <Step
124
+ status={current}
125
+ key={label}
126
+ label={label}
127
+ name={getCopy('stepLabel').replace('%{stepNumber}', index + 1)}
128
+ stepIndex={index}
129
+ stepCount={steps.length}
130
+ tokens={themeTokens}
131
+ />
132
+ )
133
+ })}
134
+ </View>
135
+ {showStepTrackerLabel && (
136
+ <View
137
+ style={[
138
+ staticStyles.stepTrackerLabelContainer,
139
+ selectStepTrackerLabelContainerStyles(themeTokens)
140
+ ]}
141
+ >
142
+ <Text style={selectStepTrackerLabelStyles(themeTokens)}>{stepTrackerLabel}</Text>
143
+ </View>
144
+ )}
145
+ </StackView>
146
+ </View>
147
+ )
148
+ }
149
+ )
150
+ StepTracker.displayName = 'StepTracker'
151
+
152
+ StepTracker.propTypes = {
153
+ current: PropTypes.number,
154
+ copy: PropTypes.oneOf(['en', 'fr']),
155
+ dictionary: PropTypes.shape({
156
+ en: PropTypes.shape({ stepLabel: PropTypes.string, stepTrackerLabel: PropTypes.string }),
157
+ fr: PropTypes.shape({ stepLabel: PropTypes.string, stepTrackerLabel: PropTypes.string })
158
+ }),
159
+ steps: PropTypes.arrayOf(PropTypes.string),
160
+ tokens: getTokensPropType('StepTracker'),
161
+ variant: variantProp.propType
162
+ }
163
+
164
+ export default StepTracker
165
+
166
+ const staticStyles = StyleSheet.create({
167
+ stepsContainer: {
168
+ alignItems: 'flex-start',
169
+ flexDirection: 'row',
170
+ justifyContent: 'space-evenly',
171
+ flexGrow: 1
172
+ },
173
+ stepTrackerLabelContainer: { textAlign: 'center', flexDirection: 'row', justifyContent: 'center' }
174
+ })
@@ -0,0 +1,10 @@
1
+ export default {
2
+ en: {
3
+ stepLabel: 'Step %{stepNumber}',
4
+ stepTrackerLabel: 'Step %{stepNumber} of %{stepCount}: %{stepLabel}'
5
+ },
6
+ fr: {
7
+ stepLabel: 'Étape %{stepNumber}',
8
+ stepTrackerLabel: 'Étape %{stepNumber} sur %{stepCount}: %{stepLabel}'
9
+ }
10
+ }
@@ -0,0 +1,3 @@
1
+ import StepTracker from './StepTracker'
2
+
3
+ export default StepTracker