@applicaster/zapp-react-native-ui-components 13.0.0-alpha.3322736490 → 13.0.0-alpha.3332871333

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.
@@ -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
  };
@@ -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
+ }
@@ -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
 
@@ -144,7 +144,7 @@ export const AnimatedScrollModalComponent = ({ children }: Props) => {
144
144
 
145
145
  setLastSnap(destSnapPoint);
146
146
 
147
- if (destSnapPoint === modalSnapPoints[0] && isMinimizedModal) {
147
+ if (destSnapPoint === modalSnapPoints[0]) {
148
148
  translateYOffset.extractOffset();
149
149
  translateYOffset.setValue(preparedTranslationY);
150
150
  translateYOffset.flattenOffset();
@@ -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;
@@ -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 {
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.3322736490",
3
+ "version": "13.0.0-alpha.3332871333",
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.3322736490",
35
- "@applicaster/zapp-react-native-bridge": "13.0.0-alpha.3322736490",
36
- "@applicaster/zapp-react-native-redux": "13.0.0-alpha.3322736490",
37
- "@applicaster/zapp-react-native-utils": "13.0.0-alpha.3322736490",
34
+ "@applicaster/applicaster-types": "13.0.0-alpha.3332871333",
35
+ "@applicaster/zapp-react-native-bridge": "13.0.0-alpha.3332871333",
36
+ "@applicaster/zapp-react-native-redux": "13.0.0-alpha.3332871333",
37
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.3332871333",
38
38
  "promise": "^8.3.0",
39
39
  "react-router-native": "^5.1.2",
40
40
  "url": "^0.11.0",