@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
@@ -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
@@ -0,0 +1,97 @@
1
+ import React, { forwardRef, useCallback } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import ABBPropTypes from 'airbnb-prop-types'
4
+
5
+ import { useThemeTokens } from '../ThemeProvider'
6
+ import StackView from '../StackView'
7
+ import { getTokensPropType, variantProp, useHash, useInputValue } from '../utils'
8
+ import HorizontalScroll, {
9
+ horizontalScrollUtils,
10
+ HorizontalScrollButton
11
+ } from '../HorizontalScroll'
12
+ import TabsItem from './TabsItem'
13
+
14
+ const { selectHorizontalScrollTokens, useItemPositions } = horizontalScrollUtils
15
+
16
+ /**
17
+ * Tabs renders a horizontally-scrolling menu of selectable buttons which may link
18
+ * to a page or control what content is displayed on this page.
19
+ */
20
+ const Tabs = forwardRef(
21
+ (
22
+ { tokens, itemTokens, scrollButtonTokens, variant, value, initialValue, onChange, items = [] },
23
+ ref
24
+ ) => {
25
+ const { space, ...themeTokens } = useThemeTokens('Tabs', tokens, variant)
26
+ const { currentValue, setValue } = useInputValue({ value, initialValue, onChange })
27
+
28
+ const [itemPositions, isPositioningReady] = useItemPositions()
29
+
30
+ useHash(
31
+ useCallback(
32
+ (hash, event) => {
33
+ const hashItem = hash && items.find(({ href }) => hash === href)
34
+ const hashId = hashItem && (hashItem.id || hashItem.label)
35
+ if (hashId) setTimeout(setValue(hashId, event), 500)
36
+ },
37
+ [items, setValue]
38
+ ),
39
+ isPositioningReady
40
+ )
41
+
42
+ return (
43
+ <HorizontalScroll
44
+ ref={ref}
45
+ ScrollButton={HorizontalScrollButton}
46
+ itemPositions={itemPositions}
47
+ tokens={selectHorizontalScrollTokens(themeTokens)}
48
+ scrollButtonTokens={scrollButtonTokens}
49
+ accessibilityRole="tablist"
50
+ >
51
+ <StackView space={space} direction="row">
52
+ {items.map(({ href, label, id, ref: itemRef }, index) => {
53
+ const itemId = id ?? label
54
+ const isSelected = Boolean(currentValue && currentValue === itemId)
55
+ const handlePress = (event) => setValue(itemId, event)
56
+ return (
57
+ <TabsItem
58
+ ref={itemRef}
59
+ key={itemId}
60
+ href={href}
61
+ variant={variant}
62
+ tokens={itemTokens}
63
+ onPress={handlePress}
64
+ selected={isSelected}
65
+ itemPositions={itemPositions}
66
+ index={index}
67
+ >
68
+ {label}
69
+ </TabsItem>
70
+ )
71
+ })}
72
+ </StackView>
73
+ </HorizontalScroll>
74
+ )
75
+ }
76
+ )
77
+ Tabs.displayName = 'Tabs'
78
+
79
+ Tabs.propTypes = {
80
+ items: PropTypes.arrayOf(
81
+ PropTypes.shape({
82
+ href: PropTypes.string,
83
+ label: PropTypes.string,
84
+ id: PropTypes.string,
85
+ ref: ABBPropTypes.ref()
86
+ })
87
+ ),
88
+ value: PropTypes.string,
89
+ initialValue: PropTypes.string,
90
+ onChange: PropTypes.func,
91
+ tokens: getTokensPropType('Tabs'),
92
+ itemTokens: getTokensPropType('TabsItem'),
93
+ scrollButtonTokens: getTokensPropType('HorizontalScrollButton'),
94
+ variant: variantProp.propType
95
+ }
96
+
97
+ export default Tabs
@@ -0,0 +1,212 @@
1
+ import React, { forwardRef, useEffect } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { Platform, Pressable, StyleSheet, Text, View } from 'react-native'
4
+
5
+ import { applyTextStyles, useThemeTokensCallback } from '../ThemeProvider'
6
+ import {
7
+ resolvePressableTokens,
8
+ selectTokens,
9
+ variantProp,
10
+ getTokensPropType,
11
+ linkProps,
12
+ a11yProps
13
+ } from '../utils'
14
+ import Spacer from '../Spacer'
15
+ import { horizontalScrollUtils } from '../HorizontalScroll'
16
+
17
+ const { itemPositionsPropType, getItemPositionLayoutHandler } = horizontalScrollUtils
18
+
19
+ const selectHighlightBarStyles = ({
20
+ highlightColor,
21
+ highlightBarBorderRadius = 0,
22
+ highlightBarBorderWidth = 0,
23
+ highlightBarHeight = 0
24
+ }) => ({
25
+ backgroundColor: highlightColor,
26
+ borderColor: highlightColor,
27
+ height: highlightBarHeight + highlightBarBorderWidth * 2,
28
+ borderRadius: highlightBarBorderRadius,
29
+ borderWidth: highlightBarBorderWidth,
30
+ bottom: -1 * (highlightBarHeight + highlightBarBorderWidth),
31
+ left: -1 * highlightBarBorderWidth,
32
+ right: -1 * highlightBarBorderWidth,
33
+ zIndex: 1 + highlightBarBorderWidth
34
+ })
35
+
36
+ const selectHighlightTriangleStyles = ({ highlightColor, highlightTriangleSize }) => ({
37
+ container: {
38
+ bottom: 0 - highlightTriangleSize * 2
39
+ },
40
+ triangle: {
41
+ height: 0,
42
+ width: 0,
43
+ borderWidth: highlightTriangleSize,
44
+ borderTopColor: highlightColor,
45
+ borderBottomColor: 'transparent',
46
+ borderLeftColor: 'transparent',
47
+ borderRightColor: 'transparent'
48
+ }
49
+ })
50
+
51
+ const selectContainerStyles = ({
52
+ backgroundColor,
53
+ borderColor,
54
+ borderWidth = 0,
55
+ borderRadius,
56
+ paddingHorizontal = 0,
57
+ paddingVertical = 0
58
+ }) => ({
59
+ backgroundColor,
60
+ borderColor,
61
+ borderWidth,
62
+ borderRadius,
63
+ paddingHorizontal: paddingHorizontal - borderWidth,
64
+ paddingVertical: paddingVertical - borderWidth
65
+ })
66
+
67
+ /**
68
+ * Item within a Tabs component representing one tab of content. May be rendered as a link
69
+ * or as a "menuitem" button depending on whether 'href' is passed.
70
+ *
71
+ * This is rendered automatically by `Tabs` and isn't intended be used directly.
72
+ */
73
+ const TabsItem = forwardRef(
74
+ (
75
+ {
76
+ onPress,
77
+ href,
78
+ variant,
79
+ tokens,
80
+ selected,
81
+ itemPositions,
82
+ index,
83
+ children,
84
+ accessibilityRole = href ? 'link' : 'tab',
85
+ accessibilityState = Platform.OS === 'web' && accessibilityRole === 'link'
86
+ ? // Web links can't be aria-selected but can be aria-current
87
+ { current: selected ? 'page' : false }
88
+ : { selected },
89
+ ...rest
90
+ },
91
+ ref
92
+ ) => {
93
+ const getTokens = useThemeTokensCallback('TabsItem', tokens, variant)
94
+ const resolveTokens = (pressableState) =>
95
+ resolvePressableTokens(getTokens, pressableState, { selected })
96
+
97
+ const getPressableStyle = (pressableState) => {
98
+ const { maxWidth } = resolveTokens(pressableState)
99
+ return [{ maxWidth }, Platform.OS === 'web' && { outline: 'none' }]
100
+ }
101
+
102
+ const handleLayout = getItemPositionLayoutHandler(itemPositions.positions, index)
103
+
104
+ // On press, update the selection, call any press handler, and open any href in platform-appropriate way
105
+ const openHref = href && linkProps.handleHref({ href })
106
+ const handlePress =
107
+ onPress || openHref
108
+ ? () => {
109
+ if (onPress) onPress()
110
+ if (openHref) openHref()
111
+ }
112
+ : undefined
113
+
114
+ const a11y = {
115
+ accessibilityRole,
116
+ accessibilityState,
117
+ ...a11yProps.select(rest)
118
+ }
119
+
120
+ useEffect(() => {
121
+ // If this is selected while off-screen, scroll it into view
122
+ if (selected) {
123
+ const position = itemPositions.positions[index]
124
+ const scrollEnd = itemPositions.scrollOffset + itemPositions.containerWidth
125
+ if (
126
+ // is off the right edge, or
127
+ (scrollEnd && position?.end > scrollEnd) ||
128
+ // is off the left edge
129
+ (typeof position?.start === 'number' && position.start < itemPositions.scrollOffset)
130
+ ) {
131
+ itemPositions.scrollTo(position.start)
132
+ }
133
+ }
134
+ // itemPositions is a ref object so this should only re-run when `selected` (or `index`) change
135
+ }, [selected, index, itemPositions])
136
+
137
+ return (
138
+ <Pressable
139
+ ref={ref}
140
+ onPress={handlePress}
141
+ href={href}
142
+ style={getPressableStyle}
143
+ onLayout={handleLayout}
144
+ {...a11y}
145
+ >
146
+ {(pressableState) => {
147
+ const { space, textAlign, ...themeTokens } = resolveTokens(pressableState)
148
+
149
+ const hasHighlightBar = Boolean(themeTokens.highlightBarHeight)
150
+ const highlightBarStyle = hasHighlightBar && selectHighlightBarStyles(themeTokens)
151
+
152
+ const hasHighlightTriangle = Boolean(themeTokens.highlightTriangleSize)
153
+ const highlightTriangleStyle =
154
+ hasHighlightTriangle && selectHighlightTriangleStyles(themeTokens)
155
+
156
+ const containerStyles = selectContainerStyles(themeTokens)
157
+ const textStyles = applyTextStyles({
158
+ ...selectTokens('Typography', themeTokens),
159
+ textAlign
160
+ })
161
+
162
+ return (
163
+ <View style={staticStyles.container}>
164
+ <View style={containerStyles}>
165
+ <Text style={textStyles}>{children}</Text>
166
+ </View>
167
+ <Spacer space={space} />
168
+ {hasHighlightBar && <View style={[staticStyles.absolute, highlightBarStyle]} />}
169
+ {hasHighlightTriangle && (
170
+ <View style={[staticStyles.absolute, highlightTriangleStyle.container]}>
171
+ <View style={highlightTriangleStyle.triangle} />
172
+ </View>
173
+ )}
174
+ </View>
175
+ )
176
+ }}
177
+ </Pressable>
178
+ )
179
+ }
180
+ )
181
+ TabsItem.displayName = 'TabsItem'
182
+
183
+ TabsItem.propTypes = {
184
+ ...a11yProps.propTypes,
185
+ tokens: getTokensPropType('TabsItem'),
186
+ variant: variantProp.propType,
187
+ onPress: PropTypes.func,
188
+ href: PropTypes.string,
189
+ index: PropTypes.number,
190
+ selected: PropTypes.bool,
191
+ itemPositions: itemPositionsPropType,
192
+ children: PropTypes.string
193
+ }
194
+
195
+ const staticStyles = StyleSheet.create({
196
+ center: {
197
+ alignItems: 'center'
198
+ },
199
+ absolute: {
200
+ position: 'absolute',
201
+ alignItems: 'center',
202
+ left: 0,
203
+ right: 0
204
+ },
205
+ container: {
206
+ flexGrow: 1,
207
+ alignItems: 'center',
208
+ justifyContent: 'center'
209
+ }
210
+ })
211
+
212
+ export default TabsItem
@@ -0,0 +1,3 @@
1
+ import Tabs from './Tabs'
2
+
3
+ export default Tabs