UNPKG

@applicaster/zapp-react-native-ui-components

Version:

Applicaster Zapp React Native ui components for the Quick Brick App

232 lines (201 loc) 5.99 kB
import * as React from "react"; import { BaseFocusable as BaseFocusableInterface } from "./BaseFocusable.interface"; import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager"; import * as FOCUS_EVENTS from "@applicaster/zapp-react-native-utils/appUtils/focusManager/events"; import { noop } from "@applicaster/zapp-react-native-utils/functionUtils"; type Props = { initialFocus?: boolean; id: string; groupId: string; preferredFocus?: boolean; onRegister?: (focusable: FocusManager.TouchableRef) => void; onUnregister?: (focusable: FocusManager.TouchableRef) => void; willReceiveFocus?: FocusManager.FocusEventCB; hasReceivedFocus?: FocusManager.FocusEventCB; willLoseFocus?: FocusManager.FocusEventCB; hasLostFocus?: FocusManager.FocusEventCB; failedLostFocus?: FocusManager.FocusEventCB; onPress?: (nativeEvent: React.SyntheticEvent) => void; onFocus?: FocusManager.FocusEventCB; onBlur?: FocusManager.FocusEventCB; selected?: boolean; }; export class BaseFocusable< T extends Props = Props, > extends BaseFocusableInterface<T> { constructor(props) { super(props); this._isMounted = false; this.state = { focused: false, boundingRect: { x: 0, y: 0, width: 0, height: 0, top: 0, bottom: 0, left: 0, right: 0, }, }; this.onRegister = this.onRegister.bind(this); this.onUnregister = this.onUnregister.bind(this); this.setFocusedState = this.setFocusedState.bind(this); this.willReceiveFocus = this.willReceiveFocus.bind(this); this.onFocus = this.onFocus.bind(this); this.hasReceivedFocus = this.hasReceivedFocus.bind(this); this.willLoseFocus = this.willLoseFocus.bind(this); this.onBlur = this.onBlur.bind(this); this.hasLostFocus = this.hasLostFocus.bind(this); this.failedLostFocus = this.failedLostFocus.bind(this); this.onPress = this.onPress.bind(this); this.ref = React.createRef(); } componentDidMount() { const { id } = this.props; const component = this; this.node = this.ref.current; focusManager.register({ id, component: component, }); } measureView() { this.ref.current.measure((x, y, width, height, pageX, pageY) => { const top = pageY; const bottom = top + height; const left = pageX; const right = left + width; if (this._isMounted) { this.setState({ boundingRect: { x, y, width, height, top, bottom, left, right, }, }); } }); } getId() { const { id } = this.props; return id; } getRect() { const { boundingRect } = this.state; return { top: boundingRect?.top, left: boundingRect?.left, right: boundingRect?.right, bottom: boundingRect?.bottom, width: boundingRect?.width, height: boundingRect?.height, x: boundingRect?.x, y: boundingRect?.y, }; } componentWillUnmount() { this._isMounted = false; const { id } = this.props; focusManager.unregister(id, { group: this.isGroup || false }); } onRegister(focusable) { this._isMounted = true; const { onRegister = noop } = this.props; onRegister(focusable); } onUnregister(focusable) { const { onUnregister = noop } = this.props; onUnregister(focusable); } willLoseFocus(focusable, scrollDirection) { const { willLoseFocus = noop } = this.props; willLoseFocus(focusable, scrollDirection); } willReceiveFocus(focusable, scrollDirection) { const { willReceiveFocus = noop } = this.props; willReceiveFocus(focusable, scrollDirection); } /** * will invoke the underlying component's focus method * @param {Object} focusable - sender * @param {Object} scrollDirection * @returns {Promise} */ onFocus(focusable, scrollDirection) { const { onFocus = noop } = this.props; this.setFocusedState(true); onFocus(focusable, scrollDirection); focusManager.invokeHandler?.( FOCUS_EVENTS.FOCUS, focusable, scrollDirection ); } /** * will invoke the underlying component's hasReceivedFocus method * @param {Object} focusable - sender * @param {Object} scrollDirection * @returns {Promise} */ hasReceivedFocus(focusable, scrollDirection) { const { hasReceivedFocus = noop } = this.props; hasReceivedFocus(focusable, scrollDirection); } /** * will invoke the underlying component's hasLostFocus method * @param {Object} focusable - sender * @param {Object} scrollDirection * @returns {Promise} */ hasLostFocus(focusable, scrollDirection) { const { hasLostFocus = noop } = this.props; hasLostFocus(focusable, scrollDirection); } /** * will invoke the underlying component's failedLostFocus method * @param {Object} focusable - sender * @param {Object} scrollDirection * @returns {Promise} */ failedLostFocus(focusable, scrollDirection) { const { failedLostFocus = noop } = this.props; failedLostFocus(focusable, scrollDirection); } /** * will invoke the underlying component's onBlur method * @param {Object} focusable - sender * @param {Object} scrollDirection * @returns {Promise} */ onBlur(focusable, scrollDirection) { const { onBlur = noop } = this.props; this.setFocusedState(false); onBlur(focusable, scrollDirection); } /** * will invoke the underlying component's onPress method * @param {Object} keyEvent * @returns {Promise} */ onPress(keyEvent) { const { onPress = noop } = this.props; onPress(keyEvent); } isInGroup(group) { const { groupId } = this.props; const { id } = group.props; return id === groupId; } setFocusedState(focused) { if (this._isMounted) { this.setState({ focused }); } } }