@hero-design/rn 8.23.0 → 8.24.0-alpha.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 (301) hide show
  1. package/.turbo/turbo-build.log +9 -9
  2. package/.turbo/turbo-build:types.log +2 -0
  3. package/.turbo/turbo-lint.log +146 -0
  4. package/.turbo/turbo-publish:npm.log +9 -0
  5. package/.turbo/turbo-test.log +451 -0
  6. package/.turbo/turbo-type-check.log +1 -0
  7. package/es/index.js +293 -101
  8. package/lib/assets/fonts/hero-icons-mobile.ttf +0 -0
  9. package/lib/index.js +293 -101
  10. package/package.json +1 -1
  11. package/src/components/DatePicker/__tests__/__snapshots__/DatePicker.spec.tsx.snap +21 -9
  12. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerAndroid.spec.tsx.snap +7 -3
  13. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerCalendar.spec.tsx.snap +7 -3
  14. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerIOS.spec.tsx.snap +7 -3
  15. package/src/components/RichTextEditor/RichTextEditor.tsx +10 -7
  16. package/src/components/RichTextEditor/__tests__/__snapshots__/RichTextEditor.spec.tsx.snap +10 -8
  17. package/src/components/Select/MultiSelect/__tests__/__snapshots__/index.spec.tsx.snap +37 -16
  18. package/src/components/Select/SingleSelect/__tests__/__snapshots__/index.spec.tsx.snap +37 -16
  19. package/src/components/Tabs/ScrollableTabs.tsx +10 -149
  20. package/src/components/Tabs/ScrollableTabsHeader.tsx +214 -0
  21. package/src/components/Tabs/ScrollableTabsV2/SceneView.tsx +61 -0
  22. package/src/components/Tabs/ScrollableTabsV2/ScrollableTabsV2.tsx +120 -0
  23. package/src/components/Tabs/ScrollableTabsV2/__tests__/SceneView.spec.tsx +76 -0
  24. package/src/components/Tabs/ScrollableTabsV2/__tests__/ScrollableTabsV2.spec.tsx +166 -0
  25. package/src/components/Tabs/ScrollableTabsV2/__tests__/__snapshots__/SceneView.spec.tsx.snap +161 -0
  26. package/src/components/Tabs/ScrollableTabsV2/__tests__/__snapshots__/ScrollableTabsV2.spec.tsx.snap +2497 -0
  27. package/src/components/Tabs/ScrollableTabsV2/index.tsx +5 -0
  28. package/src/components/Tabs/__tests__/ScrollableTabsHeader.spec.tsx +80 -0
  29. package/src/components/Tabs/__tests__/__snapshots__/ScrollableTabsHeader.spec.tsx.snap +587 -0
  30. package/src/components/Tabs/index.tsx +2 -0
  31. package/src/components/TextInput/StyledTextInput.tsx +40 -29
  32. package/src/components/TextInput/__tests__/StyledTextInput.spec.tsx +48 -57
  33. package/src/components/TextInput/__tests__/__snapshots__/StyledTextInput.spec.tsx.snap +84 -58
  34. package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +326 -74
  35. package/src/components/TextInput/__tests__/index.spec.tsx +16 -4
  36. package/src/components/TextInput/index.tsx +25 -15
  37. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerAndroid.spec.tsx.snap +14 -6
  38. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerIOS.spec.tsx.snap +14 -6
  39. package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +8 -3
  40. package/src/theme/components/textInput.ts +10 -4
  41. package/testUtils/setup.tsx +6 -0
  42. package/types/components/Accordion/AccordionItem.d.ts +0 -0
  43. package/types/components/Accordion/StyledAccordion.d.ts +0 -0
  44. package/types/components/Accordion/index.d.ts +0 -0
  45. package/types/components/Alert/StyledAlert.d.ts +0 -0
  46. package/types/components/Alert/index.d.ts +0 -0
  47. package/types/components/Attachment/StyledAttachment.d.ts +0 -0
  48. package/types/components/Attachment/index.d.ts +0 -0
  49. package/types/components/Avatar/Avatar.d.ts +0 -0
  50. package/types/components/Avatar/AvatarStack/StyledAvatarStack.d.ts +0 -0
  51. package/types/components/Avatar/AvatarStack/index.d.ts +0 -0
  52. package/types/components/Avatar/AvatarStack/utils.d.ts +0 -0
  53. package/types/components/Avatar/StyledAvatar.d.ts +0 -0
  54. package/types/components/Avatar/index.d.ts +0 -0
  55. package/types/components/Badge/Status.d.ts +0 -0
  56. package/types/components/Badge/StyledBadge.d.ts +0 -0
  57. package/types/components/Badge/index.d.ts +0 -0
  58. package/types/components/BottomNavigation/StyledBottomNavigation.d.ts +0 -0
  59. package/types/components/BottomNavigation/index.d.ts +0 -0
  60. package/types/components/BottomSheet/BottomSheetContext.d.ts +0 -0
  61. package/types/components/BottomSheet/Footer.d.ts +0 -0
  62. package/types/components/BottomSheet/Header.d.ts +0 -0
  63. package/types/components/BottomSheet/ScrollView.d.ts +0 -0
  64. package/types/components/BottomSheet/StyledBottomSheet.d.ts +0 -0
  65. package/types/components/BottomSheet/index.d.ts +0 -0
  66. package/types/components/Box/StyledBox.d.ts +0 -0
  67. package/types/components/Box/config.d.ts +0 -0
  68. package/types/components/Box/index.d.ts +0 -0
  69. package/types/components/Box/types.d.ts +0 -0
  70. package/types/components/Button/Button.d.ts +0 -0
  71. package/types/components/Button/IconButton.d.ts +0 -0
  72. package/types/components/Button/LoadingIndicator/StyledLoadingIndicator.d.ts +0 -0
  73. package/types/components/Button/LoadingIndicator/index.d.ts +0 -0
  74. package/types/components/Button/StyledButton.d.ts +0 -0
  75. package/types/components/Button/UtilityButton/StyledUtilityButton.d.ts +0 -0
  76. package/types/components/Button/UtilityButton/index.d.ts +0 -0
  77. package/types/components/Button/index.d.ts +0 -0
  78. package/types/components/Calendar/CalendarRowItem.d.ts +0 -0
  79. package/types/components/Calendar/StyledCalendar.d.ts +0 -0
  80. package/types/components/Calendar/helpers.d.ts +0 -0
  81. package/types/components/Calendar/index.d.ts +0 -0
  82. package/types/components/Card/DataCard/StyledDataCard.d.ts +0 -0
  83. package/types/components/Card/DataCard/index.d.ts +0 -0
  84. package/types/components/Card/StyledCard.d.ts +0 -0
  85. package/types/components/Card/index.d.ts +0 -0
  86. package/types/components/Carousel/CardCarousel.d.ts +0 -0
  87. package/types/components/Carousel/CarouselItem.d.ts +0 -0
  88. package/types/components/Carousel/StyledCardCarousel.d.ts +0 -0
  89. package/types/components/Carousel/StyledCarousel.d.ts +0 -0
  90. package/types/components/Carousel/contants.d.ts +0 -0
  91. package/types/components/Carousel/index.d.ts +0 -0
  92. package/types/components/Carousel/types.d.ts +0 -0
  93. package/types/components/Checkbox/StyledCheckbox.d.ts +0 -0
  94. package/types/components/Checkbox/index.d.ts +0 -0
  95. package/types/components/Collapse/StyledCollapse.d.ts +0 -0
  96. package/types/components/Collapse/index.d.ts +0 -0
  97. package/types/components/ContentNavigator/StyledContentNavigator.d.ts +0 -0
  98. package/types/components/ContentNavigator/index.d.ts +0 -0
  99. package/types/components/DatePicker/DatePickerAndroid.d.ts +0 -0
  100. package/types/components/DatePicker/DatePickerCalendar.d.ts +0 -0
  101. package/types/components/DatePicker/DatePickerIOS.d.ts +0 -0
  102. package/types/components/DatePicker/StyledDatePicker.d.ts +0 -0
  103. package/types/components/DatePicker/index.d.ts +0 -0
  104. package/types/components/DatePicker/types.d.ts +0 -0
  105. package/types/components/Divider/StyledDivider.d.ts +0 -0
  106. package/types/components/Divider/index.d.ts +0 -0
  107. package/types/components/Drawer/DragableDrawer/helpers.d.ts +0 -0
  108. package/types/components/Drawer/DragableDrawer/index.d.ts +0 -0
  109. package/types/components/Drawer/StyledDrawer.d.ts +0 -0
  110. package/types/components/Drawer/index.d.ts +0 -0
  111. package/types/components/Empty/StyledEmpty.d.ts +0 -0
  112. package/types/components/Empty/index.d.ts +0 -0
  113. package/types/components/Error/StyledError.d.ts +0 -0
  114. package/types/components/Error/index.d.ts +0 -0
  115. package/types/components/FAB/ActionGroup/ActionItem.d.ts +0 -0
  116. package/types/components/FAB/ActionGroup/StyledActionGroup.d.ts +0 -0
  117. package/types/components/FAB/ActionGroup/StyledActionItem.d.ts +0 -0
  118. package/types/components/FAB/ActionGroup/index.d.ts +0 -0
  119. package/types/components/FAB/AnimatedFABIcon.d.ts +0 -0
  120. package/types/components/FAB/FAB.d.ts +0 -0
  121. package/types/components/FAB/StyledFAB.d.ts +0 -0
  122. package/types/components/FAB/index.d.ts +0 -0
  123. package/types/components/Icon/AnimatedIcon.d.ts +0 -0
  124. package/types/components/Icon/HeroIcon/index.d.ts +0 -0
  125. package/types/components/Icon/IconList.d.ts +0 -0
  126. package/types/components/Icon/index.d.ts +0 -0
  127. package/types/components/Icon/utils.d.ts +0 -0
  128. package/types/components/Image/index.d.ts +0 -0
  129. package/types/components/List/BasicListItem.d.ts +0 -0
  130. package/types/components/List/ListItem.d.ts +0 -0
  131. package/types/components/List/StyledBasicListItem.d.ts +0 -0
  132. package/types/components/List/StyledListItem.d.ts +0 -0
  133. package/types/components/List/index.d.ts +0 -0
  134. package/types/components/PageControl/StyledPageControl.d.ts +0 -0
  135. package/types/components/PageControl/index.d.ts +0 -0
  136. package/types/components/PinInput/PinCell.d.ts +0 -0
  137. package/types/components/PinInput/StyledPinInput.d.ts +0 -0
  138. package/types/components/PinInput/index.d.ts +0 -0
  139. package/types/components/Progress/ProgressBar.d.ts +0 -0
  140. package/types/components/Progress/ProgressCircle.d.ts +0 -0
  141. package/types/components/Progress/StyledProgressBar.d.ts +0 -0
  142. package/types/components/Progress/StyledProgressCircle.d.ts +0 -0
  143. package/types/components/Progress/__tests__/index.spec.d.ts +0 -0
  144. package/types/components/Progress/constants.d.ts +0 -0
  145. package/types/components/Progress/index.d.ts +0 -0
  146. package/types/components/Progress/types.d.ts +0 -0
  147. package/types/components/Radio/Radio.d.ts +0 -0
  148. package/types/components/Radio/RadioGroup.d.ts +0 -0
  149. package/types/components/Radio/StyledRadio.d.ts +0 -0
  150. package/types/components/Radio/index.d.ts +0 -0
  151. package/types/components/Radio/types.d.ts +0 -0
  152. package/types/components/RefreshControl/index.d.ts +0 -0
  153. package/types/components/RichTextEditor/EditorEvent.d.ts +0 -0
  154. package/types/components/RichTextEditor/EditorToolbar.d.ts +0 -0
  155. package/types/components/RichTextEditor/MentionList.d.ts +0 -0
  156. package/types/components/RichTextEditor/RichTextEditor.d.ts +0 -0
  157. package/types/components/RichTextEditor/StyledRichTextEditor.d.ts +0 -0
  158. package/types/components/RichTextEditor/StyledToolbar.d.ts +0 -0
  159. package/types/components/RichTextEditor/__mocks__/heroEditorApp.d.ts +0 -0
  160. package/types/components/RichTextEditor/constants.d.ts +0 -0
  161. package/types/components/RichTextEditor/heroEditorApp.d.ts +0 -0
  162. package/types/components/RichTextEditor/index.d.ts +0 -0
  163. package/types/components/RichTextEditor/types.d.ts +0 -0
  164. package/types/components/RichTextEditor/utils/events.d.ts +0 -0
  165. package/types/components/RichTextEditor/utils/rnWebView.d.ts +0 -0
  166. package/types/components/SectionHeading/StyledHeading.d.ts +0 -0
  167. package/types/components/SectionHeading/index.d.ts +0 -0
  168. package/types/components/Select/BaseOptionList.d.ts +0 -0
  169. package/types/components/Select/Footer.d.ts +0 -0
  170. package/types/components/Select/MultiSelect/Option.d.ts +0 -0
  171. package/types/components/Select/MultiSelect/OptionList.d.ts +0 -0
  172. package/types/components/Select/MultiSelect/index.d.ts +0 -0
  173. package/types/components/Select/SingleSelect/Option.d.ts +0 -0
  174. package/types/components/Select/SingleSelect/OptionList.d.ts +0 -0
  175. package/types/components/Select/SingleSelect/StyledSingleSelect.d.ts +0 -0
  176. package/types/components/Select/SingleSelect/index.d.ts +0 -0
  177. package/types/components/Select/StyledSelect.d.ts +0 -0
  178. package/types/components/Select/helpers.d.ts +0 -0
  179. package/types/components/Select/index.d.ts +0 -0
  180. package/types/components/Select/types.d.ts +0 -0
  181. package/types/components/Skeleton/StyledSkeleton.d.ts +0 -0
  182. package/types/components/Skeleton/index.d.ts +0 -0
  183. package/types/components/Slider/index.d.ts +0 -0
  184. package/types/components/Spinner/AnimatedSpinner.d.ts +0 -0
  185. package/types/components/Spinner/StyledSpinner.d.ts +0 -0
  186. package/types/components/Spinner/index.d.ts +0 -0
  187. package/types/components/Success/StyledSuccess.d.ts +0 -0
  188. package/types/components/Success/index.d.ts +0 -0
  189. package/types/components/Swipeable/StyledSwipeable.d.ts +0 -0
  190. package/types/components/Swipeable/SwipeableAction.d.ts +0 -0
  191. package/types/components/Swipeable/index.d.ts +0 -0
  192. package/types/components/Switch/SelectorSwitch/Option.d.ts +0 -0
  193. package/types/components/Switch/SelectorSwitch/StyledSelectorSwitch.d.ts +0 -0
  194. package/types/components/Switch/SelectorSwitch/index.d.ts +0 -0
  195. package/types/components/Switch/StyledSwitch.d.ts +0 -0
  196. package/types/components/Switch/index.d.ts +0 -0
  197. package/types/components/Tabs/ActiveTabIndicator.d.ts +0 -0
  198. package/types/components/Tabs/SceneView.d.ts +9 -0
  199. package/types/components/Tabs/ScrollableTabs.d.ts +0 -0
  200. package/types/components/Tabs/ScrollableTabsHeader.d.ts +35 -0
  201. package/types/components/Tabs/ScrollableTabsV2/SceneView.d.ts +10 -0
  202. package/types/components/Tabs/ScrollableTabsV2/ScrollableTabsV2.d.ts +9 -0
  203. package/types/components/Tabs/ScrollableTabsV2/index.d.ts +4 -0
  204. package/types/components/Tabs/StyledScrollableTabs.d.ts +0 -0
  205. package/types/components/Tabs/StyledTabs.d.ts +0 -0
  206. package/types/components/Tabs/TabWithBadge.d.ts +0 -0
  207. package/types/components/Tabs/index.d.ts +3 -0
  208. package/types/components/Tabs/utils.d.ts +0 -0
  209. package/types/components/Tag/StyledTag.d.ts +0 -0
  210. package/types/components/Tag/index.d.ts +0 -0
  211. package/types/components/TextInput/StyledTextInput.d.ts +12 -7
  212. package/types/components/TextInput/index.d.ts +8 -4
  213. package/types/components/TimePicker/StyledTimePicker.d.ts +0 -0
  214. package/types/components/TimePicker/TimePickerAndroid.d.ts +0 -0
  215. package/types/components/TimePicker/TimePickerIOS.d.ts +0 -0
  216. package/types/components/TimePicker/index.d.ts +0 -0
  217. package/types/components/TimePicker/types.d.ts +0 -0
  218. package/types/components/Toast/StyledToast.d.ts +0 -0
  219. package/types/components/Toast/Toast.d.ts +0 -0
  220. package/types/components/Toast/ToastContainer.d.ts +0 -0
  221. package/types/components/Toast/ToastContext.d.ts +0 -0
  222. package/types/components/Toast/ToastProvider.d.ts +0 -0
  223. package/types/components/Toast/index.d.ts +0 -0
  224. package/types/components/Toast/types.d.ts +0 -0
  225. package/types/components/Toolbar/StyledToolbar.d.ts +0 -0
  226. package/types/components/Toolbar/ToolbarGroup.d.ts +0 -0
  227. package/types/components/Toolbar/ToolbarItem.d.ts +0 -0
  228. package/types/components/Toolbar/index.d.ts +0 -0
  229. package/types/components/Typography/Text/StyledText.d.ts +0 -0
  230. package/types/components/Typography/Text/index.d.ts +0 -0
  231. package/types/components/Typography/index.d.ts +0 -0
  232. package/types/index.d.ts +0 -0
  233. package/types/testHelpers/renderWithTheme.d.ts +0 -0
  234. package/types/theme/ThemeProvider.d.ts +0 -0
  235. package/types/theme/ThemeSwitcher.d.ts +0 -0
  236. package/types/theme/components/accordion.d.ts +0 -0
  237. package/types/theme/components/alert.d.ts +0 -0
  238. package/types/theme/components/attachment.d.ts +0 -0
  239. package/types/theme/components/avatar.d.ts +0 -0
  240. package/types/theme/components/badge.d.ts +0 -0
  241. package/types/theme/components/bottomNavigation.d.ts +0 -0
  242. package/types/theme/components/bottomSheet.d.ts +0 -0
  243. package/types/theme/components/button.d.ts +0 -0
  244. package/types/theme/components/calendar.d.ts +0 -0
  245. package/types/theme/components/card.d.ts +0 -0
  246. package/types/theme/components/cardCarousel.d.ts +0 -0
  247. package/types/theme/components/carousel.d.ts +0 -0
  248. package/types/theme/components/checkbox.d.ts +0 -0
  249. package/types/theme/components/contentNavigator.d.ts +0 -0
  250. package/types/theme/components/datePicker.d.ts +0 -0
  251. package/types/theme/components/divider.d.ts +0 -0
  252. package/types/theme/components/drawer.d.ts +0 -0
  253. package/types/theme/components/empty.d.ts +0 -0
  254. package/types/theme/components/error.d.ts +0 -0
  255. package/types/theme/components/fab.d.ts +0 -0
  256. package/types/theme/components/icon.d.ts +0 -0
  257. package/types/theme/components/image.d.ts +0 -0
  258. package/types/theme/components/list.d.ts +0 -0
  259. package/types/theme/components/pageControl.d.ts +0 -0
  260. package/types/theme/components/pinInput.d.ts +0 -0
  261. package/types/theme/components/progress.d.ts +0 -0
  262. package/types/theme/components/radio.d.ts +0 -0
  263. package/types/theme/components/refreshControl.d.ts +0 -0
  264. package/types/theme/components/richTextEditor.d.ts +0 -0
  265. package/types/theme/components/sectionHeading.d.ts +0 -0
  266. package/types/theme/components/select.d.ts +0 -0
  267. package/types/theme/components/skeleton.d.ts +0 -0
  268. package/types/theme/components/slider.d.ts +0 -0
  269. package/types/theme/components/spinner.d.ts +0 -0
  270. package/types/theme/components/success.d.ts +0 -0
  271. package/types/theme/components/swipeable.d.ts +0 -0
  272. package/types/theme/components/switch.d.ts +0 -0
  273. package/types/theme/components/tabs.d.ts +0 -0
  274. package/types/theme/components/tag.d.ts +0 -0
  275. package/types/theme/components/textInput.d.ts +5 -0
  276. package/types/theme/components/timePicker.d.ts +0 -0
  277. package/types/theme/components/toast.d.ts +0 -0
  278. package/types/theme/components/toolbar.d.ts +0 -0
  279. package/types/theme/components/typography.d.ts +0 -0
  280. package/types/theme/getTheme.d.ts +0 -0
  281. package/types/theme/global/borders.d.ts +0 -0
  282. package/types/theme/global/colors/eBens.d.ts +0 -0
  283. package/types/theme/global/colors/global.d.ts +0 -0
  284. package/types/theme/global/colors/globalDark.d.ts +0 -0
  285. package/types/theme/global/colors/jobs.d.ts +0 -0
  286. package/types/theme/global/colors/swag.d.ts +0 -0
  287. package/types/theme/global/colors/swagDark.d.ts +0 -0
  288. package/types/theme/global/colors/types.d.ts +0 -0
  289. package/types/theme/global/colors/wallet.d.ts +0 -0
  290. package/types/theme/global/colors/work.d.ts +0 -0
  291. package/types/theme/global/index.d.ts +0 -0
  292. package/types/theme/global/scale.d.ts +0 -0
  293. package/types/theme/global/sizes.d.ts +0 -0
  294. package/types/theme/global/space.d.ts +0 -0
  295. package/types/theme/global/typography.d.ts +0 -0
  296. package/types/theme/index.d.ts +0 -0
  297. package/types/types.d.ts +0 -0
  298. package/types/utils/functions.d.ts +0 -0
  299. package/types/utils/helpers.d.ts +0 -0
  300. package/types/utils/hooks.d.ts +0 -0
  301. package/types/utils/scale.d.ts +0 -0
