Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow dynamically change focusKey #168

Merged
merged 2 commits into from
Sep 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/create/src/components/Pressable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ const View = React.forwardRef<RNView | undefined, PressableProps>(
focusOptions.nextFocusRight,
]);

useEffect(() => {
if (focus) {
model.setFocusKey(focusOptions.focusKey);
}
}, [focusOptions.focusKey]);

useEffect(() => {
if (focus) {
Event.emit(model.getType(), model.getId(), EVENT_TYPES.ON_MOUNT);
Expand Down
18 changes: 9 additions & 9 deletions packages/create/src/components/Screen/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type { ScreenProps } from '../../focusManager/types';
import { useCombinedRefs } from '../../hooks/useCombinedRef';
import ScreenClass from '../../focusManager/model/screen';
import useOnLayout from '../../hooks/useOnLayout';
import Event, { EVENT_TYPES } from '../../focusManager/events';
import useOnComponentLifeCycle from '../../hooks/useOnComponentLifeCycle';
import { CoreManager } from '../..';

Expand Down Expand Up @@ -34,21 +33,22 @@ const Screen = React.forwardRef<RNView | undefined, ScreenProps>(

useOnComponentLifeCycle({ model });

useEffect(() => {
model.setFocusKey(focusOptions.focusKey);
}, [focusOptions.focusKey]);

useEffect(() => {
if (focusOptions.screenState) {
Event.emit(model.getType(), model.getId(), EVENT_TYPES.ON_PROPERTY_CHANGED, {
property: 'state',
newValue: focusOptions.screenState,
});
model.setPrevState(model.getState()).setState(focusOptions.screenState);
if (model.isPrevStateBackground() && model.isInForeground()) {
model.setFocus(model.getFirstFocusableOnScreen());
}
}
}, [focusOptions.screenState]);

useEffect(() => {
if (focusOptions.screenOrder !== undefined) {
Event.emit(model.getType(), model.getId(), EVENT_TYPES.ON_PROPERTY_CHANGED, {
property: 'order',
newValue: focusOptions.screenOrder,
});
model.setOrder(focusOptions.screenOrder);
}
}, [focusOptions.screenOrder]);

Expand Down
4 changes: 4 additions & 0 deletions packages/create/src/components/ViewGroup/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ const ViewGroup = React.forwardRef<View, ViewGroupProps>(
model.setGroup(focusOptions.group);
}, [focusOptions.group]);

useEffect(() => {
model.setFocusKey(focusOptions.focusKey);
}, [focusOptions.focusKey]);

const { onLayout } = useOnLayout(model);

const childrenWithProps = React.Children.map(children, (child) => {
Expand Down
1 change: 0 additions & 1 deletion packages/create/src/focusManager/events.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export const EVENT_TYPES = {
ON_PROPERTY_CHANGED: 'onPropertyChanged',
ON_MOUNT: 'onMount',
ON_MOUNT_AND_MEASURED: 'onMountAndMeasured',
ON_UNMOUNT: 'onUnMount',
Expand Down
32 changes: 10 additions & 22 deletions packages/create/src/focusManager/model/screen.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { View as RNView } from 'react-native';
import { ScreenProps, ScreenStates } from '../types';
import { ScreenProps } from '../types';
import CoreManager from '../service/core';
import Logger from '../service/logger';
import FocusModel, { MODEL_TYPES } from './abstractFocusModel';
Expand Down Expand Up @@ -30,7 +30,7 @@ class Screen extends FocusModel {
private _verticalWindowAlignment: typeof VIEWPORT_ALIGNMENT[keyof typeof VIEWPORT_ALIGNMENT];
private _horizontalWindowAlignment: typeof VIEWPORT_ALIGNMENT[keyof typeof VIEWPORT_ALIGNMENT];
private _order: number;
private _focusKey: string;
private _focusKey?: string;
private _horizontalViewportOffset: number;
private _verticalViewportOffset: number;
private _initialLoadInProgress: boolean;
Expand All @@ -52,7 +52,7 @@ class Screen extends FocusModel {
screenState = SCREEN_STATES.FOREGROUND,
screenOrder = 0,
stealFocus = true,
focusKey = '',
focusKey,
group,
verticalWindowAlignment = VIEWPORT_ALIGNMENT.LOW_EDGE,
horizontalWindowAlignment = VIEWPORT_ALIGNMENT.LOW_EDGE,
Expand Down Expand Up @@ -90,13 +90,11 @@ class Screen extends FocusModel {
this._onMount = this._onMount.bind(this);
this._onUnmount = this._onUnmount.bind(this);
this._onLayout = this._onLayout.bind(this);
this._onPropertyChanged = this._onPropertyChanged.bind(this);

this._events = [
Event.subscribe(this.getType(), this.getId(), EVENT_TYPES.ON_MOUNT, this._onMount),
Event.subscribe(this.getType(), this.getId(), EVENT_TYPES.ON_UNMOUNT, this._onUnmount),
Event.subscribe(this.getType(), this.getId(), EVENT_TYPES.ON_LAYOUT, this._onLayout),
Event.subscribe(this.getType(), this.getId(), EVENT_TYPES.ON_PROPERTY_CHANGED, this._onPropertyChanged),
];
}

Expand All @@ -116,22 +114,6 @@ class Screen extends FocusModel {
measureSync({ model: this });
}

private _onPropertyChanged({ property, newValue }: { property: string; newValue: ScreenStates | number }) {
switch (property) {
case 'state':
this.setPrevState(this.getState()).setState(newValue as ScreenStates);
if (this.isPrevStateBackground() && this.isInForeground()) {
this.setFocus(this.getFirstFocusableOnScreen());
}
break;
case 'order':
this.setOrder(newValue as number);
break;
default:
break;
}
}

// END EVENTS

public onScreenRemoved() {
Expand Down Expand Up @@ -290,10 +272,16 @@ class Screen extends FocusModel {
return this._order;
}

public getFocusKey(): string {
public getFocusKey(): string | undefined {
return this._focusKey;
}

public setFocusKey(value?: string): this {
this._focusKey = value;

return this;
}

public getHorizontalViewportOffset(): number {
return this._horizontalViewportOffset;
}
Expand Down
12 changes: 9 additions & 3 deletions packages/create/src/focusManager/model/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class View extends FocusModel {
private _parentScrollView?: ScrollView;

private _isFocused: boolean;
private _focusKey: string;
private _focusKey?: string;
private _hasPreferredFocus: boolean;
private _verticalContentContainerGap = 0;
private _horizontalContentContainerGap = 0;
Expand Down Expand Up @@ -51,7 +51,7 @@ class View extends FocusModel {
onFocus,
onBlur,
onPress,
focusKey = '',
focusKey,
hasPreferredFocus = false,
verticalContentContainerGap = 0,
horizontalContentContainerGap = 0,
Expand Down Expand Up @@ -214,10 +214,16 @@ class View extends FocusModel {
return this._repeatContext;
}

public getFocusKey(): string {
public getFocusKey(): string | undefined {
return this._focusKey;
}

public setFocusKey(value?: string): this {
this._focusKey = value;

return this;
}

public hasPreferredFocus(): boolean {
return this._hasPreferredFocus;
}
Expand Down
8 changes: 7 additions & 1 deletion packages/create/src/focusManager/model/viewGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,16 @@ class ViewGroup extends FocusModel {
return this;
}

public getFocusKey() {
public getFocusKey(): string | undefined {
return this._focusKey;
}

public setFocusKey(value?: string): this {
this._focusKey = value;

return this;
}

public getNode(): MutableRefObject<View> {
return this.node;
}
Expand Down
Loading