@applicaster/zapp-react-native-ui-components 14.0.0-alpha.5351122050 → 14.0.0-alpha.5365702091

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 (30) hide show
  1. package/Components/Cell/Cell.tsx +91 -64
  2. package/Components/Cell/CellWithFocusable.tsx +3 -0
  3. package/Components/FeedLoader/FeedLoader.tsx +1 -1
  4. package/Components/Focusable/Focusable.tsx +10 -3
  5. package/Components/Focusable/FocusableTvOS.tsx +2 -2
  6. package/Components/Focusable/Touchable.tsx +5 -3
  7. package/Components/Focusable/index.android.tsx +8 -4
  8. package/Components/FocusableGroup/FocusableTvOS.tsx +1 -1
  9. package/Components/FocusableList/FocusableItem.tsx +4 -3
  10. package/Components/FocusableList/FocusableListItemWrapper.tsx +2 -1
  11. package/Components/FocusableList/hooks/useCellState.android.ts +13 -3
  12. package/Components/FocusableList/index.tsx +16 -9
  13. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +0 -12
  14. package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +65 -17
  15. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/Image.test.tsx +21 -3
  16. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +6 -3
  17. package/Components/MasterCell/DefaultComponents/Text/index.tsx +26 -6
  18. package/Components/PlayerContainer/PlayerContainer.tsx +4 -1
  19. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +2 -2
  20. package/Components/Tabs/TV/Tabs.android.tsx +1 -1
  21. package/Components/TextInputTv/__tests__/__snapshots__/TextInputTv.test.js.snap +13 -0
  22. package/Components/TextInputTv/index.tsx +11 -0
  23. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +42 -22
  24. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +9 -1
  25. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +40 -15
  26. package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +2 -2
  27. package/Components/VideoModal/hooks/utils/index.ts +4 -0
  28. package/Contexts/CellFocusedStateContext/index.tsx +27 -0
  29. package/events/index.ts +2 -0
  30. package/package.json +5 -5
