@applicaster/zapp-react-native-ui-components 13.0.0-alpha.7586259907 → 13.0.0-alpha.7620873141

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 (31) hide show
  1. package/Components/Cell/CellWithFocusable.tsx +4 -2
  2. package/Components/Cell/CellWrapper.tsx +18 -0
  3. package/Components/CellRendererResolver/index.ts +2 -1
  4. package/Components/Layout/TV/LayoutBackground.tsx +28 -0
  5. package/Components/Layout/TV/ScreenContainer.tsx +0 -1
  6. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +15 -10
  7. package/Components/Layout/TV/__tests__/index.test.tsx +8 -2
  8. package/Components/Layout/TV/index.tsx +6 -20
  9. package/Components/Layout/TV/index.web.tsx +4 -1
  10. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
  11. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
  12. package/Components/ModalComponent/BottomSheetModalContent.tsx +45 -19
  13. package/Components/ModalComponent/Button/Item.tsx +6 -5
  14. package/Components/ModalComponent/Button/index.tsx +29 -42
  15. package/Components/ModalComponent/utils.ts +55 -7
  16. package/Components/PlayerContainer/PlayerContainer.tsx +16 -1
  17. package/Components/River/RiverItem.tsx +2 -1
  18. package/Components/TopMarginApplicator/TopMarginApplicator.tsx +2 -3
  19. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +4 -2
  20. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +21 -9
  21. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +8 -1
  22. package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
  23. package/Components/VideoModal/ModalAnimation/const.ts +5 -0
  24. package/Components/VideoModal/ModalAnimation/index.ts +2 -0
  25. package/Components/VideoModal/ModalAnimation/utils.ts +36 -0
  26. package/Components/VideoModal/PlayerDetails.tsx +9 -4
  27. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -40
  28. package/Components/VideoModal/utils.ts +3 -4
  29. package/Components/ZappUIComponent/index.tsx +4 -4
  30. package/package.json +5 -5
  31. package/Components/Cell/CellWrapper.ts +0 -5
@@ -23,6 +23,8 @@ type Props = {
23
23
  focused?: boolean;
24
24
  };
25
25
 
