/* eslint-disable react-native/no-unused-styles */
import * as React from "react";
import * as R from "ramda";
import { FlatList, Platform, StyleSheet, View } from "react-native";
import { Gutter } from "./Gutter";
import Tab from "./Tab";
import { getOpacityFromHexColor } from "@applicaster/zapp-react-native-utils/configurationUtils";
import { useIsRTL } from "@applicaster/zapp-react-native-utils/localizationUtils";
import { useConfiguration } from "@applicaster/zapp-react-native-utils/reactHooks/configuration";
type RenderItemProps = {
item: ZappEntry;
index: number;
};
type FlexAlignment = "flex-start" | "center" | "flex-end";
const CUSTOM_KEY = "other";
const getTabsFlexAlignment = (tabsAlignment: string): FlexAlignment => {
switch (tabsAlignment) {
case "left":
return "flex-start";
case "center":
return "center";
case "right":
return "flex-end";
default:
return "flex-start";
}
};
const getStyles = ({
tab_bar_background_color,
tab_bar_border_bottom_width,
tab_bar_border_bottom_color,
tab_bar_padding_left,
tab_bar_padding_right,
tab_bar_elevation,
display_mode_tabs_alignment,
tab_bar_shadow_color,
tab_bar_shadow_offset_height,
tab_bar_shadow_offset_width,
tab_bar_shadow_radius,
}) => {
const iosStyles = {
shadowColor: tab_bar_shadow_color,
shadowOffset: {
height: tab_bar_shadow_offset_height,
width: tab_bar_shadow_offset_width,
},
shadowOpacity: getOpacityFromHexColor(tab_bar_shadow_color),
shadowRadius: tab_bar_shadow_radius,
zIndex: 10,
};
const androidStyles = { elevation: tab_bar_elevation };
return StyleSheet.create({
container: {
backgroundColor: tab_bar_background_color,
borderBottomWidth: tab_bar_border_bottom_width,
borderBottomColor: tab_bar_border_bottom_color,
...(Platform.OS === "ios" ? iosStyles : androidStyles),
},
contentContainer: {
flexGrow: 1,
justifyContent: getTabsFlexAlignment(display_mode_tabs_alignment),
paddingLeft: tab_bar_padding_left,
paddingRight: tab_bar_padding_right,
},
fractionalWrapper: {
flexDirection: "row",
paddingLeft: tab_bar_padding_left,
paddingRight: tab_bar_padding_right,
},
});
};
type Props = {
tabs: [ZappEntry];
activeTab: ZappEntry;
setActiveTab: (ZappEntry) => void;
onTabsSelectorLayout: (number) => void;
};
const TabsComponent = ({
tabs,
activeTab,
setActiveTab,
onTabsSelectorLayout,
}: Props) => {
const isRTL = useIsRTL();
const configuration = useConfiguration();
const scrollViewRef = React.useRef(null);
const tabRefs = React.useRef([]);
const {
tab_bar_gutter,
display_mode,
text_label_data_key,
text_label_custom_data_key,
} = configuration;
const styles = React.useMemo(() => getStyles(configuration), []);
const scrollToItem = React.useCallback(
(index) => {
scrollViewRef.current.scrollToIndex({
index: Platform.select({
ios: isRTL ? tabs?.length - index - 1 : index,
android: index,
}),
viewPosition: 0.5,
viewOffset: tab_bar_gutter / 2,
});
},
[tabs, tab_bar_gutter]
);
const onTabPress = React.useCallback(
(item, index) => {
setActiveTab(item);
if (display_mode === "dynamic" || display_mode === "fixed") {
scrollToItem(index);
}
},
[display_mode, scrollToItem, setActiveTab]
);
const getTitle = React.useCallback(
(item: ZappEntry): string => {
const titlePath = R.split(
".",
text_label_data_key === CUSTOM_KEY
? text_label_custom_data_key
: text_label_data_key
);
return R.path(titlePath, item);
},
[text_label_data_key, text_label_custom_data_key]
);
const getSelectedItem = React.useCallback(
(id) => {
return R.propEq("id", id)(activeTab);
},
[activeTab]
);
const renderGutter = React.useCallback(
() => ,
[tab_bar_gutter]
);
const renderItem = React.useCallback(
({ item, index, item: { id } }: RenderItemProps) => (
{
tabRefs.current[index] = ref;
}}
{...{
title: getTitle(item),
id,
handleOnPress: () => {
onTabPress(item, index);
},
selected: getSelectedItem(id),
configuration,
}}
/>
{display_mode === "fractional" &&
index !== tabs?.length - 1 &&
renderGutter()}
),
[tabs, display_mode, configuration, onTabPress, getTitle, getSelectedItem]
);
const keyExtractor = React.useCallback(R.compose(String, R.prop("id")), []);
if (display_mode === "fractional") {
return (
{tabs?.map((item, index) => renderItem({ item, index }))}
);
}
return (
);
};
export const Tabs = React.memo(TabsComponent);