@@ -8,6 +8,7 @@ import { getItemType } from "@applicaster/zapp-react-native-utils/navigationUtil
8
8
  import { SCREEN_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/itemTypes";
9
9
  import { sendSelectCellEvent } from "@applicaster/zapp-react-native-utils/analyticsUtils";
10
10
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
11
+ import { CellFocusedStateContextProvider } from "@applicaster/zapp-react-native-ui-components/Contexts/CellFocusedStateContext";
11
12
 
12
13
  import { CellWithFocusable } from "./CellWithFocusable";
13
14
  import { BaseFocusable } from "../BaseFocusable";
@@ -15,6 +16,7 @@ import { AccessibilityManager } from "@applicaster/zapp-react-native-utils/appUt
15
16
  import { styles } from "./styles";
16
17
 
17
18
  type Props = {
19
+ dataLength: number;
18
20
  item: ZappEntry;
19
21
  index: number;
20
22
  shouldScrollHorizontally: (arg1: [any]) => boolean | null | undefined;
@@ -67,9 +69,12 @@ type Props = {
67
69
 
68
70
  type State = {
69
71
  hasFocusableInside: boolean;
72
+ cellFocused: boolean;
70
73
  };
71
74
 
72
75
  export class CellComponent extends React.Component<Props, State> {
76
+ accessibilityManager: AccessibilityManager;
77
+
73
78
  constructor(props) {
74
79
  super(props);
75
80
  this.onPress = this.onPress.bind(this);
@@ -79,10 +84,14 @@ export class CellComponent extends React.Component<Props, State> {
79
84
  this.hasReceivedFocus = this.hasReceivedFocus.bind(this);
80
85
  this.scrollVertically = this.scrollVertically.bind(this);
81
86
  this.scrollToIndex = this.scrollToIndex.bind(this);
87
+ this.handleAccessibilityFocus = this.handleAccessibilityFocus.bind(this);
82
88
 
83
89
  this.state = {
84
90
  hasFocusableInside: props.CellRenderer.hasFocusableInside?.(props.item),
91
+ cellFocused: false,
85
92
  };
93
+
94
+ this.accessibilityManager = AccessibilityManager.getInstance();
86
95
  }
87
96
 
88
97
  setScreenLayout(componentAnchorPointY, screenLayout) {
@@ -130,6 +139,8 @@ export class CellComponent extends React.Component<Props, State> {
130
139
  } = this.props;
131
140
 
132
141
  if (isFocusable) {
142
+ this.setState({ cellFocused: true });
143
+
133
144
  if (
134
145
  shouldUpdate &&
135
146
  shouldScrollVertically?.(mouse, focusable, id, title)
@@ -139,7 +150,9 @@ export class CellComponent extends React.Component<Props, State> {
139
150
  }
140
151
  }
141
152
 
142
- onBlur() {}
153
+ onBlur() {
154
+ this.setState({ cellFocused: false });
155
+ }
143
156
 
144
157
  willReceiveFocus() {}
145
158
 
@@ -183,6 +196,25 @@ export class CellComponent extends React.Component<Props, State> {
183
196
  return !isFocusable ? false : focused || focusableFocused;
184
197
  }
185
198
 
199
+ handleAccessibilityFocus(index, dataLength) {
200
+ // For loop scrolling, calculate the correct logical index
201
+ const logicalIndex = dataLength ? index % dataLength : index;
202
+
203
+ const positionLabel = dataLength
204
+ ? `item ${logicalIndex + 1} of ${dataLength}`
205
+ : "";
206
+
207
+ if (this.state.hasFocusableInside) {
208
+ this.accessibilityManager.readText({
209
+ text: " ",
210
+ });
211
+ } else {
212
+ this.accessibilityManager.readText({
213
+ text: `${positionLabel}`,
214
+ });
215
+ }
216
+ }
217
+
186
218
  componentDidUpdate(prevProps: Readonly<Props>) {
187
219
  if (prevProps.item !== this.props.item) {
188
220
  this.setState({
@@ -191,6 +223,8 @@ export class CellComponent extends React.Component<Props, State> {
191
223
  ),
192
224
  });
193
225
  }
226
+
227
+ this.handleAccessibilityFocus(this.props.index, this.props.dataLength);
194
228
  }
195
229
 
196
230
  render() {
@@ -212,7 +246,6 @@ export class CellComponent extends React.Component<Props, State> {
212
246
  } = this.props;
213
247
 
214
248
  const { id } = item;
215
-
216
249
  const focusableId = join("-", [component?.id, id, index]);
217
250
 
218
251
  const handleFocus = (focusable, mouse) => {
@@ -223,73 +256,67 @@ export class CellComponent extends React.Component<Props, State> {
223
256
 
224
257
  if (this.state.hasFocusableInside) {
225
258
  return (
226
- <CellWithFocusable
227
- CellRenderer={CellRenderer}
228
- item={item}
229
- id={focusableId}
230
- groupId={groupId || component?.id}
231
- onFocus={handleFocus}
232
- index={index}
233
- scrollTo={this.scrollToIndex()}
234
- isFocusable={isFocusable}
235
- skipFocusManagerRegistration={skipFocusManagerRegistration}
236
- behavior={behavior}
237
- />
259
+ <CellFocusedStateContextProvider cellFocused={this.state.cellFocused}>
260
+ <CellWithFocusable
261
+ CellRenderer={CellRenderer}
262
+ item={item}
263
+ id={focusableId}
264
+ groupId={groupId || component?.id}
265
+ onFocus={handleFocus}
266
+ onBlur={onBlur || this.onBlur}
267
+ index={index}
268
+ scrollTo={this.scrollToIndex()}
269
+ isFocusable={isFocusable}
270
+ skipFocusManagerRegistration={skipFocusManagerRegistration}
271
+ behavior={behavior}
272
+ />
273
+ </CellFocusedStateContextProvider>
238
274
  );
239
275
  }
240
276
 
241
277
  return (
242
- <View
243
- testID={`${component?.id}-${id}`}
244
- accessible={false}
245
- style={styles.touchableCell}
246
- >
247
- <Focusable
248
- id={focusableId}
249
- groupId={groupId || component?.id}
250
- onFocus={handleFocus}
251
- onBlur={onBlur || this.onBlur}
252
- onPress={this.onPress}
253
- willReceiveFocus={willReceiveFocus || this.willReceiveFocus}
254
- hasReceivedFocus={hasReceivedFocus || this.hasReceivedFocus}
255
- preferredFocus={preferredFocus}
256
- offsetUpdater={offsetUpdater}
257
- style={styles.baseCell}
258
- isFocusable={isFocusable}
259
- skipFocusManagerRegistration={skipFocusManagerRegistration}
278
+ <CellFocusedStateContextProvider cellFocused={this.state.cellFocused}>
279
+ <View
280
+ testID={`${component?.id}-${id}`}
281
+ accessible={false}
282
+ style={styles.touchableCell}
260
283
  >
261
- {(focused, event) => {
262
- const isFocused = this.isCellFocused(focused);
263
-
264
- if (isFocused) {
265
- const accessibilityManager = AccessibilityManager.getInstance();
266
-
267
- const accessibilityTitle =
268
- item?.extensions?.accessibility?.label || item?.title || "";
269
-
270
- const accessibilityHint =
271
- item?.extensions?.accessibility?.hint || "";
272
-
273
- accessibilityManager.readText({
274
- text: `${accessibilityTitle} ${accessibilityHint}`,
275
- });
276
- }
277
-
278
- return (
279
- <FocusableCell
280
- {...{
281
- index,
282
- CellRenderer,
283
- item,
284
- focused: isFocused,
285
- scrollTo: this.scrollToIndex(event),
286
- behavior,
287
- }}
288
- />
289
- );
290
- }}
291
- </Focusable>
292
- </View>
284
+ <Focusable
285
+ id={focusableId}
286
+ groupId={groupId || component?.id}
287
+ onFocus={handleFocus}
288
+ onBlur={onBlur || this.onBlur}
289
+ onPress={this.onPress}
290
+ willReceiveFocus={willReceiveFocus || this.willReceiveFocus}
291
+ hasReceivedFocus={hasReceivedFocus || this.hasReceivedFocus}
292
+ preferredFocus={preferredFocus}
293
+ offsetUpdater={offsetUpdater}
294
+ style={styles.baseCell}
295
+ isFocusable={isFocusable}
296
+ skipFocusManagerRegistration={skipFocusManagerRegistration}
297
+ {...this.accessibilityManager.getButtonAccessibilityProps(
298
+ item?.extensions?.accessibility?.label || item?.title
299
+ )}
300
+ >
301
+ {(focused, event) => {
302
+ const isFocused = this.isCellFocused(focused);
303
+
304
+ return (
305
+ <FocusableCell
306
+ {...{
307
+ index,
308
+ CellRenderer,
309
+ item,
310
+ focused: isFocused,
311
+ scrollTo: this.scrollToIndex(event),
312
+ behavior,
313
+ }}
314
+ />
315
+ );
316
+ }}
317
+ </Focusable>
318
+ </View>
319
+ </CellFocusedStateContextProvider>
293
320
  );
294
321
  }
295
322
  }
@@ -14,6 +14,7 @@ type Props = {
14
14
  id: string;
15
15
  groupId: string;
16
16
  onFocus: Function;
17
+ onBlur?: Function;
17
18
  index: number;
18
19
  scrollTo: Function;
19
20
  preferredFocus?: boolean;
@@ -33,6 +34,7 @@ export function CellWithFocusable(props: Props) {
33
34
  id,
34
35
  groupId,
35
36
  onFocus,
37
+ onBlur = noop,
36
38
  scrollTo = noop,
37
39
  preferredFocus,
38
40
  skipFocusManagerRegistration,
@@ -78,6 +80,7 @@ export function CellWithFocusable(props: Props) {
78
80
  const onGroupBlur = React.useCallback(() => {
79
81
  if (!skipFocusManagerRegistration) {
80
82
  setIsFocused(false);
83
+ onBlur?.();
81
84
  }
82
85
  }, [skipFocusManagerRegistration]);
83
86
 
@@ -8,7 +8,7 @@ type Props = {
8
8
  typeof import("@applicaster/zapp-react-native-utils/reactHooks/feed").useLoadPipesDataDispatch
9
9
  >;
10
10
  feedUrl: string;
11
- children: (feed: ZappFeed) => React.ComponentType<any>;
11
+ children: (feed: ZappFeed) => React.ReactNode;
12
12
  onFeedLoaded: (feed: ZappFeed) => {};
13
13
  onError: (error: ZappPipesData["error"]) => {};
14
14
  refreshing: boolean;
@@ -6,6 +6,7 @@ import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focu
6
6
  import { LONG_KEY_PRESS_TIMEOUT } from "@applicaster/quick-brick-core/const";
7
7
  import { withFocusableContext } from "../../Contexts/FocusableGroupContext/withFocusableContext";
8
8
  import { StyleSheet, ViewStyle } from "react-native";
9
+ import { AccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager";
9
10
 
10
11
  type Props = {
11
12
  initialFocus?: boolean;
@@ -20,7 +21,7 @@ type Props = {
20
21
  onPressOut?: () => void;
21
22
  onLongPress?: () => void;
22
23
  handleFocus?: ({ mouse }: { mouse: boolean }) => void;
23
- children: (boolean, string) => React.ComponentType<any>;
24
+ children: (boolean, string) => React.ReactNode;
24
25
  selected?: boolean;
25
26
  style?: ViewStyle[] | ViewStyle;
26
27
  };
@@ -29,6 +30,7 @@ class Focusable extends BaseFocusable<Props> {
29
30
  isGroup: boolean;
30
31
  mouse: boolean;
31
32
  longPressTimeout = null;
33
+ accessibilityManager: AccessibilityManager;
32
34
 
33
35
  constructor(props) {
34
36
  super(props);
@@ -43,6 +45,8 @@ class Focusable extends BaseFocusable<Props> {
43
45
  this.resetLongPressTimeout = this.resetLongPressTimeout.bind(this);
44
46
  this.longPress = this.longPress.bind(this);
45
47
  this.press = this.press.bind(this);
48
+
49
+ this.accessibilityManager = AccessibilityManager.getInstance();
46
50
  }
47
51
 
48
52
  /**
@@ -123,12 +127,15 @@ class Focusable extends BaseFocusable<Props> {
123
127
  }
124
128
 
125
129
  render() {
126
- const { children, style, ...otherProps } = this.props;
130
+ const { children, style } = this.props;
127
131
  const { focused } = this.state;
128
132
 
129
133
  const id = this.getId();
130
134
  const focusableId = `focusable-${id}`;
131
135
 
136
+ const accessibilityProps =
137
+ this.accessibilityManager.getWebAccessibilityProps(this.props);
138
+
132
139
  return (
133
140
  <div
134
141
  id={focusableId}
@@ -141,7 +148,7 @@ class Focusable extends BaseFocusable<Props> {
141
148
  data-testid={focusableId}
142
149
  focused-teststate={focused ? "focused" : "default"}
143
150
  style={StyleSheet.flatten(style) as any as React.CSSProperties}
144
- {...otherProps}
151
+ {...accessibilityProps}
145
152
  >
146
153
  {children(focused, { mouse: this.mouse })}
147
154
  </div>
@@ -19,7 +19,7 @@ type Props = {
19
19
  onPress?: (nativeEvent: any) => void;
20
20
  onFocus?: (nativeEvent: any) => void;
21
21
  onBlur?: (nativeEvent: any) => void;
22
- children: (focused?: boolean) => React.ReactNode;
22
+ children: ((focused?: boolean) => React.ReactNode) | React.ReactNode;
23
23
  isParallaxDisabled: boolean;
24
24
  preferredFocus?: boolean;
25
25
  selected?: boolean;
@@ -204,7 +204,7 @@ export class Focusable extends BaseFocusable<Props> {
204
204
  {...this.nextFocusableReactTags}
205
205
  {...otherProps}
206
206
  >
207
- {R.is(Function, children) ? children(focused) : children}
207
+ {typeof children === "function" ? children(focused) : children}
208
208
  </FocusableItemNative>
209
209
  );
210
210
  }
@@ -9,7 +9,8 @@ type Props = {
9
9
  onLongPress?: (ref: FocusManager.TouchableRef) => void;
10
10
  onFocus?: (
11
11
  ref: FocusManager.TouchableRef,
12
- options: FocusManager.Android.CallbackOptions
12
+ options: FocusManager.Android.CallbackOptions,
13
+ context: Option<FocusManager.FocusContext>
13
14
  ) => void;
14
15
  onBlur?: (
15
16
  ref: FocusManager.TouchableRef,
@@ -39,9 +40,10 @@ export class Touchable extends React.Component<Props> {
39
40
 
40
41
  onFocus(
41
42
  focusableRef: FocusManager.TouchableRef,
42
- options: FocusManager.Android.CallbackOptions
43
+ options: FocusManager.Android.CallbackOptions,
44
+ context: Option<FocusManager.FocusContext>
43
45
  ): void {
44
- this.props?.onFocus?.(focusableRef, options);
46
+ this.props?.onFocus?.(focusableRef, options, context);
45
47
  }
46
48
 
47
49
  onBlur(
@@ -22,7 +22,8 @@ type Props = {
22
22
  onPress?: (ref: FocusManager.FocusableRef) => void;
23
23
  onFocus?: (
24
24
  ref: FocusManager.FocusableRef,
25
- options: FocusManager.Android.CallbackOptions
25
+ options: FocusManager.Android.CallbackOptions,
26
+ context?: FocusManager.FocusContext
26
27
  ) => void;
27
28
  onBlur?: (
28
29
  ref: FocusManager.FocusableRef,
@@ -32,6 +33,7 @@ type Props = {
32
33
  onPressOut?: (ref: FocusManager.FocusableRef) => void;
33
34
  onLongPress?: (ref: FocusManager.FocusableRef) => void;
34
35
  onRegister?: () => void;
36
+ onUnregister?: () => void;
35
37
  isFocusableCell?: boolean;
36
38
  /** only for FocusableScrollView */
37
39
  onSetIsFocusable?: (isFocusable: boolean) => void;
@@ -70,6 +72,7 @@ function FocusableComponent(props: Props, forwardedRef) {
70
72
  onPressOut,
71
73
  onLongPress,
72
74
  onRegister = noop,
75
+ onUnregister = noop,
73
76
  isFocusableCell = true,
74
77
  onSetIsFocusable,
75
78
  } = props;
@@ -113,9 +116,10 @@ function FocusableComponent(props: Props, forwardedRef) {
113
116
 
114
117
  return () => {
115
118
  unregister();
119
+ onUnregister();
116
120
  };
117
121
  }
118
- }, [id, onRegister, isFocusableCell, parentFocusableId]);
122
+ }, [id, onRegister, onUnregister, isFocusableCell, parentFocusableId]);
119
123
 
120
124
  if (R.isNil(id)) {
121
125
  // eslint-disable-next-line no-console
@@ -125,9 +129,9 @@ function FocusableComponent(props: Props, forwardedRef) {
125
129
  }
126
130
 
127
131
  const _onFocus = React.useCallback(
128
- (ref, options) => {
132
+ (ref, options, context) => {
129
133
  setFocused(true);
130
- onFocus?.(ref, options);
134
+ onFocus?.(ref, options, context);
131
135
  },
132
136
  [onFocus]
133
137
  );
@@ -22,7 +22,7 @@ type FocusableGroupNativeEvent = {
22
22
 
23
23
  type Props = {
24
24
  id: string;
25
- children: (arg1: boolean) => React.ComponentType<any>;
25
+ children: React.ReactNode;
26
26
  isFocusDisabled: boolean;
27
27
  isWithMemory: boolean;
28
28
  focusGroupRef: React.Component;
@@ -10,7 +10,8 @@ type FocusableItemComponentProps = {
10
10
  onFocus: (
11
11
  element: FocusManager.FocusableRef,
12
12
  renderArgs: { item: FocusableItemComponentProps["item"]; index: number },
13
- direction: FocusManager.Android.FocusNavigationDirections
13
+ options: FocusManager.Android.CallbackOptions,
14
+ context: Option<FocusManager.FocusContext>
14
15
  ) => void;
15
16
  onListElementFocus?: (any, RenderItemProps, Direction) => void;
16
17
  onListElementBlur?: (any, RenderItemProps, Direction) => void;
@@ -45,8 +46,8 @@ const FocusableItemComponent = ({
45
46
  const renderArgs = { item, index };
46
47
 
47
48
  const onFocusHandler = React.useCallback(
48
- (element, direction) => {
49
- onFocus?.(element, renderArgs, direction);
49
+ (element, options, context) => {
50
+ onFocus?.(element, renderArgs, options, context);
50
51
  },
51
52
  [item, onFocus]
52
53
  );
@@ -17,7 +17,8 @@ type Props = {
17
17
  onFocus: (
18
18
  element: FocusManager.FocusableRef,
19
19
  renderArgs: { item: Item; index: number },
20
- direction: FocusManager.Android.FocusNavigationDirections
20
+ options: FocusManager.Android.CallbackOptions,
21
+ context: FocusManager.FocusContext
21
22
  ) => void;
22
23
  onListElementBlur?: (any, RenderItemProps, Direction) => void;
23
24
  onListElementPress?: (any, RenderItemProps) => void;
@@ -10,15 +10,25 @@ export const useCellState = (id: string) => {
10
10
  );
11
11
 
12
12
  React.useEffect(() => {
13
- const handler = (focusable) => {
13
+ const focusHandler = (focusable) => {
14
14
  const isChildren = focusManager.isFocusableChildOf(focusable, id);
15
+
15
16
  setCurrentCellFocused(isChildren);
16
17
  };
17
18
 
18
- focusManager.on(FOCUS_EVENTS.FOCUS, handler);
19
+ focusManager.on(FOCUS_EVENTS.FOCUS, focusHandler);
20
+
21
+ const resetHandler = ({ focusedId }) => {
22
+ if (id === focusedId) {
23
+ setCurrentCellFocused(false);
24
+ }
25
+ };
26
+
27
+ focusManager.on(FOCUS_EVENTS.RESET, resetHandler);
19
28
 
20
29
  return () => {
21
- focusManager.removeHandler(FOCUS_EVENTS.FOCUS, handler);
30
+ focusManager.removeHandler(FOCUS_EVENTS.FOCUS, focusHandler);
31
+ focusManager.removeHandler(FOCUS_EVENTS.RESET, resetHandler);
22
32
  };
23
33
  }, [id]);
24
34
 
@@ -20,27 +20,34 @@ import { FocusableScrollView } from "../FocusableScrollView";
20
20
  const mapIndexed = R.addIndex(R.map);
21
21
 
22
22
  export type IListRenderItem<ItemT> = (
23
- info: IListRenderItemInfo<ItemT> & {
23
+ info: {
24
24
  focused: boolean;
25
25
  onLoadFinished: () => void;
26
26
  onLoadFailed: () => void;
27
- }
27
+ } & IListRenderItemInfo<ItemT>
28
28
  ) => React.ReactElement | null;
29
29
 
30
30
  export const getFocusableId = (parentId, index) =>
31
31
  `${parentId}___index:${index}`;
32
32
 
33
+ type Item = ZappEntry | ZappUIComponent | any;
34
+
33
35
  export type Props<ItemT> = FlatListProps<ItemT> & {
34
36
  id?: number | string;
35
37
  horizontal?: boolean;
36
38
  loop?: boolean;
37
39
  numColumns?: number;
38
40
  data: ZappEntry[] | ZappUIComponent[] | any[];
39
- onListElementFocus?: (any, RenderItemProps, Direction) => void;
40
- onListElementBlur?: (any, RenderItemProps, Direction) => void;
41
- onListElementPress?: (any, RenderItemProps) => void;
42
- onListElementPressOut?: (any, RenderItemProps) => void;
43
- onListElementLongPress?: (any, RenderItemProps) => void;
41
+ onListElementFocus?: (
42
+ element: FocusManager.FocusableRef,
43
+ renderItemProps: { item: Item; index: number },
44
+ options: FocusManager.Android.CallbackOptions,
45
+ context: FocusManager.FocusContext
46
+ ) => void;
47
+ onListElementBlur?: (element, renderItemProps, direction) => void;
48
+ onListElementPress?: (element, renderItemProps) => void;
49
+ onListElementPressOut?: (element, renderItemProps) => void;
50
+ onListElementLongPress?: (element, renderItemProps) => void;
44
51
  focusableItemProps?: any;
45
52
  focused?: boolean;
46
53
  initialScrollIndex?: number;
@@ -138,11 +145,11 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
138
145
  );
139
146
 
140
147
  const onFocus = React.useCallback(
141
- (element, renderArgs, direction) => {
148
+ (element, renderArgs, options, context) => {
142
149
  const { index } = renderArgs;
143
150
 
144
151
  updateFocusedIndex?.(index);
145
- onListElementFocus?.(element, renderArgs, direction);
152
+ onListElementFocus?.(element, renderArgs, options, context);
146
153
  },
147
154
  [onListElementFocus, updateFocusedIndex]
148
155
  );
@@ -4,7 +4,6 @@ import { Focusable } from "@applicaster/zapp-react-native-ui-components/Componen
4
4
  import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
5
5
  import { getXray } from "@applicaster/zapp-react-native-utils/logger";
6
6
  import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
7
- import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
8
7
 
9
8
  const { Logger } = getXray();
10
9
 
@@ -44,11 +43,6 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
44
43
 
45
44
  const actionContext = useActions(pluginIdentifier);
46
45
 
47
- const accessibilityManager = useAccessibilityManager({});
48
-
49
- const { ttsLabel = "" } =
50
- actionContext?.initialEntryState(item)?.getAccessibility?.(item) || {};
51
-
52
46
  const onPress = (event) => {
53
47
  event?.preventDefault?.();
54
48
 
@@ -71,12 +65,6 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
71
65
  focusedButtonId,
72
66
  mouse: focusable.mouse,
73
67
  });
74
-
75
- if (ttsLabel) {
76
- accessibilityManager.readText({
77
- text: ttsLabel,
78
- });
79
- }
80
68
  };
81
69
 
82
70
  const handleBlur = (_focusable, _direction) => {
@@ -28,17 +28,10 @@ interface Props {
28
28
  onAsyncRender: () => void;
29
29
  }
30
30
 
31
- const SecondaryImageComponent = (props: Props) => {
32
- const {
33
- uri,
34
- style,
35
- displayMode,
36
- imageSizing,
37
- fitPosition,
38
- fixedHeight,
39
- fixedWidth,
40
- onAsyncRender,
41
- } = props;
31
+ /** Secondary Image Dynamic does not render until the image is loaded */
32
+ const SecondaryImageDynamic = (props: Props) => {
33
+ const { uri, style, displayMode, imageSizing, fitPosition, onAsyncRender } =
34
+ props;
42
35
 
43
36
  const imageDimension = useGetImageDimensions(
44
37
  uri,
@@ -46,13 +39,9 @@ const SecondaryImageComponent = (props: Props) => {
46
39
  isImageSizingFit(imageSizing) ? undefined : (style.height as number)
47
40
  );
48
41
 
49
- const containerHeight = isDisplayModeFixed(displayMode)
50
- ? fixedHeight
51
- : imageDimension?.height;
42
+ const containerHeight = imageDimension?.height;
52
43
 
53
- const containerWidth = isDisplayModeFixed(displayMode)
54
- ? fixedWidth
55
- : style?.width;
44
+ const containerWidth = style?.width;
56
45
 
57
46
  if (isNil(imageDimension?.aspectRatio)) {
58
47
  return null;
@@ -80,4 +69,63 @@ const SecondaryImageComponent = (props: Props) => {
80
69
  );
81
70
  };
82
71
 
72
+ /** Secondary Image Fixed does not render the image until the image is loaded, but keep container rendered */
73
+ const SecondaryImageFixed = (props: Props) => {
74
+ const {
75
+ uri,
76
+ style,
77
+ displayMode,
78
+ imageSizing,
79
+ fitPosition,
80
+ fixedHeight,
81
+ fixedWidth,
82
+ onAsyncRender,
83
+ } = props;
84
+
85
+ const imageDimension = useGetImageDimensions(
86
+ uri,
87
+ style.width as number,
88
+ isImageSizingFit(imageSizing) ? undefined : (style.height as number)
89
+ );
90
+
91
+ return (
92
+ <View style={style} onLayout={onAsyncRender}>
93
+ {isNil(imageDimension?.aspectRatio) ? null : (
94
+ <Image
95
+ {...props}
96
+ source={{ uri }}
97
+ style={{
98
+ ...getStyle({
99
+ imageSizing,
100
+ fitPosition,
101
+ displayMode,
102
+ imageDimension,
103
+ containerHeight: fixedHeight,
104
+ containerWidth: fixedWidth,
105
+ }),
106
+ borderRadius: style.borderRadius,
107
+ aspectRatio: imageDimension.aspectRatio,
108
+ }}
109
+ />
110
+ )}
111
+ </View>
112
+ );
113
+ };
114
+
115
+ const SecondaryImageComponent = (props: Props) => {
116
+ const { uri, displayMode } = props;
117
+
118
+ if (!uri) {
119
+ return null;
120
+ }
121
+
122
+ const isFixed = isDisplayModeFixed(displayMode);
123
+
124
+ return isFixed ? (
125
+ <SecondaryImageFixed {...props} />
126
+ ) : (
127
+ <SecondaryImageDynamic {...props} />
128
+ );
129
+ };
130
+
83
131
  export const SecondaryImage = withAsyncRenderHOC(SecondaryImageComponent);
@@ -4,9 +4,26 @@ import { render } from "@testing-library/react-native";
4
4
  import { SecondaryImage } from "../Image";
5
5
 
6
6
  describe("SecondaryImage - Image", () => {
7
- it("SecondaryImage should not render if no aspect ratio", async () => {
7
+ it("SecondaryImage should not render if no uri", async () => {
8
8
  const wrapper = await render(
9
- <SecondaryImage uri="" style={{ width: 100 }} />
9
+ <SecondaryImage
10
+ displayMode="dynamic"
11
+ uri={undefined}
12
+ style={{ width: 100 }}
13
+ />
14
+ );
15
+
16
+ expect(wrapper.toJSON()).toEqual(null);
17
+ expect(wrapper.toJSON()).toMatchSnapshot();
18
+ });
19
+
20
+ it("SecondaryImage should not render if no aspect ratio (dynamic)", async () => {
21
+ const wrapper = await render(
22
+ <SecondaryImage
23
+ displayMode="dynamic"
24
+ uri="someurl"
25
+ style={{ width: 100 }}
26
+ />
10
27
  );
11
28
 
12
29
  expect(wrapper.toJSON()).toEqual(null);
@@ -16,7 +33,8 @@ describe("SecondaryImage - Image", () => {
16
33
  it("SecondaryImage should render if known dimensions", async () => {
17
34
  const wrapper = await render(
18
35
  <SecondaryImage
19
- uri=""
36
+ uri="someUrl"
37
+ displayMode="dynamic"
20
38
  style={{ width: 100, height: 100, borderRadius: 10 }}
21
39
  />
22
40
  );
@@ -1,6 +1,8 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`SecondaryImage - Image SecondaryImage should not render if no aspect ratio 1`] = `null`;
3
+ exports[`SecondaryImage - Image SecondaryImage should not render if no aspect ratio (dynamic) 1`] = `null`;
4
+
5
+ exports[`SecondaryImage - Image SecondaryImage should not render if no uri 1`] = `null`;
4
6
 
5
7
  exports[`SecondaryImage - Image SecondaryImage should render if known dimensions 1`] = `
6
8
  <View
@@ -14,10 +16,11 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
14
16
  }
15
17
  >
16
18
  <Image
19
+ displayMode="dynamic"
17
20
  onAsyncRender={[Function]}
18
21
  source={
19
22
  {
20
- "uri": "",
23
+ "uri": "someUrl",
21
24
  }
22
25
  }
23
26
  style={
@@ -28,7 +31,7 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
28
31
  "width": 100,
29
32
  }
30
33
  }
31
- uri=""
34
+ uri="someUrl"
32
35
  />
33
36
  </View>
34
37
  `;
@@ -11,6 +11,8 @@ import { withScaledLineHeight } from "./utils";
11
11
  import { toNumber } from "@applicaster/zapp-react-native-utils/numberUtils";
12
12
  import { MeasurementPortalContext } from "../../../MeasurmentsPortal";
13
13
  import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
14
+ import { CellFocusedStateContext } from "@applicaster/zapp-react-native-ui-components/Contexts/CellFocusedStateContext";
15
+ import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
14
16
 
15
17
  type Props = {
16
18
  style: any;
@@ -35,10 +37,9 @@ const _Text = ({
35
37
  }: Props) => {
36
38
  const _label = useTextLabel({ label, entry });
37
39
  const isMeasurement = React.useContext(MeasurementPortalContext);
40
+ const cellFocused = React.useContext(CellFocusedStateContext);
38
41
 
39
- if (isNilOrEmpty(_label)) {
40
- return null;
41
- }
42
+ const accessibilityManager = useAccessibilityManager({});
42
43
 
43
44
  // set maximum possible height for the text in case of measurement
44
45
  const height =
@@ -46,6 +47,27 @@ const _Text = ({
46
47
  ? toNumber(otherProps.numberOfLines) * toNumber(style.lineHeight)
47
48
  : undefined;
48
49
 
50
+ const textLabel = dateTransformEnabled
51
+ ? dateFormat(dateTransform, label)
52
+ : textTransform(transformText, _label);
53
+
54
+ React.useLayoutEffect(() => {
55
+ // For FocusableCells with action buttons
56
+ if (otherProps.state) {
57
+ if (otherProps.state === "focused" && cellFocused === true) {
58
+ accessibilityManager.addHeading(textLabel);
59
+ }
60
+ } else {
61
+ if (cellFocused === true) {
62
+ accessibilityManager.addHeading(textLabel);
63
+ }
64
+ }
65
+ }, [cellFocused, otherProps.state, textLabel]);
66
+
67
+ if (isNilOrEmpty(_label)) {
68
+ return null;
69
+ }
70
+
49
71
  return (
50
72
  <Text
51
73
  style={[
@@ -55,9 +77,7 @@ const _Text = ({
55
77
  allowFontScaling={false}
56
78
  {...withoutLabel(otherProps)}
57
79
  >
58
- {dateTransformEnabled
59
- ? dateFormat(dateTransform, label)
60
- : textTransform(transformText, _label)}
80
+ {textLabel}
61
81
  </Text>
62
82
  );
63
83
  };
@@ -423,7 +423,10 @@ const PlayerContainerComponent = (props: Props) => {
423
423
  id: playerContainerId,
424
424
  listener: {
425
425
  onVideoEnd,
426
- onError,
426
+ onError: (err: Error) => {
427
+ // Adapt Error to the expected shape for onError
428
+ onError({ error: err });
429
+ },
427
430
  onLoad,
428
431
  onPlayerClose: close,
429
432
  onPlayerDetached: close,
@@ -19,9 +19,9 @@ describe("ScreenRevealManager", () => {
19
19
 
20
20
  const manager = new ScreenRevealManager(componentsToRender, mockCallback);
21
21
 
22
- expect(manager["numberOfComponentsWaitToLoadBeforePresent"]).toBe(3);
22
+ expect(manager.numberOfComponentsWaitToLoadBeforePresent).toBe(3);
23
23
 
24
- expect(manager["renderingState"]).toEqual([
24
+ expect(manager.renderingState).toEqual([
25
25
  COMPONENT_LOADING_STATE.UNKNOWN,
26
26
  COMPONENT_LOADING_STATE.UNKNOWN,
27
27
  COMPONENT_LOADING_STATE.UNKNOWN,
@@ -62,7 +62,7 @@ const TabsComponent = ({
62
62
  );
63
63
 
64
64
  const renderItem = useCallback(
65
- ({ item, index, focused }) => {
65
+ ({ item, index, focused }: { item: any; index: any; focused?: any }) => {
66
66
  const itemId = generateFocusableId(getId(item));
67
67
 
68
68
  const isSelected = R.equals(index, selectedEntryIndex);
@@ -2,6 +2,19 @@
2
2
 
3
3
  exports[`<TextInputTv /> renders 1`] = `
4
4
  <input
5
+ accessibilityProps={
6
+ {
7
+ "accessibilityHint": "Enter text into Search",
8
+ "accessibilityLabel": "Search",
9
+ "accessibilityRole": "searchbox",
10
+ "accessible": true,
11
+ "aria-description": "Enter text into Search",
12
+ "aria-label": "Search",
13
+ "aria-role": "searchbox",
14
+ "role": "searchbox",
15
+ "tabindex": 0,
16
+ }
17
+ }
5
18
  testID="TextInput-tv"
6
19
  />
7
20
  `;
@@ -4,6 +4,7 @@ import { Appearance, Platform, StyleSheet, TextInput } from "react-native";
4
4
  import { isFunction } from "@applicaster/zapp-react-native-utils/functionUtils";
5
5
  import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
6
6
  import { useIsRTL } from "@applicaster/zapp-react-native-utils/localizationUtils";
7
+ import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
7
8
 
8
9
  type Props = Partial<{
9
10
  style: any;
@@ -42,6 +43,8 @@ function TextInputTV(props: Props, ref) {
42
43
  const [colorScheme, setColorScheme] = useState(getInitialColorScheme());
43
44
  const isRTL = useIsRTL();
44
45
 
46
+ const accessibilityManager = useAccessibilityManager({});
47
+
45
48
  const onColorChange = useCallback(
46
49
  ({ colorScheme: color }) => {
47
50
  if (color !== colorScheme) {
@@ -153,6 +156,13 @@ function TextInputTV(props: Props, ref) {
153
156
  ])
154
157
  )(props);
155
158
 
159
+ const getAccessibilityProps = () => {
160
+ return {
161
+ accessibilityProps:
162
+ accessibilityManager.getInputAccessibilityProps("Search"),
163
+ };
164
+ };
165
+
156
166
  const inputProps = {
157
167
  ...getProps(),
158
168
  ...getStyle(),
@@ -161,6 +171,7 @@ function TextInputTV(props: Props, ref) {
161
171
  ...getSecureTextEntry(),
162
172
  ...getOnEndEditing(),
163
173
  ...getOnPress(),
174
+ ...getAccessibilityProps(),
164
175
  };
165
176
 
166
177
  if (
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from "react";
1
+ import React, { useEffect, useMemo } from "react";
2
2
  import { Animated, Dimensions } from "react-native";
3
3
 
4
4
  import {
@@ -163,31 +163,51 @@ const Provider = ({ children }: { children: React.ReactNode }) => {
163
163
 
164
164
  return (
165
165
  <ReactContext.Provider
166
- value={{
167
- yTranslate,
168
- startComponentsAnimation,
169
- setStartComponentsAnimation,
170
- isActiveGesture: playerAnimationState !== null,
171
- playerAnimationState,
172
- setPlayerAnimationState,
173
- resetPlayerAnimationState,
174
- minimisedHeight,
175
- animatedValues: {
166
+ value={useMemo(
167
+ () => ({
168
+ yTranslate,
169
+ startComponentsAnimation,
170
+ setStartComponentsAnimation,
171
+ isActiveGesture: playerAnimationState !== null,
172
+ playerAnimationState,
173
+ setPlayerAnimationState,
174
+ resetPlayerAnimationState,
175
+ minimisedHeight,
176
+ animatedValues: {
177
+ lastScrollY,
178
+ dragScrollY,
179
+ dragVideoPlayerY,
180
+ translateYOffset,
181
+ },
182
+ lastScrollYValue,
183
+ scrollPosition,
184
+ modalSnapPoints,
185
+ lastSnap,
186
+ setLastSnap,
187
+ tabletLandscapePlayerTopPosition,
188
+ setTabletLandscapePlayerTopPosition,
189
+ startComponentsAnimationDistance,
190
+ progressBarHeight,
191
+ }),
192
+ // eslint-disable-next-line react-hooks/exhaustive-deps
193
+ [
194
+ startComponentsAnimation,
195
+ playerAnimationState,
196
+ minimisedHeight,
176
197
  lastScrollY,
177
198
  dragScrollY,
178
199
  dragVideoPlayerY,
179
200
  translateYOffset,
180
- },
181
- lastScrollYValue,
182
- scrollPosition,
183
- modalSnapPoints,
184
- lastSnap,
185
- setLastSnap,
186
- tabletLandscapePlayerTopPosition,
187
- setTabletLandscapePlayerTopPosition,
188
- startComponentsAnimationDistance,
189
- progressBarHeight,
190
- }}
201
+ lastSnap,
202
+ modalSnapPoints,
203
+ lastScrollYValue,
204
+ scrollPosition,
205
+ tabletLandscapePlayerTopPosition,
206
+ startComponentsAnimationDistance,
207
+ progressBarHeight,
208
+ isLiveItem,
209
+ ]
210
+ )}
191
211
  >
192
212
  {children}
193
213
  </ReactContext.Provider>
@@ -2,6 +2,8 @@ import { renderHook } from "@testing-library/react-hooks";
2
2
  import { useDelayedPlayerDetails } from "../useDelayedPlayerDetails";
3
3
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
4
4
 
5
+ jest.useFakeTimers();
6
+
5
7
  jest.mock("@applicaster/zapp-react-native-utils/reactHooks", () => ({
6
8
  useIsTablet: jest.fn().mockReturnValue(false),
7
9
  }));
@@ -11,11 +13,15 @@ describe("useDelayedPlayerDetails", () => {
11
13
  jest.clearAllMocks();
12
14
  });
13
15
 
14
- it("should return true initially", () => {
16
+ it("should return false initially, that changes after 1 second", () => {
15
17
  const { result } = renderHook(() =>
16
18
  useDelayedPlayerDetails({ isInline: true, isDocked: false, isPip: false })
17
19
  );
18
20
 
21
+ expect(result.current).toBe(false);
22
+
23
+ jest.advanceTimersByTime(1000);
24
+
19
25
  expect(result.current).toBe(true);
20
26
  });
21
27
 
@@ -46,6 +52,8 @@ describe("useDelayedPlayerDetails", () => {
46
52
  })
47
53
  );
48
54
 
55
+ jest.advanceTimersByTime(1000);
56
+
49
57
  expect(result.current).toBe(true);
50
58
  });
51
59
  });
@@ -1,22 +1,26 @@
1
+ // const showPlayerDetails = (
2
+ // isInline: boolean,
3
+ // isDocked: boolean,
4
+ // isPip: boolean,
5
+ // isTablet: boolean
6
+ // ) => {
7
+ // return showDetails({
8
+ // isMobile: !isTablet,
9
+ // isInline,
10
+ // isDocked,
11
+ // isPip,
12
+ // });
13
+ // };
14
+
15
+ import * as React from "react";
1
16
  import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
17
+ import { withTimeout$ } from "@applicaster/zapp-react-native-utils/idleUtils";
2
18
 
3
19
  import { showDetails } from "./utils";
4
20
 
5
- type Props = { isInline: boolean; isDocked: boolean; isPip: boolean };
21
+ const TIMEOUT = 1000; // ms
6
22
 
7
- const showPlayerDetails = (
8
- isInline: boolean,
9
- isDocked: boolean,
10
- isPip: boolean,
11
- isTablet: boolean
12
- ) => {
13
- return showDetails({
14
- isMobile: !isTablet,
15
- isInline,
16
- isDocked,
17
- isPip,
18
- });
19
- };
23
+ type Props = { isInline: boolean; isDocked: boolean; isPip: boolean };
20
24
 
21
25
  /**
22
26
  * Custom hook to determine whether to show player details with a delay.
@@ -32,7 +36,28 @@ export const useDelayedPlayerDetails = ({
32
36
  isDocked,
33
37
  isPip,
34
38
  }: Props): boolean => {
39
+ const [shouldShowDetails, setShouldShowDetails] = React.useState(false);
40
+
35
41
  const isTablet = useIsTablet();
36
42
 
37
- return showPlayerDetails(isInline, isDocked, isPip, isTablet);
43
+ React.useEffect(() => {
44
+ const subscription = withTimeout$(TIMEOUT).subscribe({
45
+ next: () => {
46
+ setShouldShowDetails(() => {
47
+ return showDetails({
48
+ isMobile: !isTablet,
49
+ isInline,
50
+ isDocked,
51
+ isPip,
52
+ });
53
+ });
54
+ },
55
+ });
56
+
57
+ return () => {
58
+ subscription.unsubscribe();
59
+ };
60
+ }, [isDocked, isTablet, isInline, isPip]);
61
+
62
+ return shouldShowDetails;
38
63
  };
@@ -12,7 +12,7 @@ describe("showDetails", () => {
12
12
  expect(result).toBe(false);
13
13
  });
14
14
 
15
- it("should return false if isDocked is true", () => {
15
+ it("should return true if isDocked & mobile", () => {
16
16
  const result = showDetails({
17
17
  isMobile: true,
18
18
  isInline: true,
@@ -20,7 +20,7 @@ describe("showDetails", () => {
20
20
  isPip: false,
21
21
  });
22
22
 
23
- expect(result).toBe(false);
23
+ expect(result).toBe(true);
24
24
  });
25
25
 
26
26
  it("should return true if isMobile is true and isInline is true", () => {
@@ -52,6 +52,10 @@ export const showDetails = ({
52
52
  }
53
53
 
54
54
  if (isDocked) {
55
+ if (isMobile) {
56
+ return true;
57
+ }
58
+
55
59
  return false;
56
60
  }
57
61
 
@@ -0,0 +1,27 @@
1
+ import React, { ReactNode } from "react";
2
+
3
+ export const CellFocusedStateContext = React.createContext<boolean>(false);
4
+
5
+ export const CellFocusedStateContextProvider = ({
6
+ cellFocused,
7
+ children,
8
+ }: {
9
+ cellFocused: boolean;
10
+ children: ReactNode;
11
+ }) => {
12
+ return (
13
+ <CellFocusedStateContext.Provider value={cellFocused}>
14
+ {children}
15
+ </CellFocusedStateContext.Provider>
16
+ );
17
+ };
18
+
19
+ export function withCellFocusedStateContext(
20
+ Component: React.ComponentType<any>
21
+ ) {
22
+ return function WithCellFocusedStateContextWrapper(props) {
23
+ const cellFocusedState = React.useContext(CellFocusedStateContext);
24
+
25
+ return <Component {...props} cellFocusedState={cellFocusedState} />;
26
+ };
27
+ }
package/events/index.ts CHANGED
@@ -3,4 +3,6 @@ export enum QBUIComponentEvents {
3
3
  topMenuBarTV_onFocus = "topMenuBarTV_onFocus",
4
4
  navigatorReplaceItem = "navigatorReplaceItem",
5
5
  scrollVerticallyToInitialOffset = "scrollVerticallyToInitialOffset",
6
+ focusOnSelectedTab = "focusOnSelectedTab",
7
+ focusOnSelectedTopMenuItem = "focusOnSelectedTopMenuItem",
6
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "14.0.0-alpha.5351122050",
3
+ "version": "14.0.0-alpha.5365702091",
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",
@@ -28,10 +28,10 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "14.0.0-alpha.5351122050",
32
- "@applicaster/zapp-react-native-bridge": "14.0.0-alpha.5351122050",
33
- "@applicaster/zapp-react-native-redux": "14.0.0-alpha.5351122050",
34
- "@applicaster/zapp-react-native-utils": "14.0.0-alpha.5351122050",
31
+ "@applicaster/applicaster-types": "14.0.0-alpha.5365702091",
32
+ "@applicaster/zapp-react-native-bridge": "14.0.0-alpha.5365702091",
33
+ "@applicaster/zapp-react-native-redux": "14.0.0-alpha.5365702091",
34
+ "@applicaster/zapp-react-native-utils": "14.0.0-alpha.5365702091",
35
35
  "promise": "^8.3.0",
36
36
  "url": "^0.11.0",
37
37
  "uuid": "^3.3.2"