@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,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { Text, Platform, StyleSheet } from 'react-native'
4
4
  import {
@@ -11,27 +11,28 @@ import {
11
11
  import { resolvePressableTokens } from '../utils/pressability'
12
12
 
13
13
  import InlinePressable from './InlinePressable'
14
- import { applyTextStyles } from '../ThemeProvider'
14
+ import { applyTextStyles, applyOuterBorder } from '../ThemeProvider'
15
15
  import { IconText, iconComponentPropTypes } from '../Icon'
16
16
 
17
17
  const selectOuterBorderStyles = ({
18
18
  outerBorderColor,
19
19
  outerBorderWidth,
20
20
  outerBorderGap,
21
- outerBorderRadius,
21
+ borderRadius,
22
22
  outerBorderOutline
23
23
  }) =>
24
24
  // A view wrapper with a border on native messes up inline text alignment
25
25
  // so for now make focus styles strictly web-only
26
26
  Platform.OS === 'web'
27
27
  ? {
28
- margin: -1 * (outerBorderGap + outerBorderWidth) || 0,
29
- padding: outerBorderGap,
30
28
  // Allow theme to define outline, or, turn off outline and use border if rounded corners required
31
29
  outline: outerBorderOutline,
32
- borderWidth: outerBorderWidth,
33
- borderColor: outerBorderColor,
34
- borderRadius: outerBorderRadius,
30
+ ...applyOuterBorder({
31
+ outerBorderColor,
32
+ outerBorderWidth,
33
+ outerBorderGap,
34
+ borderRadius
35
+ }),
35
36
  // Stops focus ring stretching horizontally if parent has display: block
36
37
  // width: fit-content isn't supported on Firefox; can't cascade props like CSS `width: fit-content; width: --moz-fit-content;`
37
38
  display: 'inline-flex'
@@ -87,68 +88,78 @@ const selectIconTokens = ({ color, iconSize, iconTranslateX, iconTranslateY }) =
87
88
  * dropped in favour of investigating if a full-featured CSS-in-JS package could or
88
89
  * should be used more widely (e.g. styled components)
89
90
  */
90
- const LinkBase = ({
91
- href,
92
- onPress,
93
- icon,
94
- iconPosition = icon ? 'left' : undefined,
95
- iconProps,
96
- variant,
97
- tokens = {},
98
- children,
99
- accessibilityRole = 'link',
100
- ...props
101
- }) => {
102
- const { hrefAttrs, rest } = hrefAttrsProp.bundle(props)
103
- const linkPropSet = linkProps.select({
104
- accessibilityRole,
105
- href,
106
- onPress: linkProps.handleHref({ href, onPress }),
107
- ...hrefAttrsProp.spread(hrefAttrs),
108
- ...rest
109
- })
91
+ const LinkBase = forwardRef(
92
+ (
93
+ {
94
+ href,
95
+ onPress,
96
+ icon,
97
+ iconPosition = icon ? 'left' : undefined,
98
+ iconProps,
99
+ variant,
100
+ tokens = {},
101
+ children,
102
+ accessibilityRole = 'link',
103
+ dataSet,
104
+ ...props
105
+ },
106
+ ref
107
+ ) => {
108
+ const { hrefAttrs, rest } = hrefAttrsProp.bundle(props)
109
+ const linkPropSet = linkProps.select({
110
+ accessibilityRole,
111
+ href,
112
+ onPress: linkProps.handleHref({ href, onPress }),
113
+ hrefAttrs,
114
+ ...rest
115
+ })
110
116
 
111
- const resolveTokens = (pressState) => resolvePressableTokens(tokens, pressState, { iconPosition })
117
+ const resolveLinkTokens = (pressState) =>
118
+ resolvePressableTokens(tokens, pressState, { iconPosition })
112
119
 
113
- // On web, this makes focus rings wrap only the link, not the entire block
114
- const blockLeftStyle = Platform.OS === 'web' && staticStyles.blockLeft
120
+ // On web, this makes focus rings wrap only the link, not the entire block
121
+ const blockLeftStyle = Platform.OS === 'web' && staticStyles.blockLeft
115
122
 
116
- return (
117
- <InlinePressable
118
- {...linkPropSet}
119
- style={(linkState) => {
120
- const themeTokens = resolveTokens(linkState)
121
- const outerBorderStyles = selectOuterBorderStyles(themeTokens)
122
- const hasIcon = Boolean(icon || themeTokens.icon)
123
- return [outerBorderStyles, blockLeftStyle, hasIcon && staticStyles.rowContainer]
124
- }}
125
- >
126
- {(linkState) => {
127
- const themeTokens = resolveTokens(linkState)
128
- const textStyles = selectTextStyles(themeTokens)
129
- const iconTokens = selectIconTokens(themeTokens)
123
+ return (
124
+ <InlinePressable
125
+ {...linkPropSet}
126
+ ref={ref}
127
+ dataSet={dataSet}
128
+ style={(linkState) => {
129
+ const themeTokens = resolveLinkTokens(linkState)
130
+ const outerBorderStyles = selectOuterBorderStyles(themeTokens)
131
+ const hasIcon = Boolean(icon || themeTokens.icon)
132
+ return [outerBorderStyles, blockLeftStyle, hasIcon && staticStyles.rowContainer]
133
+ }}
134
+ >
135
+ {(linkState) => {
136
+ const themeTokens = resolveLinkTokens(linkState)
137
+ const textStyles = selectTextStyles(themeTokens)
138
+ const iconTokens = selectIconTokens(themeTokens)
130
139
 
131
- // TODO: may need to apply some smarter text inheritance here if inline to avoid native
132
- // issues like double-application of line heights breaking align-items: baseline
133
- const blockTextStyles = selectBlockStyles(themeTokens)
140
+ // TODO: may need to apply some smarter text inheritance here if inline to avoid native
141
+ // issues like double-application of line heights breaking align-items: baseline
142
+ const blockTextStyles = selectBlockStyles(themeTokens)
134
143
 
135
- const IconComponent = icon || themeTokens.icon
136
- const { iconSpace } = themeTokens
144
+ const IconComponent = icon || themeTokens.icon
145
+ const { iconSpace } = themeTokens
137
146
 
138
- return (
139
- <IconText
140
- icon={IconComponent}
141
- iconPosition={iconPosition}
142
- space={iconSpace}
143
- iconProps={{ ...iconProps, tokens: iconTokens }}
144
- >
145
- <Text style={[textStyles, blockTextStyles, staticStyles.baseline]}>{children}</Text>
146
- </IconText>
147
- )
148
- }}
149
- </InlinePressable>
150
- )
151
- }
147
+ return (
148
+ <IconText
149
+ icon={IconComponent}
150
+ iconPosition={iconPosition}
151
+ space={iconSpace}
152
+ iconProps={{ ...iconProps, tokens: iconTokens }}
153
+ >
154
+ <Text style={[textStyles, blockTextStyles, staticStyles.baseline]}>{children}</Text>
155
+ </IconText>
156
+ )
157
+ }}
158
+ </InlinePressable>
159
+ )
160
+ }
161
+ )
162
+ LinkBase.displayName = 'LinkBase'
152
163
 
153
164
  LinkBase.propTypes = {
154
165
  ...a11yProps.types,
@@ -170,7 +181,7 @@ LinkBase.propTypes = {
170
181
  iconPosition: PropTypes.oneOf(['left', 'right']),
171
182
  /**
172
183
  * On Web if href is passed, React Native Web maps this object's props to
173
- * `rel`, `target` and (>= RNW 0.15.0) `download` attrs.
184
+ * `rel`, `target` and `download` attrs.
174
185
  */
175
186
  hrefAttrs: PropTypes.shape(hrefAttrsProp.types)
176
187
  }
@@ -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 { useThemeTokensCallback } from '../ThemeProvider'
@@ -9,28 +9,35 @@ import LinkBase from './LinkBase'
9
9
  * Link but has the accessibility role of a `Button`. It should be used for actions that
10
10
  * take place on the current page, or for navigation within an app.
11
11
  */
12
- const TextButton = ({
13
- onPress,
14
- children,
15
- variant,
16
- tokens,
17
- // TODO: this may need to use `link` role on Web in the case of being passed both `href` and
18
- // `onPress` in an omniplatform app that uses React Navigation's useLinkProps for internal nav.
19
- accessibilityRole = 'button',
20
- ...linkProps
21
- }) => {
22
- const getTokens = useThemeTokensCallback('Link', tokens, variant)
23
- return (
24
- <LinkBase
25
- onPress={onPress}
26
- accessibilityRole={accessibilityRole}
27
- tokens={getTokens}
28
- {...linkProps}
29
- >
30
- {children}
31
- </LinkBase>
32
- )
33
- }
12
+ const TextButton = forwardRef(
13
+ (
14
+ {
15
+ onPress,
16
+ children,
17
+ variant,
18
+ tokens,
19
+ // TODO: this may need to use `link` role on Web in the case of being passed both `href` and
20
+ // `onPress` in an omniplatform app that uses React Navigation's useLinkProps for internal nav.
21
+ accessibilityRole = 'button',
22
+ ...linkProps
23
+ },
24
+ ref
25
+ ) => {
26
+ const getTokens = useThemeTokensCallback('Link', tokens, variant)
27
+ return (
28
+ <LinkBase
29
+ onPress={onPress}
30
+ accessibilityRole={accessibilityRole}
31
+ tokens={getTokens}
32
+ ref={ref}
33
+ {...linkProps}
34
+ >
35
+ {children}
36
+ </LinkBase>
37
+ )
38
+ }
39
+ )
40
+ TextButton.displayName = 'TextButton'
34
41
 
35
42
  TextButton.propTypes = {
36
43
  ...LinkBase.propTypes,
package/src/List/List.jsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, { cloneElement, Children } from 'react'
1
+ import React, { cloneElement, forwardRef, Children } from 'react'
2
2
  import { View, Platform } from 'react-native'
3
3
  import PropTypes from 'prop-types'
4
4
  import { getTokensPropType, variantProp, componentPropType } from '../utils'
@@ -9,7 +9,7 @@ import ListItem from './ListItem'
9
9
  * A Unordered List component has a child a ListItem that
10
10
  * allows icon, dividers and customized typography
11
11
  */
12
- const List = ({ children, showDivider, tokens, variant, ...rest }) => {
12
+ const List = forwardRef(({ children, showDivider, tokens, variant, ...rest }, ref) => {
13
13
  const accessibilityRole = Platform.select({ web: 'list', default: 'none' })
14
14
  const a11y = a11yProps.select(rest)
15
15
  const items = Children.map(children, (child, index) => {
@@ -25,11 +25,12 @@ const List = ({ children, showDivider, tokens, variant, ...rest }) => {
25
25
  })
26
26
 
27
27
  return (
28
- <View accessibilityRole={accessibilityRole} {...a11y}>
28
+ <View ref={ref} accessibilityRole={accessibilityRole} {...a11y}>
29
29
  {items}
30
30
  </View>
31
31
  )
32
- }
32
+ })
33
+ List.displayName = 'List'
33
34
 
34
35
  List.Item = ListItem
35
36
 
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { forwardRef } from 'react'
2
2
  import { View, Platform, Text, StyleSheet } from 'react-native'
3
3
  import PropTypes from 'prop-types'
4
4
  import { useThemeTokens, applyTextStyles } from '../ThemeProvider'
@@ -48,104 +48,96 @@ const selectDividerStyles = ({ dividerColor, dividerSize, interItemMarginWithDiv
48
48
  /**
49
49
  * ListItem is responsible for rendering icon or a bullet as side item
50
50
  */
51
- const ListItem = ({
52
- tokens,
53
- variant,
54
- icon,
55
- iconColor,
56
- iconSize,
57
- showDivider,
58
- children,
59
- isLastItem
60
- }) => {
61
- const themeTokens = useThemeTokens('List', tokens, variant)
62
-
63
- const itemStyles = selectItemStyles(themeTokens)
64
- const itemBlockStyles = selectItemBlockStyles(themeTokens)
65
- const dividerStyles = selectDividerStyles(themeTokens)
66
- const itemBulletContainerStyles = selectBulletContainerStyles(themeTokens)
67
- const itemBulletStyles = selectBulletStyles(themeTokens)
68
- const iconTokens = selectItemIconTokens(themeTokens)
69
- const sideItemContainerStyles = selectSideItemContainerStyles(themeTokens)
70
- const accessibilityRole = Platform.select({ web: 'listitem', default: 'item' })
71
-
72
- const areChildrenStrings = () => {
73
- if (Array.isArray(children)) {
74
- return children.every((child) => typeof child === 'string')
51
+ const ListItem = forwardRef(
52
+ ({ tokens, variant, icon, iconColor, iconSize, showDivider, children, isLastItem }, ref) => {
53
+ const themeTokens = useThemeTokens('List', tokens, variant)
54
+
55
+ const itemStyles = selectItemStyles(themeTokens)
56
+ const itemBlockStyles = selectItemBlockStyles(themeTokens)
57
+ const dividerStyles = selectDividerStyles(themeTokens)
58
+ const itemBulletContainerStyles = selectBulletContainerStyles(themeTokens)
59
+ const itemBulletStyles = selectBulletStyles(themeTokens)
60
+ const iconTokens = selectItemIconTokens(themeTokens)
61
+ const sideItemContainerStyles = selectSideItemContainerStyles(themeTokens)
62
+ const accessibilityRole = Platform.select({ web: 'listitem', default: 'item' })
63
+
64
+ const areChildrenStrings = () => {
65
+ if (Array.isArray(children)) {
66
+ return children.every((child) => typeof child === 'string')
67
+ }
68
+
69
+ return typeof children === 'string'
75
70
  }
76
71
 
77
- return typeof children === 'string'
78
- }
79
-
80
- const renderItem = () => {
81
- if (areChildrenStrings()) {
82
- return <Text style={itemStyles}>{children}</Text>
83
- }
72
+ const renderItem = () => {
73
+ if (areChildrenStrings()) {
74
+ return <Text style={itemStyles}>{children}</Text>
75
+ }
84
76
 
85
- return <View>{children}</View>
86
- }
87
-
88
- /**
89
- * Function responsible returning styling, in case the item is the last shouldn't
90
- * add extra margin on the bottom, if "showDivider" is true it should add a divider
91
- * and custom margin and padding, otherwise just adds a margin to the bottom
92
- */
93
- const getContainerStyle = () => {
94
- if (isLastItem) {
95
- return undefined
77
+ return <View style={staticStyles.wrap}>{children}</View>
96
78
  }
97
79
 
98
- if (showDivider) {
99
- return dividerStyles
80
+ /**
81
+ * Function responsible returning styling, in case the item is the last shouldn't
82
+ * add extra margin on the bottom, if "showDivider" is true it should add a divider
83
+ * and custom margin and padding, otherwise just adds a margin to the bottom
84
+ */
85
+ const getContainerStyle = () => {
86
+ if (isLastItem) {
87
+ return undefined
88
+ }
89
+
90
+ if (showDivider) {
91
+ return dividerStyles
92
+ }
93
+
94
+ return itemBlockStyles
100
95
  }
101
96
 
102
- return itemBlockStyles
103
- }
104
-
105
- /**
106
- * Renders item bullet or Icon in case it's defined
107
- * in case children are string the icon is centered otherwise
108
- * it will align itself at start of the container
109
- */
110
- const renderMarker = () => {
111
- const IconComponent = icon || <></>
97
+ /**
98
+ * Renders item bullet or Icon in case it's defined
99
+ * in case children are string the icon is centered otherwise
100
+ * it will align itself at start of the container
101
+ */
102
+ const renderMarker = () => {
103
+ const IconComponent = icon || <></>
104
+
105
+ if (icon) {
106
+ return (
107
+ <View
108
+ style={[
109
+ sideItemContainerStyles,
110
+ areChildrenStrings() ? staticStyles.centeredIcons : undefined
111
+ ]}
112
+ >
113
+ <IconComponent
114
+ size={iconSize || iconTokens.size}
115
+ color={iconColor || iconTokens.color}
116
+ />
117
+ </View>
118
+ )
119
+ }
112
120
 
113
- if (icon) {
114
121
  return (
115
- <View
116
- style={[
117
- sideItemContainerStyles,
118
- areChildrenStrings() ? staticStyles.centeredIcons : undefined
119
- ]}
120
- >
121
- <IconComponent
122
- tokens={{
123
- ...iconTokens,
124
- size: iconSize || iconTokens.size,
125
- color: iconColor || iconTokens.color
126
- }}
127
- />
122
+ <View style={[sideItemContainerStyles, itemBulletContainerStyles]}>
123
+ <View style={itemBulletStyles} testID="unordered-item-bullet" />
128
124
  </View>
129
125
  )
130
126
  }
131
127
 
132
128
  return (
133
- <View style={[sideItemContainerStyles, itemBulletContainerStyles]}>
134
- <View style={itemBulletStyles} testID="unordered-item-bullet" />
129
+ <View
130
+ ref={ref}
131
+ style={[staticStyles.itemContainer, getContainerStyle()]}
132
+ accessibilityRole={accessibilityRole}
133
+ >
134
+ {renderMarker()}
135
+ {renderItem()}
135
136
  </View>
136
137
  )
137
138
  }
138
-
139
- return (
140
- <View
141
- style={[staticStyles.itemContainer, getContainerStyle()]}
142
- accessibilityRole={accessibilityRole}
143
- >
144
- {renderMarker()}
145
- {renderItem()}
146
- </View>
147
- )
148
- }
139
+ )
140
+ ListItem.displayName = 'ListItem'
149
141
 
150
142
  const staticStyles = StyleSheet.create({
151
143
  itemContainer: {
@@ -153,6 +145,9 @@ const staticStyles = StyleSheet.create({
153
145
  },
154
146
  centeredIcons: {
155
147
  justifyContent: 'center'
148
+ },
149
+ wrap: {
150
+ flex: 1
156
151
  }
157
152
  })
158
153
 
@@ -0,0 +1,190 @@
1
+ import React, { forwardRef } from 'react'
2
+ import {
3
+ StyleSheet,
4
+ TouchableWithoutFeedback,
5
+ View,
6
+ Modal as NativeModal,
7
+ Platform
8
+ } from 'react-native'
9
+
10
+ import PropTypes from 'prop-types'
11
+ import { applyShadowToken, useThemeTokens } from '../ThemeProvider'
12
+ import { getTokensPropType, useCopy, copyPropTypes, variantProp } from '../utils'
13
+ import { useViewport } from '../ViewportProvider'
14
+ import ButtonBase from '../Button/ButtonBase'
15
+ import dictionary from './dictionary'
16
+
17
+ const selectContainerStyles = ({
18
+ containerPaddingLeft,
19
+ containerPaddingRight,
20
+ containerPaddingTop,
21
+ containerPaddingBottom,
22
+ maxWidth,
23
+ height
24
+ }) => ({
25
+ height,
26
+ maxWidth,
27
+ paddingLeft: containerPaddingLeft,
28
+ paddingRight: containerPaddingRight,
29
+ paddingTop: containerPaddingTop,
30
+ paddingBottom: containerPaddingBottom
31
+ })
32
+
33
+ const selectModalStyles = ({
34
+ backgroundColor,
35
+ borderRadius,
36
+ height,
37
+ paddingLeft,
38
+ paddingRight,
39
+ paddingTop,
40
+ paddingBottom,
41
+ shadow
42
+ }) => ({
43
+ backgroundColor,
44
+ borderRadius,
45
+ height,
46
+ paddingLeft,
47
+ paddingRight,
48
+ paddingTop,
49
+ paddingBottom,
50
+ ...applyShadowToken(shadow)
51
+ })
52
+
53
+ const selectBackdropStyles = ({ backdropColor, backdropOpacity }) => ({
54
+ backgroundColor: backdropColor,
55
+ opacity: backdropOpacity
56
+ })
57
+
58
+ const selectCloseButtonContainerStyles = ({ paddingRight, paddingTop }) => ({
59
+ paddingRight,
60
+ paddingTop
61
+ })
62
+
63
+ const selectCloseIconProps = ({ closeIconSize, closeIconColor }) => ({
64
+ size: closeIconSize,
65
+ color: closeIconColor
66
+ })
67
+
68
+ /**
69
+ * A modal window is a secondary window that opens on top of the main one.
70
+ * Users have to interact with it before they can carry out their task and return to the main window.
71
+ * Use to reveal additional information to a user after they have performed an explicit interaction.
72
+ * They are a strongly discouraged pattern; it's preferred to have all relevant information within a page,
73
+ * and irrelevant information either linked externally or omitted.
74
+ *
75
+ * - Must only appear after a customer interaction, not on page load or any other circumstance
76
+ * - Open a modal based on explicit customer action e.g. clicking on a button/link/form field
77
+ * - Only one modal should be "current" at any time
78
+ * - Read [WebAIM's documentation](https://www.w3.org/TR/wai-aria-practices/examples/dialog-modal/dialog.html) to create accessible modals
79
+ * - Don’t use modals to reinforce or repeat information already available in the parent page or view
80
+ * - Don’t use modals consecutively
81
+ */
82
+ const Modal = forwardRef(({ children, isOpen, onClose, maxWidth, tokens, variant, copy }, ref) => {
83
+ const viewport = useViewport()
84
+ const themeTokens = useThemeTokens('Modal', tokens, variant, { viewport, maxWidth })
85
+
86
+ const { closeIcon: CloseIconComponent } = themeTokens
87
+
88
+ const getCopy = useCopy({ dictionary, copy })
89
+ const closeLabel = getCopy('closeButton')
90
+
91
+ const handleClose = () => {
92
+ if (typeof onClose === 'function') onClose()
93
+ }
94
+
95
+ const handleKeyUp = (event) => {
96
+ if (event.key === 'Escape') onClose()
97
+ }
98
+
99
+ if (!isOpen) {
100
+ return null
101
+ }
102
+
103
+ // TODO: replace the close button with IconButton when implemented (https://github.com/telus/universal-design-system/issues/281)
104
+ return (
105
+ <NativeModal transparent>
106
+ <View style={[staticStyles.positioningContainer]}>
107
+ <View
108
+ style={[staticStyles.sizingContainer, selectContainerStyles(themeTokens)]}
109
+ pointerEvents="box-none" // don't capture backdrop press events
110
+ >
111
+ <View
112
+ ref={ref}
113
+ style={[staticStyles.modal, selectModalStyles(themeTokens)]}
114
+ onKeyUp={handleKeyUp}
115
+ >
116
+ <View
117
+ style={[
118
+ staticStyles.closeButtonContainer,
119
+ selectCloseButtonContainerStyles(themeTokens)
120
+ ]}
121
+ >
122
+ <ButtonBase
123
+ onPress={handleClose}
124
+ accessibilityRole="button"
125
+ accessibilityLabel={closeLabel}
126
+ >
127
+ {
128
+ // TODO: add close button interactive states after IconButton is done
129
+ () => <CloseIconComponent {...selectCloseIconProps(themeTokens)} />
130
+ }
131
+ </ButtonBase>
132
+ </View>
133
+ {children}
134
+ </View>
135
+ </View>
136
+ {/* when a modal becomes open its first focusable element is being automatically focused */}
137
+ {/* and we prefer the close button over backdrop */}
138
+ <TouchableWithoutFeedback onPress={handleClose}>
139
+ <View style={[staticStyles.backdrop, selectBackdropStyles(themeTokens)]} />
140
+ </TouchableWithoutFeedback>
141
+ </View>
142
+ </NativeModal>
143
+ )
144
+ })
145
+ Modal.displayName = 'Modal'
146
+
147
+ Modal.propTypes = {
148
+ children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
149
+ copy: copyPropTypes,
150
+ isOpen: PropTypes.bool,
151
+ onClose: PropTypes.func,
152
+ maxWidth: PropTypes.bool,
153
+ tokens: getTokensPropType('Modal'),
154
+ variant: variantProp.propType
155
+ }
156
+
157
+ export default Modal
158
+
159
+ const staticStyles = StyleSheet.create({
160
+ backdrop: {
161
+ position: 'absolute',
162
+ top: 0,
163
+ left: 0,
164
+ right: 0,
165
+ bottom: 0,
166
+ zIndex: -1,
167
+ ...Platform.select({
168
+ web: {
169
+ cursor: 'pointer'
170
+ }
171
+ })
172
+ },
173
+ positioningContainer: {
174
+ flexBasis: '100%',
175
+ alignItems: 'center',
176
+ justifyContent: 'center'
177
+ },
178
+ sizingContainer: {
179
+ maxHeight: '100%', // so that the container can expand up to the full viewport height
180
+ width: '100%' // ensure that the modal actually expands to the set maxWidth
181
+ },
182
+ modal: {
183
+ maxHeight: '100%' // so that the modal can expand vertically up to the sizing container's height (exclusive of its vertical padding)
184
+ },
185
+ closeButtonContainer: {
186
+ position: 'absolute',
187
+ top: 0,
188
+ right: 0
189
+ }
190
+ })
@@ -0,0 +1,9 @@
1
+ export default {
2
+ en: {
3
+ // English text from TDS Community `Modal`
4
+ closeButton: 'Close'
5
+ },
6
+ fr: {
7
+ closeButton: 'Fermer'
8
+ }
9
+ }
@@ -0,0 +1,3 @@
1
+ import Modal from './Modal'
2
+
3
+ export default Modal