@@ -0,0 +1,120 @@
1
+ import React from 'react';
2
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
3
+ import PagerView from 'react-native-pager-view';
4
+ import { TabContainer, ContentWrapper } from '../StyledScrollableTabs';
5
+ import type { TabsProps } from '..';
6
+ import { SceneView } from './SceneView';
7
+ import ScrollableTabHeader from '../ScrollableTabsHeader';
8
+
9
+ export const TabContext = React.createContext<{
10
+ selectedTabKey: string;
11
+ } | null>(null);
12
+
13
+ export const ScreenContext = React.createContext<string | null>(null);
14
+
15
+ export const useIsFocused = () => {
16
+ const context = React.useContext(TabContext);
17
+ const key = React.useContext(ScreenContext);
18
+ if (!context || !key) {
19
+ return;
20
+ }
21
+
22
+ const isFocused = context.selectedTabKey === key;
23
+
24
+ return isFocused;
25
+ };
26
+
27
+ const ScrollableTab = ({
28
+ onTabPress,
29
+ selectedTabKey,
30
+ tabs,
31
+ containerStyle,
32
+ barStyle,
33
+ lazy = false,
34
+ lazyPreloadDistance = 1,
35
+ swipeEnabled = true,
36
+ testID: componentTestID,
37
+ }: TabsProps) => {
38
+ const pagerViewRef = React.useRef<PagerView>(null);
39
+ const insets = useSafeAreaInsets();
40
+ const selectedTabIndex = tabs.findIndex(
41
+ (item) => item.key === selectedTabKey
42
+ );
43
+
44
+ React.useEffect(() => {
45
+ let timeoutHandle: number | null = null;
46
+ if (selectedTabIndex !== -1) {
47
+ // If the selected tab is changed too quickly, the setPage is crashed and not work anymore
48
+ // We apply throttle to prevent this issue https://github.com/Thinkei/hero-design/issues/1715
49
+ timeoutHandle = setTimeout(() => {
50
+ // use no animation to prevent unexpected behavior if users select tab too quickly
51
+ pagerViewRef.current?.setPageWithoutAnimation(selectedTabIndex);
52
+ }, 200);
53
+ }
54
+
55
+ return () => {
56
+ if (timeoutHandle) {
57
+ clearTimeout(timeoutHandle);
58
+ }
59
+ };
60
+ }, [selectedTabIndex, pagerViewRef]);
61
+
62
+ const indexRef = React.useRef(selectedTabIndex);
63
+ const tabContextProviderValue = React.useMemo(
64
+ () => ({
65
+ selectedTabKey,
66
+ }),
67
+ [selectedTabKey]
68
+ );
69
+
70
+ return (
71
+ <TabContext.Provider value={tabContextProviderValue}>
72
+ <TabContainer style={containerStyle} testID={componentTestID}>
73
+ <ScrollableTabHeader
74
+ tabs={tabs}
75
+ selectedIndex={selectedTabIndex}
76
+ onTabPress={onTabPress}
77
+ barStyle={barStyle}
78
+ insets={insets}
79
+ testID={componentTestID ? `${componentTestID}-tab-bar` : undefined}
80
+ />
81
+ <ContentWrapper
82
+ initialPage={selectedTabIndex}
83
+ ref={pagerViewRef}
84
+ onPageSelected={(e) => {
85
+ const index = e.nativeEvent.position;
86
+ const selectedItem = tabs[index];
87
+ if (selectedItem) {
88
+ setTimeout(() => {
89
+ onTabPress(selectedItem.key);
90
+ });
91
+ }
92
+ indexRef.current = index;
93
+ }}
94
+ scrollEnabled={swipeEnabled}
95
+ >
96
+ {tabs.map((tab, index) => {
97
+ const { key, component, testID } = tab;
98
+
99
+ return (
100
+ <ScreenContext.Provider value={key}>
101
+ <SceneView
102
+ testID={testID}
103
+ key={key}
104
+ index={index}
105
+ selectedIndex={indexRef.current}
106
+ lazy={lazy}
107
+ lazyPreloadDistance={lazyPreloadDistance}
108
+ >
109
+ {component}
110
+ </SceneView>
111
+ </ScreenContext.Provider>
112
+ );
113
+ })}
114
+ </ContentWrapper>
115
+ </TabContainer>
116
+ </TabContext.Provider>
117
+ );
118
+ };
119
+
120
+ export default ScrollableTab;
@@ -0,0 +1,76 @@
1
+ import React from 'react';
2
+ import { ThemeProvider } from '@emotion/react';
3
+ import renderWithTheme from '../../../../testHelpers/renderWithTheme';
4
+ import ScenceView from '../SceneView';
5
+ import Typography from '../../../Typography';
6
+ import { theme } from '../../../../index';
7
+
8
+ describe('ScenceView', () => {
9
+ describe('lazy', () => {
10
+ it('renders child correctly when the scence is focused and should not unmount if selected index changed to index which is out of lazyPreloadDistance', () => {
11
+ const { getByText, toJSON, queryByText, rerender } = renderWithTheme(
12
+ <ScenceView
13
+ testID="scene-view"
14
+ index={0}
15
+ selectedIndex={0}
16
+ lazy
17
+ lazyPreloadDistance={1}
18
+ >
19
+ <Typography.Text>Scene 1</Typography.Text>
20
+ </ScenceView>
21
+ );
22
+
23
+ expect(toJSON()).toMatchSnapshot();
24
+ expect(getByText('Scene 1')).toBeDefined();
25
+
26
+ rerender(
27
+ <ThemeProvider theme={theme}>
28
+ <ScenceView
29
+ testID="scene-view"
30
+ index={0}
31
+ selectedIndex={2}
32
+ lazy
33
+ lazyPreloadDistance={1}
34
+ >
35
+ <Typography.Text>Scene 1</Typography.Text>
36
+ </ScenceView>
37
+ </ThemeProvider>
38
+ );
39
+ expect(toJSON()).toMatchSnapshot();
40
+ expect(queryByText('Scene 1')).toBeDefined();
41
+ });
42
+
43
+ it('not renders child correctly when the scence is lazy and renders when selectedIndex change to 1', () => {
44
+ const { rerender, queryByText, toJSON } = renderWithTheme(
45
+ <ScenceView
46
+ testID="scene-view"
47
+ index={2}
48
+ selectedIndex={0}
49
+ lazy
50
+ lazyPreloadDistance={1}
51
+ >
52
+ <Typography.Text>Scene 1</Typography.Text>
53
+ </ScenceView>
54
+ );
55
+
56
+ expect(toJSON()).toMatchSnapshot();
57
+ expect(queryByText('Scene 1')).toBeNull();
58
+
59
+ rerender(
60
+ <ThemeProvider theme={theme}>
61
+ <ScenceView
62
+ testID="scene-view"
63
+ index={2}
64
+ selectedIndex={1}
65
+ lazy
66
+ lazyPreloadDistance={1}
67
+ >
68
+ <Typography.Text>Scene 1</Typography.Text>
69
+ </ScenceView>
70
+ </ThemeProvider>
71
+ );
72
+ expect(toJSON()).toMatchSnapshot();
73
+ expect(queryByText('Scene 1')).toBeDefined();
74
+ });
75
+ });
76
+ });
@@ -0,0 +1,166 @@
1
+ import React from 'react';
2
+ import { Text } from 'react-native';
3
+ import { fireEvent, waitFor } from '@testing-library/react-native';
4
+ import { SafeAreaProvider } from 'react-native-safe-area-context';
5
+ import type { ComponentProps } from 'react';
6
+ import renderWithTheme from '../../../../testHelpers/renderWithTheme';
7
+ import ScrollableTabsV2 from '..';
8
+ import Button from '../../../Button';
9
+ import type { TabType } from '../..';
10
+
11
+ const CustomScreen = ({ title }: { title: string }) => {
12
+ const isFocused = ScrollableTabsV2.useIsFocused();
13
+ // console.error('render ' + title);
14
+ return (
15
+ <Text>
16
+ {title} {isFocused ? 'focused' : 'unfocused'}
17
+ </Text>
18
+ );
19
+ };
20
+ const TestTabsComponent = (
21
+ props: Omit<
22
+ ComponentProps<typeof ScrollableTabsV2>,
23
+ 'selectedTabKey' | 'onTabPress' | 'tabs'
24
+ >
25
+ ) => {
26
+ const [selectedTabKey, setSelectedTabKey] = React.useState('work');
27
+ const tabs: TabType[] = [
28
+ {
29
+ key: 'work',
30
+ activeItem: 'Work',
31
+ component: <CustomScreen title="Work Screen" />,
32
+ },
33
+ {
34
+ key: 'personal',
35
+ activeItem: 'speaker',
36
+ inactiveItem: 'speaker-outlined',
37
+ component: <CustomScreen title="Personal Screen" />,
38
+ },
39
+ {
40
+ key: 'home',
41
+ activeItem: 'home',
42
+ inactiveItem: 'home-outlined',
43
+ component: <CustomScreen title="Home Screen" />,
44
+ badge: {
45
+ type: 'status',
46
+ },
47
+ },
48
+ {
49
+ key: 'calendar',
50
+ activeItem: 'calendar',
51
+ inactiveItem: 'calendar-dates-outlined',
52
+ component: <CustomScreen title="Calendar Screen" />,
53
+ badge: {
54
+ type: 'counter',
55
+ value: 50,
56
+ },
57
+ },
58
+ ];
59
+
60
+ return (
61
+ <SafeAreaProvider
62
+ initialMetrics={{
63
+ frame: { x: 0, y: 0, width: 0, height: 0 },
64
+ insets: { top: 0, left: 0, right: 0, bottom: 0 },
65
+ }}
66
+ >
67
+ <Button.Utility
68
+ text="Move to Work"
69
+ onPress={() => setSelectedTabKey('work')}
70
+ icon="sync"
71
+ />
72
+ <ScrollableTabsV2
73
+ {...props}
74
+ tabs={tabs}
75
+ selectedTabKey={selectedTabKey}
76
+ onTabPress={(newTabKey) => setSelectedTabKey(newTabKey)}
77
+ />
78
+ </SafeAreaProvider>
79
+ );
80
+ };
81
+
82
+ describe('Tabs.ScrollV2', () => {
83
+ it('renders correctly', async () => {
84
+ const { getByTestId, getByText, toJSON } = renderWithTheme(
85
+ <TestTabsComponent />
86
+ );
87
+
88
+ expect(toJSON()).toMatchSnapshot();
89
+ expect(getByText('Work')).toBeDefined();
90
+ expect(getByTestId('hero-icon-speaker-outlined')).toBeDefined();
91
+ expect(getByTestId('hero-icon-home-outlined')).toBeDefined();
92
+ expect(getByText('Work Screen focused')).toBeDefined();
93
+ expect(getByText('Personal Screen unfocused')).toBeDefined();
94
+ await waitFor(() =>
95
+ expect(getByText('Home Screen unfocused')).toBeDefined()
96
+ );
97
+
98
+ expect(getByText('Home Screen unfocused')).toBeDefined();
99
+ expect(getByText('Calendar Screen unfocused')).toBeDefined();
100
+ });
101
+
102
+ describe('lazy', () => {
103
+ it('render all screens when lazy = false', async () => {
104
+ const { queryByText } = renderWithTheme(
105
+ <TestTabsComponent lazy={false} />
106
+ );
107
+ expect(queryByText('Work Screen focused')).toBeDefined();
108
+ expect(queryByText('Personal Screen unfocused')).toBeDefined();
109
+ await waitFor(() =>
110
+ expect(queryByText('Home Screen unfocused')).toBeDefined()
111
+ );
112
+ expect(queryByText('Home Screen unfocused')).toBeDefined();
113
+ expect(queryByText('Calendar Screen unfocused')).toBeDefined();
114
+ });
115
+
116
+ it('not render lazy screen', async () => {
117
+ const { toJSON, queryByText } = renderWithTheme(
118
+ <TestTabsComponent lazyPreloadDistance={1} lazy />
119
+ );
120
+ expect(queryByText('Work Screen focused')).toBeDefined();
121
+ expect(queryByText('Personal Screen unfocused')).toBeDefined();
122
+ await waitFor(() =>
123
+ expect(queryByText('Home Screen unfocused')).toBeDefined()
124
+ );
125
+ expect(toJSON()).toMatchSnapshot('xxx');
126
+ expect(queryByText('Home Screen unfocused')).toBeDefined();
127
+ expect(queryByText('Calendar Screen unfocused')).toBeNull();
128
+ });
129
+ });
130
+ });
131
+
132
+ describe('useIsFocused', () => {
133
+ it('renders correctly', () => {
134
+ const { getByTestId, getByText, toJSON } = renderWithTheme(
135
+ <TestTabsComponent lazyPreloadDistance={4} />
136
+ );
137
+
138
+ expect(toJSON()).toMatchSnapshot();
139
+ expect(getByText('Work')).toBeDefined();
140
+ expect(getByTestId('hero-icon-speaker-outlined')).toBeDefined();
141
+ expect(getByTestId('hero-icon-home-outlined')).toBeDefined();
142
+ expect(getByText('Work Screen focused')).toBeDefined();
143
+ expect(getByText('Personal Screen unfocused')).toBeDefined();
144
+ expect(getByText('Home Screen unfocused')).toBeDefined();
145
+ expect(getByText('Calendar Screen unfocused')).toBeDefined();
146
+
147
+ fireEvent.press(getByTestId('hero-icon-speaker-outlined'));
148
+ expect(getByText('Personal Screen focused')).toBeDefined();
149
+ expect(getByText('Work Screen unfocused')).toBeDefined();
150
+ expect(getByText('Home Screen unfocused')).toBeDefined();
151
+ expect(getByText('Calendar Screen unfocused')).toBeDefined();
152
+
153
+ fireEvent.press(getByTestId('hero-icon-home-outlined'));
154
+ expect(getByText('Personal Screen unfocused')).toBeDefined();
155
+ expect(getByText('Work Screen unfocused')).toBeDefined();
156
+ expect(getByText('Home Screen focused')).toBeDefined();
157
+ expect(getByText('Calendar Screen unfocused')).toBeDefined();
158
+
159
+ fireEvent.press(getByTestId('hero-icon-calendar-dates-outlined'));
160
+ expect(getByText('Personal Screen unfocused')).toBeDefined();
161
+ expect(getByText('Work Screen unfocused')).toBeDefined();
162
+ expect(getByText('Home Screen unfocused')).toBeDefined();
163
+ expect(getByText('Calendar Screen focused')).toBeDefined();
164
+ expect(getByText('50')).toBeDefined();
165
+ });
166
+ });
@@ -0,0 +1,161 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`ScenceView lazy not renders child correctly when the scence is lazy and renders when selectedIndex change to 1 1`] = `
4
+ <View
5
+ accessibilityElementsHidden={true}
6
+ importantForAccessibility="no-hide-descendants"
7
+ style={
8
+ Array [
9
+ Object {
10
+ "flex": 1,
11
+ },
12
+ Array [
13
+ Object {
14
+ "flex": 1,
15
+ "overflow": "hidden",
16
+ },
17
+ null,
18
+ ],
19
+ ]
20
+ }
21
+ testID="scene-view"
22
+ />
23
+ `;
24
+
25
+ exports[`ScenceView lazy not renders child correctly when the scence is lazy and renders when selectedIndex change to 1 2`] = `
26
+ <View
27
+ accessibilityElementsHidden={true}
28
+ importantForAccessibility="no-hide-descendants"
29
+ style={
30
+ Array [
31
+ Object {
32
+ "flex": 1,
33
+ },
34
+ Array [
35
+ Object {
36
+ "flex": 1,
37
+ "overflow": "hidden",
38
+ },
39
+ null,
40
+ ],
41
+ ]
42
+ }
43
+ testID="scene-view"
44
+ >
45
+ <Text
46
+ allowFontScaling={false}
47
+ style={
48
+ Array [
49
+ Object {
50
+ "color": "#001f23",
51
+ "fontFamily": "BeVietnamPro-Regular",
52
+ "fontSize": 14,
53
+ "letterSpacing": 0.42,
54
+ "lineHeight": 22,
55
+ },
56
+ undefined,
57
+ ]
58
+ }
59
+ themeFontSize="medium"
60
+ themeFontWeight="regular"
61
+ themeIntent="body"
62
+ themeTypeface="neutral"
63
+ >
64
+ Scene 1
65
+ </Text>
66
+ </View>
67
+ `;
68
+
69
+ exports[`ScenceView lazy renders child correctly when the scence is focused and should not unmount if selected index changed to index which is out of lazyPreloadDistance 1`] = `
70
+ <View
71
+ accessibilityElementsHidden={false}
72
+ importantForAccessibility="auto"
73
+ style={
74
+ Array [
75
+ Object {
76
+ "flex": 1,
77
+ },
78
+ Array [
79
+ Object {
80
+ "flex": 1,
81
+ "overflow": "hidden",
82
+ },
83
+ Object {
84
+ "bottom": 0,
85
+ "left": 0,
86
+ "position": "absolute",
87
+ "right": 0,
88
+ "top": 0,
89
+ },
90
+ ],
91
+ ]
92
+ }
93
+ testID="scene-view"
94
+ >
95
+ <Text
96
+ allowFontScaling={false}
97
+ style={
98
+ Array [
99
+ Object {
100
+ "color": "#001f23",
101
+ "fontFamily": "BeVietnamPro-Regular",
102
+ "fontSize": 14,
103
+ "letterSpacing": 0.42,
104
+ "lineHeight": 22,
105
+ },
106
+ undefined,
107
+ ]
108
+ }
109
+ themeFontSize="medium"
110
+ themeFontWeight="regular"
111
+ themeIntent="body"
112
+ themeTypeface="neutral"
113
+ >
114
+ Scene 1
115
+ </Text>
116
+ </View>
117
+ `;
118
+
119
+ exports[`ScenceView lazy renders child correctly when the scence is focused and should not unmount if selected index changed to index which is out of lazyPreloadDistance 2`] = `
120
+ <View
121
+ accessibilityElementsHidden={true}
122
+ importantForAccessibility="no-hide-descendants"
123
+ style={
124
+ Array [
125
+ Object {
126
+ "flex": 1,
127
+ },
128
+ Array [
129
+ Object {
130
+ "flex": 1,
131
+ "overflow": "hidden",
132
+ },
133
+ null,
134
+ ],
135
+ ]
136
+ }
137
+ testID="scene-view"
138
+ >
139
+ <Text
140
+ allowFontScaling={false}
141
+ style={
142
+ Array [
143
+ Object {
144
+ "color": "#001f23",
145
+ "fontFamily": "BeVietnamPro-Regular",
146
+ "fontSize": 14,
147
+ "letterSpacing": 0.42,
148
+ "lineHeight": 22,
149
+ },
150
+ undefined,
151
+ ]
152
+ }
153
+ themeFontSize="medium"
154
+ themeFontWeight="regular"
155
+ themeIntent="body"
156
+ themeTypeface="neutral"
157
+ >
158
+ Scene 1
159
+ </Text>
160
+ </View>
161
+ `;