@applicaster/zapp-react-native-ui-components 15.0.0-rc.11 → 15.0.0-rc.13

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.
@@ -0,0 +1,44 @@
1
+ import * as React from "react";
2
+ import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable/FocusableTvOS";
3
+ import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
4
+
5
+ type Props = {
6
+ id: string;
7
+ groupId: string;
8
+ isParallaxDisabled: boolean;
9
+ applyWrapper: boolean;
10
+ children: (focused: boolean) => React.ReactNode;
11
+ onFocus: (arg1: any, index?: number) => void;
12
+ onBlur: Callback;
13
+ };
14
+
15
+ export const FocusableWrapper = ({
16
+ id,
17
+ groupId,
18
+ isParallaxDisabled,
19
+ children,
20
+ applyWrapper,
21
+ onFocus,
22
+ onBlur,
23
+ }: Props) => {
24
+ if (applyWrapper) {
25
+ return (
26
+ <Focusable
27
+ id={id}
28
+ groupId={groupId}
29
+ isParallaxDisabled={isParallaxDisabled}
30
+ onFocus={onFocus}
31
+ onBlur={onBlur}
32
+ willReceiveFocus={noop}
33
+ hasReceivedFocus={noop}
34
+ // @ts-ignore
35
+ offsetUpdater={noop}
36
+ isFocusable
37
+ >
38
+ {(focused) => children(focused)}
39
+ </Focusable>
40
+ );
41
+ }
42
+
43
+ return <>{children(false)}</>;
44
+ };
@@ -1,6 +1,9 @@
1
1
  import * as React from "react";
2
2
  import * as R from "ramda";
3
3
  import { View, StyleSheet } from "react-native";
4
+ import { first, filter } from "rxjs/operators";
5
+
6
+ import { compose } from "@applicaster/zapp-react-native-utils/utils";
4
7
 
5
8
  import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable/FocusableTvOS";
6
9
  import { FocusableCell } from "@applicaster/zapp-react-native-ui-components/Components/FocusableCell";
@@ -10,6 +13,9 @@ import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focu
10
13
  import { sendSelectCellEvent } from "@applicaster/zapp-react-native-utils/analyticsUtils";
11
14
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
12
15
  import { CellWithFocusable } from "./CellWithFocusable";
16
+ import { FocusableWrapper } from "./FocusableWrapper";
17
+
18
+ import { focusableButtonsRegistration$ } from "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux/utils/utils.ios";
13
19
 
