@applicaster/zapp-react-native-ui-components 15.0.0-rc.12 → 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
|
-
|
|
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
|
-
<
|
|
263
|
-
CellRenderer={CellRenderer}
|
|
264
|
-
item={item}
|
|
270
|
+
<FocusableWrapper
|
|
265
271
|
id={focusableId}
|
|
266
|
-
groupId={(groupId || component?.id)
|
|
272
|
+
groupId={String(groupId || component?.id)}
|
|
273
|
+
isParallaxDisabled={this.layout?.width > 1740}
|
|
267
274
|
onFocus={handleFocus}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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.
|
|
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.
|
|
32
|
-
"@applicaster/zapp-react-native-bridge": "15.0.0-rc.
|
|
33
|
-
"@applicaster/zapp-react-native-redux": "15.0.0-rc.
|
|
34
|
-
"@applicaster/zapp-react-native-utils": "15.0.0-rc.
|
|
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"
|