/* eslint-disable react-native/no-unused-styles */ import React, { useCallback, useMemo, useRef } from "react"; import { FlatList, View, ImageBackground } from "react-native"; import * as R from "ramda"; import { useConfiguration } from "@applicaster/zapp-react-native-utils/reactHooks/configuration"; import { noop } from "@applicaster/zapp-react-native-utils/functionUtils"; import { isEmptyOrNil } from "@applicaster/zapp-react-native-utils/cellUtils"; import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager"; import { FocusableGroup } from "@applicaster/zapp-react-native-ui-components/Components/FocusableGroup"; import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable"; import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks"; import { Gutter } from "../Gutter"; import Tab from "./Tab"; import { getStyles } from "./styles"; import { getId, scrollToSelectedIndex as scrollToSelectedIndexFn, generateFocusableId, applyFontConfig, } from "./utils"; const VIEW_POSITION = 0.5; const TabsComponent = ({ entry, groupId, id, parentFocus, style, selectedEntryIndex, setSelectedEntry, accessibility, }: TabsProps & Partial) => { const configuration = useConfiguration(); const config = applyFontConfig(configuration); const styles = useMemo(() => getStyles(config), [config]); const accessibilityManager = useAccessibilityManager({}); const { tab_bar_gutter: horizontalGutter, tab_bar_background_image: bgImage, component_padding_left: componentPaddingLeft, component_padding_right: componentPaddingRight, tab_bar_item_width: itemWidth, } = config; const { tabs, tabsWrapper, tabsBackground, tabsListWrapper, tabsListContentContainer, } = styles; const flatListRef = useRef(null); const selectedItem = useRef(null); const entryLength = R.length(entry); const scrollToSelectedIndex = useMemo( () => scrollToSelectedIndexFn(flatListRef, config, entryLength), [config] ); const onListElementFocus = useCallback( (index, isSelected: boolean, item: ZappEntry) => { if (isSelected) { accessibilityManager.readText({ text: `${accessibility?.selectedHint} ${item.title}`, }); } else { accessibilityManager.readText({ text: `${accessibility?.hint} ${item.title}`, }); } scrollToSelectedIndex(index, VIEW_POSITION); }, [scrollToSelectedIndex, accessibility] ); const renderItem = useCallback( ({ item, index }) => { const itemId = generateFocusableId(getId(item)); const isSelected = R.equals(index, selectedEntryIndex); const focusableId = `${id}-${itemId}`; if (isSelected && selectedItem?.current !== focusableId) { selectedItem.current = focusableId; } const isLast = R.equals(index, entryLength - 1); const isFirst = R.equals(index, 0); const style = { paddingLeft: isFirst ? Number(componentPaddingLeft) : 0, paddingRight: isLast ? Number(componentPaddingRight) : 0, marginLeft: isFirst ? -Number(componentPaddingLeft) : 0, marginRight: isLast ? -Number(componentPaddingRight) : 0, }; return ( onListElementFocus(index, isSelected, item)} onPress={() => setSelectedEntry && setSelectedEntry(item)} style={style} > {(focused) => ( )} ); }, [onListElementFocus, id, selectedEntryIndex] ); const renderGutter = useCallback( () => , [horizontalGutter] ); const onLayoutChange = useCallback(() => { scrollToSelectedIndex(selectedEntryIndex, VIEW_POSITION); }, [scrollToSelectedIndex, selectedEntryIndex]); const getItemLayout = useCallback( (_data, index) => ({ length: itemWidth, offset: (itemWidth + (horizontalGutter || 0)) * index, index, }), [itemWidth, horizontalGutter] ); React.useEffect(() => { const currentFocusElement = focusManager.getCurrentFocus(); if (!currentFocusElement && selectedItem.current) { focusManager.setFocus(selectedItem.current); } }, []); return ( { accessibilityManager.addHeading(accessibility?.announcement); }} > ); }; export const Tabs = React.memo(TabsComponent);