Skip to content

Commit dbaa0ed

Browse files
committed
Focus fixes and react-native polyfill fixes
Fixes focus manager not resetting focusability for elements that change parents Fixes elements getting loaded event too early, causing some layout issues in react native
1 parent 7c7f432 commit dbaa0ed

File tree

5 files changed

+41
-4
lines changed

5 files changed

+41
-4
lines changed

.changeset/busy-donkeys-report.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@plextv/react-native-lightning": patch
3+
---
4+
5+
fix(polyfill): Set loaded flags for elements on layout event, rather than inViewport

.changeset/empty-streets-call.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@plextv/react-native-lightning": patch
3+
---
4+
5+
feat(polyfill): Add requestTVFocus polyfill

.changeset/stale-shoes-press.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@plextv/react-lightning": patch
3+
---
4+
5+
fix(focus): Fix focusability of items not getting reset when element parent changes

packages/react-lightning/src/focus/FocusManager.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,16 @@ export class FocusManager<
205205

206206
if (index !== -1) {
207207
childNode.parent.children.splice(index, 1);
208+
this._checkFocusableChildren(childNode.parent);
208209
}
209210

210211
childNode.parent = parentNode;
212+
213+
// If we weren't focusable before, assume we can be now and then check again
214+
if (!childNode.element.focusable) {
215+
childNode.element.focusable = true;
216+
this._checkFocusableChildren(parentNode);
217+
}
211218
}
212219
} else {
213220
// If the child node doesn't exist, we need to create it
@@ -522,6 +529,10 @@ export class FocusManager<
522529
let currChild: FocusNode<T> | RootNode<T> = childNode;
523530
const elements = this.activeLayer.elements;
524531

532+
if (currChild.children.length && !currChild.focusedElement) {
533+
this._findNextBestFocus(currChild);
534+
}
535+
525536
while (currChild && !isRootNode(currChild) && currParent) {
526537
if (currChild.focusRedirect && currChild.destinations) {
527538
// TODO: Probably something smarter here to decide which destination to focus

packages/react-native-lightning/src/plugins/reactNativePolyfillsPlugin.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,27 @@ export const reactNativePolyfillsPlugin = (): Plugin => {
111111

112112
if (!focusManager) {
113113
console.warn(
114-
'>> FocusManager not found, cannot set destinations',
114+
'[react-native-lightning polyfills] FocusManager not found, cannot set destinations',
115115
);
116116
return;
117117
}
118118
}
119119

120120
focusManager.setDestinations(this, destinations);
121121
},
122-
requestTVFocus(): void {
123-
// No-op
122+
requestTVFocus(this: LightningNativeViewElement): void {
123+
if (!focusManager) {
124+
focusManager = tryFindFocusManager(this.node.__reactFiber);
125+
126+
if (!focusManager) {
127+
console.warn(
128+
'[react-native-lightning polyfills] FocusManager not found, failed to request focus',
129+
);
130+
return;
131+
}
132+
}
133+
134+
focusManager.focus(this);
124135
},
125136
} satisfies Partial<LightningNativeViewElement>;
126137

@@ -152,7 +163,7 @@ export const reactNativePolyfillsPlugin = (): Plugin => {
152163

153164
// Initialize the load promise to resolve when the instance is available
154165
nativeInstance.__loadPromise = new Promise<void>((resolve) => {
155-
nativeInstance.once('inViewport', () => {
166+
nativeInstance.once('layout', () => {
156167
nativeInstance.__loaded = true;
157168
resolve();
158169
});

0 commit comments

Comments
 (0)