26
+ const addPrefix = (id: string) => `focusable-cell-wrapper-${id}`;
27
+
26
28
  export function CellWithFocusable(props: Props) {
27
29
  const {
28
30
  index,
@@ -81,7 +83,7 @@ export function CellWithFocusable(props: Props) {
81
83
 
82
84
  return (
83
85
  <FocusableGroup
84
- id={`focusable-cell-wrapper-${id}`}
86
+ id={addPrefix(id)}
85
87
  testID={"cell-with-focusable-cell-renderer-focusable-group"}
86
88
  groupId={groupId}
87
89
  preferredFocus={preferredFocus}
@@ -94,7 +96,7 @@ export function CellWithFocusable(props: Props) {
94
96
  <CellRenderer
95
97
  testID={"cell-with-focusable-cell-renderer"}
96
98
  item={item}
97
- groupId={`focusable-cell-wrapper-${id}`}
99
+ groupId={addPrefix(id)}
98
100
  onToggleFocus={handleToggleFocus}
99
101
  state={state}
100
102
  prefixId={id}
@@ -0,0 +1,18 @@
1
+ import * as React from "react";
2
+ import { View, ViewStyle } from "react-native";
3
+ import { isTvOSPlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
4
+
5
+ const isTvOS = isTvOSPlatform();
6
+
7
+ type Props = {
8
+ style: ViewStyle;
9
+ children: React.ReactNode;
10
+ };
11
+
12
+ export const CellWrapper = ({ style, children }: Props) => {
13
+ if (isTvOS) {
14
+ return <View style={style}>{children}</View>;
15
+ }
16
+
17
+ return <>{children}</>;
18
+ };
@@ -1,4 +1,5 @@
1
1
  import { findPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
2
+ import { isGroup } from "@applicaster/zapp-react-native-utils/componentsUtils";
2
3
 
3
4
  import { componentsLogger } from "../../Helpers/logger";
4
5
  import defaultCellRenderer from "../default-cell-renderer";
@@ -80,7 +81,7 @@ export function CellRendererResolver({
80
81
  }: Props) {
81
82
  const cellRendererPlugin = getRendererPlugin(component, plugins, cellStyles);
82
83
 
83
- if (!cellRendererPlugin && component.component_type !== "group-qb") {
84
+ if (!cellRendererPlugin && !isGroup(component)) {
84
85
  logger.warning({
85
86
  message: "Could not resolve cell builder plugin",
86
87
  data: { component },
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks/usePickFromState";
3
+ import { getBackgroundImageUrl } from "../utils";
4
+ import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
5
+
6
+ export const LayoutBackground = ({
7
+ Background,
8
+ children,
9
+ }: {
10
+ Background: React.ComponentType<any>;
11
+ children: React.ReactNode;
12
+ }) => {
13
+ const theme = useTheme();
14
+
15
+ const { remoteConfigurations } = usePickFromState(["remoteConfigurations"]);
16
+
17
+ const backgroundColor = theme.app_background_color;
18
+ const backgroundImageUrl = getBackgroundImageUrl(remoteConfigurations);
19
+
20
+ return (
21
+ <Background
22
+ backgroundColor={backgroundColor}
23
+ backgroundImageUrl={backgroundImageUrl}
24
+ >
25
+ {children}
26
+ </Background>
27
+ );
28
+ };
@@ -22,7 +22,6 @@ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
22
22
  import { NavBarContainer } from "./NavBarContainer";
23
23
 
24
24
  type ComponentsExtraProps = {
25
- Background?: Record<string, any>;
26
25
  NavBar?: Record<string, any>;
27
26
  };
28
27
 
@@ -2,18 +2,23 @@
2
2
 
3
3
  exports[`Layout TV renders 1`] = `
4
4
  <View
5
- excludeFromFocusSearching={true}
6
- id="/river/A1234"
7
- preferredFocus={true}
5
+ backgroundColor="#000000"
6
+ testID="background-component"
8
7
  >
9
8
  <View
10
- Components={
11
- {
12
- "Background": [Function],
13
- "NavBar": [Function],
9
+ excludeFromFocusSearching={true}
10
+ id="/river/A1234"
11
+ preferredFocus={true}
12
+ >
13
+ <View
14
+ Components={
15
+ {
16
+ "Background": [Function],
17
+ "NavBar": [Function],
18
+ }
14
19
  }
15
- }
16
- route="/river/A1234"
17
- />
20
+ route="/river/A1234"
21
+ />
22
+ </View>
18
23
  </View>
19
24
  `;
@@ -5,6 +5,14 @@ import { render } from "@testing-library/react-native";
5
5
  import { Provider } from "react-redux";
6
6
  import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NavigationContext";
7
7
  import configureStore from "redux-mock-store";
8
+ import Layout from "../index.web";
9
+
10
+ // mock useTheme to provide app_background_color
11
+ jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
12
+ useTheme: () => ({
13
+ app_background_color: "#000000",
14
+ }),
15
+ }));
8
16
 
9
17
  const withoutChildren = omit(["children"]);
10
18
 
@@ -16,8 +24,6 @@ jest.mock("../../../Screen/TV/index.web", () => {
16
24
  };
17
25
  });
18
26
 
19
- const Layout = require("../index.web").default;
20
-
21
27
  const mockStore = configureStore()({
22
28
  appState: { appReady: true },
23
29
  });
@@ -1,10 +1,7 @@
1
1
  import * as React from "react";
2
- import * as R from "ramda";
3
2
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
4
3
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
5
- import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
6
4
 
7
- import { getBackgroundImageUrl } from "../utils";
8
5
  import { LayoutContainer } from "./LayoutContainer";
9
6
  import { ScreenContainer } from "./ScreenContainer";
10
7
 
@@ -12,6 +9,7 @@ import { ScreenLayoutContextProvider } from "./ScreenLayoutContextProvider";
12
9
  import { PathnameContext } from "../../../Contexts/PathnameContext";
13
10
  import { ScreenDataContext } from "../../../Contexts/ScreenDataContext";
14
11
  import { ScreenContextProvider } from "../../../Contexts/ScreenContext";
12
+ import { LayoutBackground } from "./LayoutBackground";
15
13
 
16
14
  type Components = {
17
15
  NavBar: React.ComponentType<any>;
@@ -19,7 +17,6 @@ type Components = {
19
17
  };
20
18
 
21
19
  type ComponentsExtraProps = {
22
- Background?: Record<string, any>;
23
20
  NavBar?: Record<string, any>;
24
21
  };
25
22
 
@@ -31,17 +28,10 @@ type Props = {
31
28
 
32
29
  const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
33
30
  const navigator = useNavigation();
34
- const theme = useTheme();
35
31
 
36
- const { appState: { appReady = false } = {}, remoteConfigurations } =
37
- usePickFromState(["appState", "remoteConfigurations", "plugins"]);
38
-
39
- const backgroundColor = React.useMemo(() => theme.app_background_color, []);
40
-
41
- const backgroundImageUrl = React.useMemo(
42
- () => getBackgroundImageUrl(remoteConfigurations),
43
- [remoteConfigurations]
44
- );
32
+ const { appState: { appReady = false } = {} } = usePickFromState([
33
+ "appState",
34
+ ]);
45
35
 
46
36
  if (!appReady) {
47
37
  return null;
@@ -50,11 +40,7 @@ const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
50
40
  return (
51
41
  <LayoutContainer>
52
42
  <ScreenLayoutContextProvider>
53
- <Components.Background
54
- backgroundColor={backgroundColor}
55
- backgroundImageUrl={backgroundImageUrl}
56
- {...R.omit(["ref"])(ComponentsExtraProps?.Background)}
57
- >
43
+ <LayoutBackground Background={Components.Background}>
58
44
  <ScreenDataContext.Provider value={navigator.data}>
59
45
  <PathnameContext.Provider value={navigator.currentRoute}>
60
46
  <ScreenContextProvider pathname={navigator.currentRoute}>
@@ -67,7 +53,7 @@ const Layout = ({ Components, ComponentsExtraProps, children }: Props) => {
67
53
  </ScreenContextProvider>
68
54
  </PathnameContext.Provider>
69
55
  </ScreenDataContext.Provider>
70
- </Components.Background>
56
+ </LayoutBackground>
71
57
  </ScreenLayoutContextProvider>
72
58
  </LayoutContainer>
73
59
  );
@@ -5,6 +5,7 @@ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
5
 
6
6
  import { ScreenLayoutContextProvider } from "./ScreenLayoutContextProvider";
7
7
  import { StackNavigator } from "../../Navigator";
8
+ import { LayoutBackground } from "./LayoutBackground";
8
9
 
9
10
  type Components = {
10
11
  NavBar: React.ComponentType<any>;
@@ -25,7 +26,9 @@ const Layout = ({ Components }: Props) => {
25
26
 
26
27
  return (
27
28
  <ScreenLayoutContextProvider>
28
- <StackNavigator Components={Components} />
29
+ <LayoutBackground Background={Components.Background}>
30
+ <StackNavigator Components={Components} />
31
+ </LayoutBackground>
29
32
  </ScreenLayoutContextProvider>
30
33
  );
31
34
  };
@@ -0,0 +1,3 @@
1
+ export const PREFIX = "tv_buttons";
2
+
3
+ export const BUTTON_PREFIX = `${PREFIX}_button`;
@@ -1,4 +1,4 @@
1
- import * as R from "ramda";
1
+ import { times } from "@applicaster/zapp-react-native-utils/utils";
2
2
  import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
3
3
 
4
4
  import { Button } from "./Button";
@@ -9,13 +9,14 @@ import {
9
9
  } from "./utils";
10
10
 
11
11
  import { compact } from "@applicaster/zapp-react-native-utils/cellUtils";
12
+ import { PREFIX, BUTTON_PREFIX } from "./const";
12
13
 
13
14
  export {
14
15
  insertButtonsBetweenLabels,
15
16
  insertButtonsBetweenLabelContainers,
16
17
  } from "./utils";
17
18
 
18
- const PREFIX = "tv_buttons";
19
+ const buttonId = (index: number) => `${BUTTON_PREFIX}_${index}`;
19
20
 
20
21
  type Props = {
21
22
  value: Function;
@@ -42,7 +43,6 @@ export const TvActionButtons = ({
42
43
  return null;
43
44
  }
44
45
 
45
- const prefix1Button = `${PREFIX}_button_1`;
46
46
  const independentStyles = value(`${PREFIX}_container_independent_styles`);
47
47
 
48
48
  return {
@@ -73,11 +73,11 @@ export const TvActionButtons = ({
73
73
  buttonsCount,
74
74
  },
75
75
  elements: compact(
76
- R.times((index) => {
77
- const prefixSpecificButton = `${PREFIX}_button_${index + 1}`;
76
+ times((index) => {
77
+ const prefixSpecificButton = buttonId(index + 1);
78
78
 
79
79
  return Button({
80
- prefix: independentStyles ? prefixSpecificButton : prefix1Button,
80
+ prefix: independentStyles ? prefixSpecificButton : buttonId(1),
81
81
  value,
82
82
  platformValue,
83
83
  pluginIdentifier: getPluginIdentifier(configuration, PREFIX, index),
@@ -10,13 +10,11 @@ import { Button } from "./Button";
10
10
  import { ItemIconProps } from "./Button/ItemIcon";
11
11
  import { ItemProps } from "./Button/Item";
12
12
  import { ItemLabelProps } from "./Button/ItemLabel";
13
- import {
14
- defaultItemIconProps,
15
- defaultItemLabelProps,
16
- defaultItemProps,
17
- } from "./utils";
13
+ import { getItemIconProps, getItemLabelProps, getItemProps } from "./utils";
18
14
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
19
15
 
16
+ import type { PluginConfiguration } from "./";
17
+
20
18
  import { ModalHeader } from "./Header";
21
19
 
22
20
  type ModalComponentProps = {
@@ -30,6 +28,20 @@ type ModalComponentProps = {
30
28
  maxHeight?: number;
31
29
  dismiss: () => void;
32
30
  buttonComponent?: React.ComponentType;
31
+ iconProps?: ItemIconProps | ((theme: PluginConfiguration) => ItemIconProps);
32
+ itemProps?:
33
+ | ItemProps
34
+ | ((theme: PluginConfiguration, width: number) => ItemProps);
35
+ labelProps?:
36
+ | ItemLabelProps
37
+ | ((theme: PluginConfiguration, width: number) => ItemLabelProps);
38
+ getSelectedItemIcon: (
39
+ theme: PluginConfiguration
40
+ ) => ItemIconProps["asset"] | null;
41
+ getDefaultItemIcon: (
42
+ theme: PluginConfiguration
43
+ ) => ItemIconProps["asset"] | null;
44
+ iconPlacement?: "left" | "right";
33
45
  };
34
46
 
35
47
  export function BottomSheetModalContent(props: ModalComponentProps) {
@@ -43,14 +55,20 @@ export function BottomSheetModalContent(props: ModalComponentProps) {
43
55
  summary,
44
56
  title,
45
57
  buttonComponent: ButtonComponent = Button,
58
+ getSelectedItemIcon = (theme) =>
59
+ theme.modal_bottom_sheet_item_selected_icon,
60
+ getDefaultItemIcon = () => null,
61
+ iconPlacement,
46
62
  } = props;
47
63
 
48
64
  const [headerHeight, setHeaderHeight] = useState(0);
49
65
  const route = useRef(currentRoute);
50
66
  const theme = useTheme<BaseThemePropertiesMobile>();
67
+ const paddingTop = Number(theme.modal_bottom_sheet_padding_top);
68
+ const paddingBottom = Number(theme.modal_bottom_sheet_padding_bottom);
51
69
 
52
70
  const maxContentHeight = maxHeight
53
- ? maxHeight - headerHeight - Number(theme.modal_bottom_sheet_padding_top)
71
+ ? maxHeight - headerHeight - paddingTop
54
72
  : undefined;
55
73
 
56
74
  const onHeaderLayout = useCallback((event: LayoutChangeEvent) => {
@@ -64,26 +82,30 @@ export function BottomSheetModalContent(props: ModalComponentProps) {
64
82
  }, [currentRoute]);
65
83
 
66
84
  const iconBaseProps = useMemo<ItemIconProps>(() => {
67
- return defaultItemIconProps(theme);
68
- }, [theme]);
85
+ return getItemIconProps(theme, props.iconProps);
86
+ }, [theme, props.iconProps]);
69
87
 
70
88
  const itemBaseProps = useMemo<ItemProps>(() => {
71
- return defaultItemProps(theme, props.width);
72
- }, [theme, props.width]);
89
+ return getItemProps(theme, props.width, props.itemProps);
90
+ }, [theme, props.width, props.itemProps]);
73
91
 
74
92
  const labelBaseProps = useMemo<ItemLabelProps>(() => {
75
- return defaultItemLabelProps(theme, props.width);
76
- }, [theme, props.width]);
93
+ return getItemLabelProps(theme, props.width, props.labelProps);
94
+ }, [theme, props.width, props.labelProps]);
77
95
 
78
- const handlePress = (item: any) => {
79
- onPress(item);
80
- dismiss();
81
- };
96
+ const handlePress = useCallback(
97
+ (item: any) => {
98
+ onPress(item);
99
+ dismiss();
100
+ },
101
+ [onPress, dismiss]
102
+ );
82
103
 
83
104
  return (
84
105
  <View
85
106
  style={{
86
- paddingTop: Number(theme.modal_bottom_sheet_padding_top),
107
+ maxWidth: props.width,
108
+ paddingTop,
87
109
  }}
88
110
  >
89
111
  <ModalHeader
@@ -98,8 +120,8 @@ export function BottomSheetModalContent(props: ModalComponentProps) {
98
120
  bounces={false}
99
121
  style={{ maxHeight: maxContentHeight }}
100
122
  contentContainerStyle={{
101
- paddingBottom: Number(theme.modal_bottom_sheet_padding_bottom),
102
- paddingTop: Number(theme.modal_bottom_sheet_padding_top),
123
+ paddingBottom,
124
+ paddingTop,
103
125
  }}
104
126
  >
105
127
  {items.map((item, index) => (
@@ -110,9 +132,13 @@ export function BottomSheetModalContent(props: ModalComponentProps) {
110
132
  selectedItem={current_selection}
111
133
  item={item}
112
134
  onPress={handlePress}
135
+ label={theme[item?.label] ?? item?.label}
113
136
  iconBaseProps={iconBaseProps}
114
137
  itemBaseProps={itemBaseProps}
115
138
  labelBaseProps={labelBaseProps}
139
+ selectedItemIcon={getSelectedItemIcon(theme)}
140
+ defaultItemIcon={getDefaultItemIcon(theme)}
141
+ iconPlacement={iconPlacement}
116
142
  />
117
143
  ))}
118
144
  </ScrollView>
@@ -5,7 +5,7 @@ export type ItemProps = {
5
5
  backgroundColor: string;
6
6
  focusedBackgroundColor: string;
7
7
  selectedBackgroundColor?: string;
8
- focusectedBackgroundColor?: string;
8
+ focusedSelectedBackgroundColor?: string;
9
9
  borderRadius: number;
10
10
  marginBottom: number;
11
11
  marginLeft: number;
@@ -15,6 +15,7 @@ export type ItemProps = {
15
15
  paddingBottom: number;
16
16
  paddingRight: number;
17
17
  paddingLeft: number;
18
+ maxWidth: number;
18
19
  focused?: boolean;
19
20
  selected?: boolean;
20
21
  children?: ReactChild[];
@@ -33,11 +34,11 @@ function getBackgroundColor({
33
34
  backgroundColor,
34
35
  focusedBackgroundColor,
35
36
  selectedBackgroundColor,
36
- focusectedBackgroundColor,
37
+ focusedSelectedBackgroundColor,
37
38
  }) {
38
39
  switch (true) {
39
40
  case selected && focused:
40
- return focusectedBackgroundColor;
41
+ return focusedSelectedBackgroundColor;
41
42
  case selected && !focused:
42
43
  return selectedBackgroundColor;
43
44
  case !selected && focused:
@@ -51,7 +52,7 @@ export function Item(props: ItemProps) {
51
52
  const {
52
53
  backgroundColor,
53
54
  focusedBackgroundColor,
54
- focusectedBackgroundColor,
55
+ focusedSelectedBackgroundColor,
55
56
  selectedBackgroundColor,
56
57
  children,
57
58
  focused,
@@ -68,7 +69,7 @@ export function Item(props: ItemProps) {
68
69
  backgroundColor: getBackgroundColor({
69
70
  selected,
70
71
  focused,
71
- focusectedBackgroundColor,
72
+ focusedSelectedBackgroundColor,
72
73
  focusedBackgroundColor,
73
74
  selectedBackgroundColor,
74
75
  backgroundColor,
@@ -3,7 +3,6 @@ import { StyleSheet, TouchableOpacity, View } from "react-native";
3
3
  import { Item, ItemProps } from "./Item";
4
4
  import { ItemIcon, ItemIconProps } from "./ItemIcon";
5
5
  import { ItemLabel, ItemLabelProps } from "./ItemLabel";
6
- import * as assets from "./assets";
7
6
  import { defaultSelectedAsset } from "./assets";
8
7
 
9
8
  type ButtonProps = {
@@ -17,6 +16,9 @@ type ButtonProps = {
17
16
  labelBaseProps?: ItemLabelProps;
18
17
  disabled?: boolean;
19
18
  label?: string | Record<string, string>;
19
+ iconPlacement?: "left" | "right";
20
+ selectedItemIcon?: ItemIconProps["asset"];
21
+ defaultItemIcon?: ItemIconProps["asset"];
20
22
  };
21
23
 
22
24
  const styles = StyleSheet.create({
@@ -33,52 +35,32 @@ export function Button({
33
35
  configuration,
34
36
  width,
35
37
  iconBaseProps,
36
- itemBaseProps,
38
+ itemBaseProps: itemProps,
37
39
  labelBaseProps,
38
40
  label,
41
+ iconPlacement = "left",
42
+ defaultItemIcon,
43
+ selectedItemIcon,
39
44
  disabled = false,
40
45
  }: ButtonProps) {
41
46
  const [focused, setFocused] = useState(false);
42
47
 
43
- const selected = useMemo(
44
- () => selectedItem && item.value === selectedItem?.value,
45
- [selectedItem, selectedItem]
46
- );
47
-
48
- const itemProps = useMemo<ItemProps>(
49
- () => ({
50
- ...itemBaseProps,
51
- width,
52
- }),
53
- [configuration, width]
54
- );
48
+ const selected = selectedItem && item.value === selectedItem?.value;
55
49
 
56
- const itemIconProps = useMemo<ItemIconProps>(
57
- () => ({
58
- ...iconBaseProps,
59
- asset: configuration[item.asset] ?? assets[item.asset] ?? item.asset,
60
- }),
61
- [configuration, item.asset]
50
+ const itemIconPropsAssets = useMemo<ItemIconProps["asset"]>(
51
+ () => configuration[item.asset] ?? item.asset ?? defaultItemIcon,
52
+ [item.asset, defaultItemIcon]
62
53
  );
63
54
 
64
- const selectedItemIconProps = useMemo<ItemIconProps>(
65
- () => ({
66
- ...iconBaseProps,
67
- asset:
68
- configuration["modal_bottom_sheet_item_selected_icon"] ||
69
- defaultSelectedAsset,
70
- marginRight: 10,
71
- }),
72
- [configuration]
55
+ const selectedItemIconPropsAssets = useMemo<ItemIconProps["asset"]>(
56
+ () => selectedItemIcon || defaultSelectedAsset,
57
+ [selectedItemIcon]
73
58
  );
74
59
 
75
- const itemLabelProps = useMemo<ItemLabelProps>(
76
- () => ({
77
- ...labelBaseProps,
78
- label: label ?? configuration[item?.label] ?? item?.label ?? null,
79
- }),
80
- [configuration, item?.label]
81
- );
60
+ const renderItemIcon =
61
+ itemIconPropsAssets && itemIconPropsAssets.length > 0 ? (
62
+ <ItemIcon {...iconBaseProps} asset={itemIconPropsAssets} />
63
+ ) : null;
82
64
 
83
65
  if (disabled) return null;
84
66
 
@@ -92,18 +74,23 @@ export function Button({
92
74
  >
93
75
  <Item {...itemProps} focused={focused} selected={selected}>
94
76
  <View style={styles.label_icon_container}>
95
- {itemIconProps.asset && itemIconProps.asset.length > 0 ? (
96
- <ItemIcon {...itemIconProps} />
97
- ) : null}
98
- {itemLabelProps.label ? (
77
+ {iconPlacement === "left" && renderItemIcon}
78
+
79
+ {label ? (
99
80
  <ItemLabel
100
- {...itemLabelProps}
81
+ {...labelBaseProps}
82
+ label={label ?? null}
101
83
  focused={focused}
102
84
  selected={selected}
103
85
  />
104
86
  ) : null}
105
87
  </View>
106
- {selected ? <ItemIcon {...selectedItemIconProps} /> : null}
88
+
89
+ {selected ? (
90
+ <ItemIcon {...iconBaseProps} asset={selectedItemIconPropsAssets} />
91
+ ) : (
92
+ iconPlacement === "right" && renderItemIcon
93
+ )}
107
94
  </Item>
108
95
  </TouchableOpacity>
109
96
  </View>
@@ -1,15 +1,18 @@
1
1
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
2
- import { PluginConfiguration } from "./index";
2
+ import { PluginConfiguration } from "./";
3
+ import { ItemIconProps } from "./Button/ItemIcon";
4
+ import { ItemLabelProps } from "./Button/ItemLabel";
5
+ import { ItemProps } from "./Button/Item";
3
6
 
4
7
  export function defaultItemProps(
5
8
  config: PluginConfiguration,
6
9
  maxWidth: number
7
- ) {
10
+ ): ItemProps {
8
11
  const {
9
12
  modal_bottom_sheet_item_background_color,
10
13
  modal_bottom_sheet_item_focus_background_color,
11
14
  modal_bottom_sheet_item_selected_background_color,
12
- modal_bottom_sheet_item_focusected_background_color,
15
+ modal_bottom_sheet_item_focused_selected_background_color,
13
16
  modal_bottom_sheet_item_corner_radius,
14
17
  modal_bottom_sheet_item_margin_bottom,
15
18
  modal_bottom_sheet_item_margin_left,
@@ -25,8 +28,8 @@ export function defaultItemProps(
25
28
  backgroundColor: modal_bottom_sheet_item_background_color,
26
29
  focusedBackgroundColor: modal_bottom_sheet_item_focus_background_color,
27
30
  selectedBackgroundColor: modal_bottom_sheet_item_selected_background_color,
28
- focusectedBackgroundColor:
29
- modal_bottom_sheet_item_focusected_background_color,
31
+ focusedSelectedBackgroundColor:
32
+ modal_bottom_sheet_item_focused_selected_background_color,
30
33
  borderRadius: modal_bottom_sheet_item_corner_radius,
31
34
  marginBottom: modal_bottom_sheet_item_margin_bottom,
32
35
  marginTop: modal_bottom_sheet_item_margin_top,
@@ -43,7 +46,7 @@ export function defaultItemProps(
43
46
  export function defaultItemLabelProps(
44
47
  config: PluginConfiguration,
45
48
  sheetWidth: number
46
- ) {
49
+ ): ItemLabelProps {
47
50
  const {
48
51
  modal_bottom_sheet_item_label_android_letter_spacing,
49
52
  modal_bottom_sheet_item_label_ios_letter_spacing,
@@ -103,7 +106,9 @@ export function defaultItemLabelProps(
103
106
  };
104
107
  }
105
108
 
106
- export function defaultItemIconProps(config: PluginConfiguration) {
109
+ export function defaultItemIconProps(
110
+ config: PluginConfiguration
111
+ ): ItemIconProps {
107
112
  const {
108
113
  modal_bottom_sheet_item_icon_height,
109
114
  modal_bottom_sheet_item_icon_width,
@@ -124,3 +129,46 @@ export function defaultItemIconProps(config: PluginConfiguration) {
124
129
  marginRight: modal_bottom_sheet_item_icon_margin_right,
125
130
  };
126
131
  }
132
+
133
+ export function getItemIconProps(
134
+ theme: PluginConfiguration,
135
+ iconProps?: ((theme: PluginConfiguration) => ItemIconProps) | ItemIconProps
136
+ ) {
137
+ if (iconProps) {
138
+ return typeof iconProps === "function" ? iconProps(theme) : iconProps;
139
+ }
140
+
141
+ return defaultItemIconProps(theme);
142
+ }
143
+
144
+ export function getItemLabelProps(
145
+ theme: PluginConfiguration,
146
+ width: number,
147
+ labelProps?:
148
+ | ((theme: PluginConfiguration, width: number) => ItemLabelProps)
149
+ | ItemLabelProps
150
+ ) {
151
+ if (labelProps) {
152
+ return typeof labelProps === "function"
153
+ ? labelProps(theme, width)
154
+ : labelProps;
155
+ }
156
+
157
+ return defaultItemLabelProps(theme, width);
158
+ }
159
+
160
+ export function getItemProps(
161
+ theme: PluginConfiguration,
162
+ width: number,
163
+ itemProps?:
164
+ | ((theme: PluginConfiguration, width: number) => ItemProps)
165
+ | ItemProps
166
+ ) {
167
+ if (itemProps) {
168
+ return typeof itemProps === "function"
169
+ ? itemProps(theme, width)
170
+ : itemProps;
171
+ }
172
+
173
+ return defaultItemProps(theme, width);
174
+ }
@@ -9,6 +9,7 @@ import {
9
9
  isApplePlatform,
10
10
  isTV,
11
11
  platformSelect,
12
+ isAndroidTVPlatform,
12
13
  } from "@applicaster/zapp-react-native-utils/reactUtils";
13
14
 
14
15
  import { TVEventHandlerComponent } from "@applicaster/zapp-react-native-tvos-ui-components/Components/TVEventHandlerComponent";
@@ -93,6 +94,20 @@ export type PlayNextData = {
93
94
 
94
95
  const focusableBottomContainerId = "player-container-bottom";
95
96
 
97
+ const isAndroidTV = isAndroidTVPlatform();
98
+
99
+ const withBorderHack = () => {
100
+ if (isAndroidTV) {
101
+ /* @HACK: see GH#7269 */
102
+ return {
103
+ borderWidth: 1,
104
+ borderColor: "transparent",
105
+ };
106
+ }
107
+
108
+ return {};
109
+ };
110
+
96
111
  // Styles
97
112
  const webStyles = {
98
113
  focusableGroup: {
@@ -648,7 +663,7 @@ const PlayerContainerComponent = (props: Props) => {
648
663
  style={[
649
664
  styles.playerWrapper,
650
665
  // eslint-disable-next-line react-native/no-inline-styles, react-native/no-color-literals
651
- { borderWidth: 1, borderColor: "transparent" },
666
+ withBorderHack(),
652
667
  ]}
653
668
  testID={"player-wrapper"}
654
669
  >
@@ -1,5 +1,6 @@
1
1
  import React, { useEffect } from "react";
2
2
  import * as R from "ramda";
3
+ import { isGroup } from "@applicaster/zapp-react-native-utils/componentsUtils";
3
4
 
4
5
  import { applyDecorators } from "../../Decorators";
5
6
 
@@ -112,7 +113,7 @@ function RiverItemComponent(props: RiverItemType) {
112
113
  jsOnly: true,
113
114
  });
114
115
 
115
- if (!CellRenderer && item.component_type !== "group-qb") {
116
+ if (!CellRenderer && !isGroup(item)) {
116
117
  riverLogger.warning({
117
118
  message: "Cell Renderer is null - will fallback to default cell",
118
119
  data: { item, CellRenderer },
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import { View, ViewProps, ViewStyle } from "react-native";
3
3
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
4
4
  import { useCurrentScreenData } from "@applicaster/zapp-react-native-utils/reactHooks";
5
+ import { isFirstComponentScreenPicker } from "@applicaster/zapp-react-native-utils/componentsUtils";
5
6
 
6
7
  interface IProps {
7
8
  targetScreenId?: string;
@@ -31,11 +32,9 @@ export const useMarginTop = (targetScreenId: string): number => {
31
32
  * ScreenPicker is a component but should really be a screen.
32
33
  * We need to skip margin top for it as it's already applied to the target screen
33
34
  **/
34
- const isScreenPicker =
35
- screenData?.ui_components?.[0]?.component_type === "screen-picker-qb-tv";
36
35
 
37
36
  // ignore margin on screenPicker
38
- if (isScreenPicker) {
37
+ if (isFirstComponentScreenPicker(screenData?.ui_components)) {
39
38
  return 0;
40
39
  }
41
40
 
@@ -23,10 +23,12 @@ import {
23
23
  setScrollModalAnimatedValue,
24
24
  } from "./utils";
25
25
 
26
+ import { DURATION_TO_MINIMIZE } from "./const";
27
+
26
28
  const getAnimatedConfig = (toValue) => {
27
29
  return {
28
30
  toValue,
29
- duration: 200,
31
+ duration: DURATION_TO_MINIMIZE,
30
32
  useNativeDriver: true,
31
33
  };
32
34
  };
@@ -142,7 +144,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
142
144
 
143
145
  setLastSnap(destSnapPoint);
144
146
 
145
- if (destSnapPoint === modalSnapPoints[0] && isMinimizedModal) {
147
+ if (destSnapPoint === modalSnapPoints[0]) {
146
148
  translateYOffset.extractOffset();
147
149
  translateYOffset.setValue(preparedTranslationY);
148
150
  translateYOffset.flattenOffset();
@@ -24,8 +24,11 @@ import {
24
24
  gestureListenerHelper,
25
25
  getAnimationDefaultValue,
26
26
  getAnimationStyle,
27
+ getMoveUpValue,
27
28
  } from "./utils";
28
29
 
30
+ import { DURATION_TO_MINIMIZE, DEFAULT_DURATION_FOR_ANIMATION } from "./const";
31
+
29
32
  type Props = {
30
33
  animationType: string;
31
34
  children: React.ReactNode;
@@ -97,14 +100,16 @@ export const AnimationView = ({
97
100
 
98
101
  const inlineAudioPlayer = additionalData.inlineAudioPlayer;
99
102
 
100
- const moveUpValue = additionalData.saveArea
101
- ? -insets.top + (isAudioItem ? 0 : progressBarHeight)
102
- : isTablet
103
- ? isTabletLandscape &&
104
- (!isAudioItem || (isAudioItem && inlineAudioPlayer))
105
- ? -tabletLandscapePlayerTopPosition + progressBarHeight
106
- : -130
107
- : -50 + progressBarHeight;
103
+ const moveUpValue = getMoveUpValue({
104
+ additionalData,
105
+ insets,
106
+ isAudioItem,
107
+ progressBarHeight,
108
+ isTablet,
109
+ isTabletLandscape,
110
+ inlineAudioPlayer,
111
+ tabletLandscapePlayerTopPosition,
112
+ });
108
113
 
109
114
  const moveComponentHorizontalValue = additionalData.moveValue
110
115
  ? isRTL
@@ -119,7 +124,10 @@ export const AnimationView = ({
119
124
  (animationType, state) => {
120
125
  const defaultConfig = {
121
126
  toValue: 0,
122
- duration: state === PlayerAnimationStateEnum.minimize ? 150 : 100,
127
+ duration:
128
+ state === PlayerAnimationStateEnum.minimize
129
+ ? DURATION_TO_MINIMIZE
130
+ : DEFAULT_DURATION_FOR_ANIMATION,
123
131
  useNativeDriver: true,
124
132
  };
125
133
 
@@ -440,6 +448,10 @@ export const AnimationComponent = (props: Props) => {
440
448
  videoModalState: { visible },
441
449
  } = useNavigation();
442
450
 
451
+ if (additionalData?.disableAnimatedComponent) {
452
+ return <>{props.children}</>;
453
+ }
454
+
443
455
  const useAnimation =
444
456
  visible && !additionalData.disableAnimatedComponent && !isTV();
445
457
 
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { useEffect } from "react";
2
2
  import { Animated } from "react-native";
3
3
 
4
4
  import {
@@ -95,6 +95,13 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
95
95
  setStartComponentsAnimation(false);
96
96
  }, []);
97
97
 
98
+ useEffect(() => {
99
+ // Reset player animation state when video modal is closed
100
+ if (!visible) {
101
+ resetPlayerAnimationState();
102
+ }
103
+ }, [visible, resetPlayerAnimationState]);
104
+
98
105
  // Animated values
99
106
  const lastScrollY = React.useRef(new Animated.Value(0)).current;
100
107
  const dragScrollY = React.useRef(new Animated.Value(0)).current;
@@ -0,0 +1,108 @@
1
+ import { getMoveUpValue } from "../utils";
2
+
3
+ describe("getMoveUpValue", () => {
4
+ it("returns correct value when additionalData.saveArea is true and isAudioItem is false", () => {
5
+ const result = getMoveUpValue({
6
+ additionalData: { saveArea: true },
7
+ insets: { top: 20 },
8
+ isAudioItem: false,
9
+ progressBarHeight: 10,
10
+ isTablet: false,
11
+ isTabletLandscape: false,
12
+ inlineAudioPlayer: false,
13
+ tabletLandscapePlayerTopPosition: 100,
14
+ });
15
+
16
+ expect(result).toBe(-20 + 10);
17
+ });
18
+
19
+ it("returns correct value when additionalData.saveArea is true and isAudioItem is true", () => {
20
+ const result = getMoveUpValue({
21
+ additionalData: { saveArea: true },
22
+ insets: { top: 15 },
23
+ isAudioItem: true,
24
+ progressBarHeight: 5,
25
+ isTablet: false,
26
+ isTabletLandscape: false,
27
+ inlineAudioPlayer: false,
28
+ tabletLandscapePlayerTopPosition: 100,
29
+ });
30
+
31
+ expect(result).toBe(-15 + 0);
32
+ });
33
+
34
+ it("returns correct value for audio item (tablet or not)", () => {
35
+ const result = getMoveUpValue({
36
+ additionalData: { marginTop: 30 },
37
+ insets: { top: 0 },
38
+ isAudioItem: true,
39
+ progressBarHeight: 0,
40
+ isTablet: false,
41
+ isTabletLandscape: false,
42
+ inlineAudioPlayer: false,
43
+ tabletLandscapePlayerTopPosition: 0,
44
+ });
45
+
46
+ expect(result).toBe(-30);
47
+ });
48
+
49
+ it("returns correct value for tablet landscape with inline audio player", () => {
50
+ const result = getMoveUpValue({
51
+ additionalData: {},
52
+ insets: { top: 0 },
53
+ isAudioItem: true,
54
+ progressBarHeight: 8,
55
+ isTablet: true,
56
+ isTabletLandscape: true,
57
+ inlineAudioPlayer: true,
58
+ tabletLandscapePlayerTopPosition: 50,
59
+ });
60
+
61
+ expect(result).toBe(-0);
62
+ });
63
+
64
+ it("returns correct value for tablet landscape without audio item", () => {
65
+ const result = getMoveUpValue({
66
+ additionalData: {},
67
+ insets: { top: 0 },
68
+ isAudioItem: false,
69
+ progressBarHeight: 12,
70
+ isTablet: true,
71
+ isTabletLandscape: true,
72
+ inlineAudioPlayer: false,
73
+ tabletLandscapePlayerTopPosition: 60,
74
+ });
75
+
76
+ expect(result).toBe(-60 + 12);
77
+ });
78
+
79
+ it("returns -130 for tablet portrait (not landscape)", () => {
80
+ const result = getMoveUpValue({
81
+ additionalData: {},
82
+ insets: { top: 0 },
83
+ isAudioItem: false,
84
+ progressBarHeight: 0,
85
+ isTablet: true,
86
+ isTabletLandscape: false,
87
+ inlineAudioPlayer: false,
88
+ tabletLandscapePlayerTopPosition: 0,
89
+ });
90
+
91
+ expect(result).toBe(-130);
92
+ });
93
+
94
+ it("returns -50 + progressBarHeight for mobile audio player in docked mode", () => {
95
+ const result = getMoveUpValue({
96
+ additionalData: {},
97
+ insets: { top: 0 },
98
+ isAudioItem: false,
99
+ progressBarHeight: 7,
100
+ isTablet: false,
101
+ isTabletLandscape: false,
102
+ inlineAudioPlayer: false,
103
+ tabletLandscapePlayerTopPosition: 0,
104
+ });
105
+
106
+ expect(result).toBe(-50 + 7);
107
+ });
108
+ });
@@ -0,0 +1,5 @@
1
+ export const DURATION_TO_MINIMIZE = 200; // old value 200
2
+
3
+ export const DURATION_TO_MAXIMIZE = 0;
4
+
5
+ export const DEFAULT_DURATION_FOR_ANIMATION = 200; // old value 100
@@ -14,3 +14,5 @@ export { useModalAnimationContext } from "./useModalAnimationContext";
14
14
  export { AnimationComponent } from "./AnimationComponent";
15
15
 
16
16
  export { ComponentAnimationType, defaultAspectRatioWidth } from "./utils";
17
+
18
+ export { DURATION_TO_MINIMIZE, DURATION_TO_MAXIMIZE } from "./const";
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable padding-line-between-statements */
2
2
 
3
3
  import { PlayerAnimationStateEnum } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
4
+ import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
4
5
 
5
6
  export enum ComponentAnimationType {
6
7
  bottomBar = "bottomBar",
@@ -300,3 +301,38 @@ export const resetScrollAnimatedValues = (
300
301
  dragScrollY.setValue(0);
301
302
  dragVideoPlayerY.setValue(0);
302
303
  };
304
+
305
+ export const getMoveUpValue = ({
306
+ additionalData,
307
+ insets,
308
+ isAudioItem,
309
+ progressBarHeight,
310
+ isTablet,
311
+ isTabletLandscape,
312
+ inlineAudioPlayer,
313
+ tabletLandscapePlayerTopPosition,
314
+ }) => {
315
+ if (additionalData.saveArea) {
316
+ return -insets.top + (isAudioItem ? 0 : progressBarHeight);
317
+ }
318
+
319
+ if (isAudioItem) {
320
+ // for any layouts in audioPlayer
321
+ return -1 * toNumberWithDefaultZero(additionalData?.marginTop);
322
+ }
323
+
324
+ if (isTablet) {
325
+ if (
326
+ isTabletLandscape &&
327
+ (!isAudioItem || (isAudioItem && inlineAudioPlayer))
328
+ ) {
329
+ return -tabletLandscapePlayerTopPosition + progressBarHeight;
330
+ }
331
+
332
+ // for audioPlayer(tablet/isTabletPortrait) in docked mode
333
+ return -130;
334
+ }
335
+
336
+ // for audioPlayer(mobile) in docked mode
337
+ return -50 + progressBarHeight;
338
+ };
@@ -10,6 +10,7 @@ import {
10
10
  import { useTargetScreenData } from "@applicaster/zapp-react-native-utils/reactHooks/screen";
11
11
  import { ComponentsMap } from "@applicaster/zapp-react-native-ui-components/Components/River/ComponentsMap";
12
12
  import { useSafeAreaInsets } from "react-native-safe-area-context";
13
+ import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
13
14
 
14
15
  const { width: SCREEN_WIDTH } = Dimensions.get("screen");
15
16
 
@@ -22,9 +23,9 @@ type Props = {
22
23
  entry: ZappEntry;
23
24
  style: StyleProp<ViewStyle>;
24
25
  configuration: Configuration;
25
- isTabletLandscape: boolean;
26
+ isTabletLandscape?: boolean;
26
27
  isAudioPlayer?: boolean;
27
- isTablet: boolean;
28
+ isTablet?: boolean;
28
29
  };
29
30
 
30
31
  const containerStyle = ({
@@ -39,9 +40,9 @@ export const PlayerDetails = ({
39
40
  entry,
40
41
  style,
41
42
  configuration,
42
- isTabletLandscape,
43
+ isTabletLandscape = false,
43
44
  isAudioPlayer,
44
- isTablet,
45
+ isTablet = false,
45
46
  }: Props) => {
46
47
  const screenData = useTargetScreenData(entry);
47
48
  const insets = useSafeAreaInsets();
@@ -78,6 +79,10 @@ export const PlayerDetails = ({
78
79
  }
79
80
  }, [isAudioPlayer]);
80
81
 
82
+ if (isNilOrEmpty(screenData?.ui_components)) {
83
+ return null;
84
+ }
85
+
81
86
  return (
82
87
  <Animated.View
83
88
  style={[
@@ -1,43 +1,5 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`PlayerDetails renders properly 1`] = `
4
- <View
5
- collapsable={false}
6
- style={
7
- {
8
- "backgroundColor": "transparent",
9
- "flex": 1,
10
- "marginTop": -8,
11
- "paddingTop": -8,
12
- "width": 750,
13
- }
14
- }
15
- >
16
- <View
17
- feed="test-source"
18
- riverComponents={[]}
19
- riverId="test-id"
20
- />
21
- </View>
22
- `;
3
+ exports[`PlayerDetails renders properly 1`] = `null`;
23
4
 
24
- exports[`PlayerDetails renders properly on tablet in landscape orientation 1`] = `
25
- <View
26
- collapsable={false}
27
- style={
28
- {
29
- "backgroundColor": "transparent",
30
- "flex": 1,
31
- "marginTop": -20,
32
- "paddingTop": 40,
33
- "width": 750,
34
- }
35
- }
36
- >
37
- <View
38
- feed="test-source"
39
- riverComponents={[]}
40
- riverId="test-id"
41
- />
42
- </View>
43
- `;
5
+ exports[`PlayerDetails renders properly on tablet in landscape orientation 1`] = `null`;
@@ -1,5 +1,4 @@
1
- import * as R from "ramda";
2
-
1
+ import { mergeRight } from "ramda";
3
2
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
4
3
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
4
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useNavigation";
@@ -25,10 +24,10 @@ export const useConfiguration = () => {
25
24
 
26
25
  const playerPluginConfig = playerManager.getPluginConfiguration();
27
26
 
28
- const config = R.mergeRight(playerPluginConfig, {
27
+ const config = mergeRight(playerPluginConfig, {
28
+ ...pluginConfiguration,
29
29
  ...targetScreenConfiguration?.general,
30
30
  ...targetScreenConfiguration?.styles,
31
- ...pluginConfiguration,
32
31
  });
33
32
 
34
33
  const {
@@ -8,7 +8,6 @@ import {
8
8
 
9
9
  import { Placeholder } from "./Placeholder";
10
10
  import { useInitialLoading } from "./hooks";
11
- import { useIsFocusable } from "@applicaster/zapp-react-native-utils/focusManager";
12
11
 
13
12
  type ReactComponent = React.ComponentType<any>;
14
13
 
@@ -138,12 +137,13 @@ New signature: {Component, ErrorComponent, LoadingComponent, options}`
138
137
  );
139
138
 
140
139
  const componentProps = React.useMemo(
141
- () => ({ ...props, parent }),
140
+ () => ({
141
+ ...props,
142
+ parent,
143
+ }),
142
144
  [props, parent]
143
145
  );
144
146
 
145
- useIsFocusable(componentProps);
146
-
147
147
  React.useEffect(() => {
148
148
  if (!skipOnLoadFinished && !isLoading) {
149
149
  onLoadFinished();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "13.0.0-alpha.7586259907",
3
+ "version": "13.0.0-alpha.7620873141",
4
4
  "description": "Applicaster Zapp React Native ui components for the Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -31,10 +31,10 @@
31
31
  "redux-mock-store": "^1.5.3"
32
32
  },
33
33
  "dependencies": {
34
- "@applicaster/applicaster-types": "13.0.0-alpha.7586259907",
35
- "@applicaster/zapp-react-native-bridge": "13.0.0-alpha.7586259907",
36
- "@applicaster/zapp-react-native-redux": "13.0.0-alpha.7586259907",
37
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.7586259907",
34
+ "@applicaster/applicaster-types": "13.0.0-alpha.7620873141",
35
+ "@applicaster/zapp-react-native-bridge": "13.0.0-alpha.7620873141",
36
+ "@applicaster/zapp-react-native-redux": "13.0.0-alpha.7620873141",
37
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.7620873141",
38
38
  "promise": "^8.3.0",
39
39
  "react-router-native": "^5.1.2",
40
40
  "url": "^0.11.0",
@@ -1,5 +0,0 @@
1
- import { isTvOSPlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
2
- import React from "react";
3
- import { View } from "react-native";
4
-
5
- export const CellWrapper = isTvOSPlatform() ? View : React.Fragment;