@applicaster/zapp-react-native-ui-components 14.0.0-alpha.6461844364 → 14.0.0-alpha.6893149866
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.
- package/Components/AudioPlayer/mobile/Layout.tsx +1 -1
- package/Components/AudioPlayer/tv/helpers.tsx +10 -3
- package/Components/BaseFocusable/index.tsx +23 -12
- package/Components/Cell/Cell.tsx +87 -65
- package/Components/Cell/CellWithFocusable.tsx +3 -0
- package/Components/Cell/__tests__/CellWIthFocusable.test.js +3 -2
- package/Components/Cell/index.js +1 -1
- package/Components/ComponentResolver/index.ts +1 -1
- package/Components/FeedLoader/FeedLoader.tsx +7 -16
- package/Components/FeedLoader/FeedLoaderHOC.tsx +21 -0
- package/Components/FeedLoader/index.js +2 -8
- package/Components/Focusable/Focusable.tsx +10 -3
- package/Components/Focusable/FocusableTvOS.tsx +2 -2
- package/Components/Focusable/FocusableiOS.tsx +2 -2
- package/Components/Focusable/index.tsx +1 -1
- package/Components/FocusableGroup/FocusableTvOS.tsx +1 -1
- package/Components/FocusableList/index.tsx +2 -2
- package/Components/FreezeWithCallback/__tests__/index.test.tsx +67 -43
- package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +42 -59
- package/Components/GeneralContentScreen/utils/useCurationAPI.ts +13 -10
- package/Components/Layout/TV/LayoutBackground.tsx +1 -1
- package/Components/Layout/TV/__tests__/index.test.tsx +0 -1
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +6 -2
- package/Components/MasterCell/DefaultComponents/Button.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +0 -12
- package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +1 -1
- package/Components/MasterCell/DefaultComponents/Text/index.tsx +26 -6
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +10 -10
- package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +18 -18
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/index.test.tsx +10 -10
- package/Components/MasterCell/utils/behaviorProvider.ts +82 -14
- package/Components/MasterCell/utils/index.ts +11 -5
- package/Components/OfflineHandler/__tests__/index.test.tsx +26 -35
- package/Components/PlayerContainer/ErrorDisplay/index.ts +1 -1
- package/Components/PlayerContainer/PlayerContainer.tsx +4 -1
- package/Components/PlayerContainer/ProgramInfo/index.tsx +1 -1
- package/Components/PlayerContainer/index.ts +1 -1
- package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +378 -0
- package/Components/River/ComponentsMap/hooks/useLoadingState.ts +2 -2
- package/Components/River/RefreshControl.tsx +11 -17
- package/Components/River/TV/River.tsx +2 -17
- package/Components/River/TV/index.tsx +3 -1
- package/Components/River/TV/withPipesV1DataLoader.tsx +43 -0
- package/Components/River/TV/withRiverDataLoader.tsx +17 -0
- package/Components/River/__tests__/river.test.js +12 -26
- package/Components/River/index.tsx +1 -1
- package/Components/Screen/__tests__/Screen.test.tsx +28 -29
- package/Components/Screen/__tests__/navigationHandler.test.ts +133 -22
- package/Components/Screen/navigationHandler.ts +20 -2
- package/Components/ScreenRevealManager/ScreenRevealManager.ts +76 -0
- package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +107 -0
- package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +96 -0
- package/Components/ScreenRevealManager/index.ts +1 -0
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +79 -0
- package/Components/Tabs/TV/Tabs.android.tsx +1 -1
- package/Components/Tabs/Tabs.tsx +2 -3
- package/Components/TextInputTv/__tests__/__snapshots__/TextInputTv.test.js.snap +3 -3
- package/Components/Touchable/__tests__/touchable.test.tsx +12 -17
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.web.tsx +294 -0
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.web.tsx +93 -0
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +66 -30
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -5
- package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +9 -1
- package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +40 -15
- package/Contexts/CellFocusedStateContext/index.tsx +27 -0
- package/Contexts/ConfigutaionContext/__tests__/ConfigurationProvider.test.tsx +3 -3
- package/Contexts/ScreenContext/index.tsx +46 -6
- package/Decorators/ConfigurationWrapper/__tests__/withConfigurationProvider.test.tsx +3 -3
- package/Decorators/RiverFeedLoader/__tests__/__snapshots__/riverFeedLoader.test.tsx.snap +221 -209
- package/Decorators/RiverFeedLoader/__tests__/riverFeedLoader.test.tsx +14 -16
- package/Decorators/RiverFeedLoader/__tests__/utils.test.ts +0 -20
- package/Decorators/RiverFeedLoader/index.tsx +22 -4
- package/Decorators/RiverFeedLoader/utils/index.ts +0 -18
- package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +3 -6
- package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -0
- package/Decorators/ZappPipesDataConnector/__tests__/NullFeedResolver.test.tsx +78 -0
- package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +205 -0
- package/Decorators/ZappPipesDataConnector/__tests__/StaticFeedResolver.test.tsx +251 -0
- package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +368 -0
- package/Decorators/ZappPipesDataConnector/__tests__/utils.test.ts +39 -0
- package/Decorators/ZappPipesDataConnector/index.tsx +26 -293
- package/Decorators/ZappPipesDataConnector/resolvers/NullFeedResolver.tsx +25 -0
- package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +87 -0
- package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +266 -0
- package/Decorators/ZappPipesDataConnector/types.ts +29 -0
- package/Decorators/ZappPipesDataConnector/utils/mongoFilter.ts +738 -0
- package/Decorators/ZappPipesDataConnector/utils/useFilter.tsx +157 -0
- package/events/index.ts +1 -0
- package/package.json +5 -6
- package/Components/River/__tests__/__snapshots__/river.test.js.snap +0 -27
|
@@ -27,7 +27,7 @@ export function AudioPlayerMobileLayout({
|
|
|
27
27
|
}: Props) {
|
|
28
28
|
const fadeAnimation = useRef(new Animated.Value(0)).current;
|
|
29
29
|
|
|
30
|
-
const mainContainerStyles = platformSelect({
|
|
30
|
+
const mainContainerStyles: ViewStyle = platformSelect({
|
|
31
31
|
native: {
|
|
32
32
|
backgroundColor: "transparent",
|
|
33
33
|
overflow: "hidden",
|
|
@@ -27,13 +27,20 @@ const LTR = {
|
|
|
27
27
|
justifyContent: "flex-start",
|
|
28
28
|
textAlign: "left",
|
|
29
29
|
alignItems: "flex-end",
|
|
30
|
-
};
|
|
30
|
+
} as const;
|
|
31
31
|
|
|
32
32
|
const RTL = {
|
|
33
33
|
flexDirection: "row-reverse",
|
|
34
34
|
justifyContent: "flex-end",
|
|
35
35
|
textAlign: "right",
|
|
36
36
|
alignItems: "flex-start",
|
|
37
|
-
};
|
|
37
|
+
} as const;
|
|
38
38
|
|
|
39
|
-
export const directionStyles = (
|
|
39
|
+
export const directionStyles = (
|
|
40
|
+
isRTL: boolean
|
|
41
|
+
): {
|
|
42
|
+
flexDirection: "row" | "row-reverse";
|
|
43
|
+
justifyContent: "flex-start" | "flex-end";
|
|
44
|
+
textAlign: "left" | "right";
|
|
45
|
+
alignItems: "flex-end" | "flex-start";
|
|
46
|
+
} => (isRTL ? RTL : LTR);
|
|
@@ -146,10 +146,14 @@ export class BaseFocusable<
|
|
|
146
146
|
* @param {Object} scrollDirection
|
|
147
147
|
* @returns {Promise}
|
|
148
148
|
*/
|
|
149
|
-
onFocus: FocusManager.FocusEventCB = (
|
|
149
|
+
onFocus: FocusManager.FocusEventCB = (
|
|
150
|
+
focusable,
|
|
151
|
+
scrollDirection,
|
|
152
|
+
context
|
|
153
|
+
) => {
|
|
150
154
|
const { onFocus = noop } = this.props;
|
|
151
155
|
this.setFocusedState(true);
|
|
152
|
-
onFocus(focusable, scrollDirection);
|
|
156
|
+
onFocus(focusable, scrollDirection, context);
|
|
153
157
|
};
|
|
154
158
|
|
|
155
159
|
/**
|
|
@@ -247,8 +251,8 @@ export class BaseFocusable<
|
|
|
247
251
|
* @param {Object} scrollDirection
|
|
248
252
|
* @returns {Promise}
|
|
249
253
|
*/
|
|
250
|
-
focus(_, scrollDirection) {
|
|
251
|
-
return this.onFocus(this, scrollDirection); // invokeComponentMethod(this, "onFocus", scrollDirection);
|
|
254
|
+
focus(_, scrollDirection, context?: FocusManager.FocusContext) {
|
|
255
|
+
return this.onFocus(this, scrollDirection, context); // invokeComponentMethod(this, "onFocus", scrollDirection, context);
|
|
252
256
|
}
|
|
253
257
|
|
|
254
258
|
/**
|
|
@@ -258,9 +262,10 @@ export class BaseFocusable<
|
|
|
258
262
|
*/
|
|
259
263
|
blur(
|
|
260
264
|
_,
|
|
261
|
-
scrollDirection?: FocusManager.Web.Direction | FocusManager.IOS.Direction
|
|
265
|
+
scrollDirection?: FocusManager.Web.Direction | FocusManager.IOS.Direction,
|
|
266
|
+
context?: FocusManager.FocusContext
|
|
262
267
|
) {
|
|
263
|
-
return this.onBlur(this, scrollDirection);
|
|
268
|
+
return this.onBlur(this, scrollDirection, context);
|
|
264
269
|
}
|
|
265
270
|
|
|
266
271
|
/**
|
|
@@ -272,7 +277,7 @@ export class BaseFocusable<
|
|
|
272
277
|
* @param {string} scrollDirection string representation of the direction of the navigation which landed
|
|
273
278
|
* to this item being focused
|
|
274
279
|
*/
|
|
275
|
-
_executeFocusSequence(methodNames, scrollDirection) {
|
|
280
|
+
_executeFocusSequence(methodNames, scrollDirection, context) {
|
|
276
281
|
return R.reduce(
|
|
277
282
|
(sequence, methodName) => {
|
|
278
283
|
const method = this[methodName]; // Access the method by name
|
|
@@ -284,7 +289,7 @@ export class BaseFocusable<
|
|
|
284
289
|
}
|
|
285
290
|
|
|
286
291
|
return sequence
|
|
287
|
-
.then(() => method.call(this, scrollDirection))
|
|
292
|
+
.then(() => method.call(this, this, scrollDirection, context))
|
|
288
293
|
.catch((e) => {
|
|
289
294
|
throw e; // Re-throw for consistent error handling
|
|
290
295
|
});
|
|
@@ -294,15 +299,21 @@ export class BaseFocusable<
|
|
|
294
299
|
);
|
|
295
300
|
}
|
|
296
301
|
|
|
297
|
-
setFocus(
|
|
302
|
+
setFocus(
|
|
303
|
+
scrollDirection?: ScrollDirection,
|
|
304
|
+
context?: FocusManager.FocusContext
|
|
305
|
+
) {
|
|
298
306
|
const focusMethods = ["willReceiveFocus", "focus", "hasReceivedFocus"];
|
|
299
307
|
|
|
300
|
-
return this._executeFocusSequence(focusMethods, scrollDirection);
|
|
308
|
+
return this._executeFocusSequence(focusMethods, scrollDirection, context);
|
|
301
309
|
}
|
|
302
310
|
|
|
303
|
-
setBlur(
|
|
311
|
+
setBlur(
|
|
312
|
+
scrollDirection?: ScrollDirection,
|
|
313
|
+
context?: FocusManager.FocusContext
|
|
314
|
+
) {
|
|
304
315
|
const blurMethods = ["willLoseFocus", "blur", "hasLostFocus"];
|
|
305
316
|
|
|
306
|
-
return this._executeFocusSequence(blurMethods, scrollDirection);
|
|
317
|
+
return this._executeFocusSequence(blurMethods, scrollDirection, context);
|
|
307
318
|
}
|
|
308
319
|
}
|
package/Components/Cell/Cell.tsx
CHANGED
|
@@ -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,6 +69,7 @@ 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> {
|
|
@@ -81,9 +84,11 @@ export class CellComponent extends React.Component<Props, State> {
|
|
|
81
84
|
this.hasReceivedFocus = this.hasReceivedFocus.bind(this);
|
|
82
85
|
this.scrollVertically = this.scrollVertically.bind(this);
|
|
83
86
|
this.scrollToIndex = this.scrollToIndex.bind(this);
|
|
87
|
+
this.handleAccessibilityFocus = this.handleAccessibilityFocus.bind(this);
|
|
84
88
|
|
|
85
89
|
this.state = {
|
|
86
90
|
hasFocusableInside: props.CellRenderer.hasFocusableInside?.(props.item),
|
|
91
|
+
cellFocused: false,
|
|
87
92
|
};
|
|
88
93
|
|
|
89
94
|
this.accessibilityManager = AccessibilityManager.getInstance();
|
|
@@ -134,6 +139,8 @@ export class CellComponent extends React.Component<Props, State> {
|
|
|
134
139
|
} = this.props;
|
|
135
140
|
|
|
136
141
|
if (isFocusable) {
|
|
142
|
+
this.setState({ cellFocused: true });
|
|
143
|
+
|
|
137
144
|
if (
|
|
138
145
|
shouldUpdate &&
|
|
139
146
|
shouldScrollVertically?.(mouse, focusable, id, title)
|
|
@@ -143,7 +150,9 @@ export class CellComponent extends React.Component<Props, State> {
|
|
|
143
150
|
}
|
|
144
151
|
}
|
|
145
152
|
|
|
146
|
-
onBlur() {
|
|
153
|
+
onBlur() {
|
|
154
|
+
this.setState({ cellFocused: false });
|
|
155
|
+
}
|
|
147
156
|
|
|
148
157
|
willReceiveFocus() {}
|
|
149
158
|
|
|
@@ -187,6 +196,25 @@ export class CellComponent extends React.Component<Props, State> {
|
|
|
187
196
|
return !isFocusable ? false : focused || focusableFocused;
|
|
188
197
|
}
|
|
189
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
|
+
|
|
190
218
|
componentDidUpdate(prevProps: Readonly<Props>) {
|
|
191
219
|
if (prevProps.item !== this.props.item) {
|
|
192
220
|
this.setState({
|
|
@@ -195,6 +223,8 @@ export class CellComponent extends React.Component<Props, State> {
|
|
|
195
223
|
),
|
|
196
224
|
});
|
|
197
225
|
}
|
|
226
|
+
|
|
227
|
+
this.handleAccessibilityFocus(this.props.index, this.props.dataLength);
|
|
198
228
|
}
|
|
199
229
|
|
|
200
230
|
render() {
|
|
@@ -216,7 +246,6 @@ export class CellComponent extends React.Component<Props, State> {
|
|
|
216
246
|
} = this.props;
|
|
217
247
|
|
|
218
248
|
const { id } = item;
|
|
219
|
-
|
|
220
249
|
const focusableId = join("-", [component?.id, id, index]);
|
|
221
250
|
|
|
222
251
|
const handleFocus = (focusable, mouse) => {
|
|
@@ -227,74 +256,67 @@ export class CellComponent extends React.Component<Props, State> {
|
|
|
227
256
|
|
|
228
257
|
if (this.state.hasFocusableInside) {
|
|
229
258
|
return (
|
|
230
|
-
<
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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>
|
|
242
274
|
);
|
|
243
275
|
}
|
|
244
276
|
|
|
245
277
|
return (
|
|
246
|
-
<
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
<Focusable
|
|
252
|
-
id={focusableId}
|
|
253
|
-
groupId={groupId || component?.id}
|
|
254
|
-
onFocus={handleFocus}
|
|
255
|
-
onBlur={onBlur || this.onBlur}
|
|
256
|
-
onPress={this.onPress}
|
|
257
|
-
willReceiveFocus={willReceiveFocus || this.willReceiveFocus}
|
|
258
|
-
hasReceivedFocus={hasReceivedFocus || this.hasReceivedFocus}
|
|
259
|
-
preferredFocus={preferredFocus}
|
|
260
|
-
offsetUpdater={offsetUpdater}
|
|
261
|
-
style={styles.baseCell}
|
|
262
|
-
isFocusable={isFocusable}
|
|
263
|
-
skipFocusManagerRegistration={skipFocusManagerRegistration}
|
|
264
|
-
{...this.accessibilityManager.getButtonAccessibilityProps(
|
|
265
|
-
item?.extensions?.accessibility?.label || item?.title
|
|
266
|
-
)}
|
|
278
|
+
<CellFocusedStateContextProvider cellFocused={this.state.cellFocused}>
|
|
279
|
+
<View
|
|
280
|
+
testID={`${component?.id}-${id}`}
|
|
281
|
+
accessible={false}
|
|
282
|
+
style={styles.touchableCell}
|
|
267
283
|
>
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
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>
|
|
298
320
|
);
|
|
299
321
|
}
|
|
300
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
|
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { View } from "react-native";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { act
|
|
3
|
+
import { act } from "@testing-library/react-native";
|
|
4
4
|
import { CellWithFocusable } from "../CellWithFocusable.tsx";
|
|
5
5
|
|
|
6
6
|
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
|
|
7
|
+
import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils/index.tsx";
|
|
7
8
|
|
|
8
9
|
const renderWith = (props) => {
|
|
9
|
-
return
|
|
10
|
+
return renderWithProviders(<CellWithFocusable {...props} />);
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
describe("CellWithFocusable", () => {
|
package/Components/Cell/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
2
|
|
|
3
|
-
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
3
|
+
import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
|
|
4
4
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
5
5
|
|
|
6
6
|
import {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as R from "ramda";
|
|
2
2
|
|
|
3
|
-
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
3
|
+
import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
|
|
4
4
|
|
|
5
5
|
import { ComponentResolverComponent } from "./ComponentResolver";
|
|
6
6
|
|
|
@@ -1,25 +1,16 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
|
+
import { selectZappPipes } from "@applicaster/zapp-react-native-redux";
|
|
3
4
|
|
|
4
5
|
type Props = {
|
|
5
|
-
zappPipes:
|
|
6
|
-
loadPipesData:
|
|
7
|
-
feed
|
|
8
|
-
|
|
9
|
-
clearCache: boolean;
|
|
10
|
-
meta: any;
|
|
11
|
-
loadLocalFavorites: boolean;
|
|
12
|
-
silentRefresh: boolean;
|
|
13
|
-
parentFeed: ZappFeed;
|
|
14
|
-
callback: () => void;
|
|
15
|
-
bodyParams: any;
|
|
16
|
-
riverId: string;
|
|
17
|
-
}>
|
|
18
|
-
) => void;
|
|
6
|
+
zappPipes: ReturnType<typeof selectZappPipes>;
|
|
7
|
+
loadPipesData: ReturnType<
|
|
8
|
+
typeof import("@applicaster/zapp-react-native-utils/reactHooks/feed").useLoadPipesDataDispatch
|
|
9
|
+
>;
|
|
19
10
|
feedUrl: string;
|
|
20
|
-
children: (feed: ZappFeed) => React.
|
|
11
|
+
children: (feed: ZappFeed) => React.ReactNode;
|
|
21
12
|
onFeedLoaded: (feed: ZappFeed) => {};
|
|
22
|
-
onError: (
|
|
13
|
+
onError: (error: ZappPipesData["error"]) => {};
|
|
23
14
|
refreshing: boolean;
|
|
24
15
|
refreshCallback: () => void;
|
|
25
16
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
selectZappPipes,
|
|
4
|
+
useAppSelector,
|
|
5
|
+
} from "@applicaster/zapp-react-native-redux";
|
|
6
|
+
import { useLoadPipesDataDispatch } from "@applicaster/zapp-react-native-utils/reactHooks/feed";
|
|
7
|
+
|
|
8
|
+
export const FeedLoaderHOC = (_Component: any) => {
|
|
9
|
+
return function FeedLoaderHOC(props: any) {
|
|
10
|
+
const zappPipes = useAppSelector(selectZappPipes);
|
|
11
|
+
const loadPipesData = useLoadPipesDataDispatch();
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<_Component
|
|
15
|
+
{...props}
|
|
16
|
+
zappPipes={zappPipes}
|
|
17
|
+
loadPipesData={loadPipesData}
|
|
18
|
+
/>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import * as R from "ramda";
|
|
2
|
-
|
|
3
|
-
import { connectToStore } from "@applicaster/zapp-react-native-redux";
|
|
4
|
-
import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
|
|
5
|
-
|
|
6
1
|
import { FeedLoaderComponent } from "./FeedLoader";
|
|
2
|
+
import { FeedLoaderHOC } from "./FeedLoaderHOC";
|
|
7
3
|
|
|
8
|
-
export const FeedLoader =
|
|
9
|
-
loadPipesData,
|
|
10
|
-
})(FeedLoaderComponent);
|
|
4
|
+
export const FeedLoader = FeedLoaderHOC(FeedLoaderComponent);
|
|
@@ -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.
|
|
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
|
|
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
|
-
{...
|
|
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
|
-
{
|
|
207
|
+
{typeof children === "function" ? children(focused) : children}
|
|
208
208
|
</FocusableItemNative>
|
|
209
209
|
);
|
|
210
210
|
}
|
|
@@ -2,7 +2,7 @@ import React from "react";
|
|
|
2
2
|
|
|
3
3
|
type Props = {
|
|
4
4
|
children: () => React.ReactNode;
|
|
5
|
-
}
|
|
5
|
+
} & Record<string, any>;
|
|
6
6
|
|
|
7
7
|
function FocusableiOSComponent({ children }: Props) {
|
|
8
8
|
if (typeof children === "function") {
|
|
@@ -12,4 +12,4 @@ function FocusableiOSComponent({ children }: Props) {
|
|
|
12
12
|
return children;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export const FocusableiOS =
|
|
15
|
+
export const FocusableiOS = FocusableiOSComponent;
|
|
@@ -4,7 +4,7 @@ import { FocusableiOS } from "./FocusableiOS";
|
|
|
4
4
|
|
|
5
5
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
6
6
|
|
|
7
|
-
export const Focusable = platformSelect({
|
|
7
|
+
export const Focusable: React.ComponentType<any> = platformSelect({
|
|
8
8
|
tvos: FocusableTvOS,
|
|
9
9
|
ios: FocusableiOS,
|
|
10
10
|
default: FocusableDefault,
|
|
@@ -20,11 +20,11 @@ import { FocusableScrollView } from "../FocusableScrollView";
|
|
|
20
20
|
const mapIndexed = R.addIndex(R.map);
|
|
21
21
|
|
|
22
22
|
export type IListRenderItem<ItemT> = (
|
|
23
|
-
info:
|
|
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) =>
|