14
20
  type Props = {
15
21
  item: ZappEntry;
@@ -66,6 +72,8 @@ type Props = {
66
72
  shouldUpdate: boolean;
67
73
  behavior: Behavior;
68
74
  componentsMapOffset: number;
75
+ applyFocusableWrapper: boolean;
76
+ hasFocusableInside: boolean;
69
77
  };
70
78
 
71
79
  type State = {
@@ -82,7 +90,7 @@ const baseCellStyles = {
82
90
  flex: 1,
83
91
  } as const;
84
92
 
85
- export class TvOSCellComponent extends React.Component<Props, State> {
93
+ class TvOSCell extends React.Component<Props, State> {
86
94
  cell: any;
87
95
  target: any;
88
96
  layout: any;
@@ -239,6 +247,8 @@ export class TvOSCellComponent extends React.Component<Props, State> {
239
247
  groupId,
240
248
  isFocusable,
241
249
  behavior,
250
+ applyFocusableWrapper,
251
+ hasFocusableInside,
242
252
  } = this.props;
243
253
 
244
254
  const { id } = item;
@@ -254,24 +264,33 @@ export class TvOSCellComponent extends React.Component<Props, State> {
254
264
  this.onFocus(arg1, index);
255
265
  };
256
266
 
257
- const hasFocusableInside = CellRenderer.hasFocusableInside?.(item);
258
-
259
267
  if (hasFocusableInside) {
260
268
  return (
261
269
  <View onLayout={this.onLayout}>
262
- <CellWithFocusable
263
- CellRenderer={CellRenderer}
264
- item={item}
270
+ <FocusableWrapper
265
271
  id={focusableId}
266
- groupId={(groupId || component?.id).toString()}
272
+ groupId={String(groupId || component?.id)}
273
+ isParallaxDisabled={this.layout?.width > 1740}
267
274
  onFocus={handleFocus}
268
- index={index}
269
- scrollTo={this.scrollTo}
270
- preferredFocus={preferredFocus}
271
- focused={this.props.focused}
272
- behavior={behavior}
273
- isFocusable={isFocusable}
274
- />
275
+ onBlur={onBlur || this.onBlur}
276
+ applyWrapper={applyFocusableWrapper}
277
+ >
278
+ {(focused) => (
279
+ <CellWithFocusable
280
+ CellRenderer={CellRenderer}
281
+ item={item}
282
+ id={focusableId}
283
+ groupId={(groupId || component?.id).toString()}
284
+ onFocus={handleFocus}
285
+ index={index}
286
+ scrollTo={this.scrollTo}
287
+ preferredFocus={preferredFocus}
288
+ focused={focused || this.props.focused}
289
+ behavior={behavior}
290
+ isFocusable={isFocusable}
291
+ />
292
+ )}
293
+ </FocusableWrapper>
275
294
  </View>
276
295
  );
277
296
  }
@@ -309,3 +328,47 @@ export class TvOSCellComponent extends React.Component<Props, State> {
309
328
  );
310
329
  }
311
330
  }
331
+
332
+ export function withFocusableWrapperHOC(Component) {
333
+ return function WrappedComponent(props) {
334
+ const [focusableViewIsRendered, setFocusableViewIsRendered] =
335
+ React.useState(false);
336
+
337
+ const { CellRenderer, item, isFocusable, groupId, component } = props;
338
+
339
+ const focusableGroupId = String(groupId || component?.id);
340
+
341
+ const hasFocusableInside = CellRenderer.hasFocusableInside?.(item);
342
+
343
+ React.useEffect(() => {
344
+ // start waiting any first registration of FocusableButton inside this focusableGroup
345
+ // after it we could get rid of applying focusable-wrapper
346
+ const subscription = focusableButtonsRegistration$(focusableGroupId)
347
+ .pipe(
348
+ filter(() => isFocusable),
349
+ first()
350
+ )
351
+ .subscribe(() => {
352
+ setFocusableViewIsRendered(true);
353
+ });
354
+
355
+ return () => {
356
+ subscription.unsubscribe();
357
+ };
358
+ }, [isFocusable, focusableGroupId]);
359
+
360
+ const applyFocusableWrapper = React.useMemo(() => {
361
+ return isFocusable && hasFocusableInside && !focusableViewIsRendered;
362
+ }, [isFocusable, hasFocusableInside, focusableViewIsRendered]);
363
+
364
+ return (
365
+ <Component
366
+ {...props}
367
+ applyFocusableWrapper={applyFocusableWrapper}
368
+ hasFocusableInside={hasFocusableInside}
369
+ />
370
+ );
371
+ };
372
+ }
373
+
374
+ export const TvOSCellComponent = compose(withFocusableWrapperHOC)(TvOSCell);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "15.0.0-rc.11",
3
+ "version": "15.0.0-rc.13",
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": "15.0.0-rc.11",
32
- "@applicaster/zapp-react-native-bridge": "15.0.0-rc.11",
33
- "@applicaster/zapp-react-native-redux": "15.0.0-rc.11",
34
- "@applicaster/zapp-react-native-utils": "15.0.0-rc.11",
31
+ "@applicaster/applicaster-types": "15.0.0-rc.13",
32
+ "@applicaster/zapp-react-native-bridge": "15.0.0-rc.13",
33
+ "@applicaster/zapp-react-native-redux": "15.0.0-rc.13",
34
+ "@applicaster/zapp-react-native-utils": "15.0.0-rc.13",
35
35
  "promise": "^8.3.0",
36
36
  "url": "^0.11.0",
37
37
  "uuid": "^3.3.2"