Skip to content

Commit

Permalink
Merge pull request #29267 from fvlvte/24955-migrate-withKeyboardState…
Browse files Browse the repository at this point in the history
…-hoc

[TS migration] Migrate 'useKeyboardState.js' hook to TypeScript
  • Loading branch information
mountiny authored Dec 29, 2023
2 parents 8c9a30d + fd31080 commit b1c6883
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 79 deletions.
68 changes: 0 additions & 68 deletions src/components/withKeyboardState.js

This file was deleted.

68 changes: 68 additions & 0 deletions src/components/withKeyboardState.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import PropTypes from 'prop-types';
import React, {ComponentType, createContext, ForwardedRef, forwardRef, ReactElement, RefAttributes, useEffect, useMemo, useState} from 'react';
import {Keyboard} from 'react-native';
import getComponentDisplayName from '@libs/getComponentDisplayName';
import ChildrenProps from '@src/types/utils/ChildrenProps';

type KeyboardStateContextValue = {
/** Whether the keyboard is open */
isKeyboardShown: boolean;
};

// TODO: Remove - left for backwards compatibility with existing components (https://github.com/Expensify/App/issues/25151)
const keyboardStatePropTypes = {
/** Whether the keyboard is open */
isKeyboardShown: PropTypes.bool.isRequired,
};

const KeyboardStateContext = createContext<KeyboardStateContextValue | null>(null);

function KeyboardStateProvider({children}: ChildrenProps): ReactElement | null {
const [isKeyboardShown, setIsKeyboardShown] = useState(false);

useEffect(() => {
const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => {
setIsKeyboardShown(true);
});
const keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', () => {
setIsKeyboardShown(false);
});

return () => {
keyboardDidShowListener.remove();
keyboardDidHideListener.remove();
};
}, []);

const contextValue = useMemo(
() => ({
isKeyboardShown,
}),
[isKeyboardShown],
);
return <KeyboardStateContext.Provider value={contextValue}>{children}</KeyboardStateContext.Provider>;
}

export default function withKeyboardState<TProps extends KeyboardStateContextValue, TRef>(
WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>,
): (props: Omit<TProps, keyof KeyboardStateContextValue> & React.RefAttributes<TRef>) => ReactElement | null {
function WithKeyboardState(props: Omit<TProps, keyof KeyboardStateContextValue>, ref: ForwardedRef<TRef>) {
return (
<KeyboardStateContext.Consumer>
{(keyboardStateProps) => (
<WrappedComponent
// eslint-disable-next-line react/jsx-props-no-spreading
{...keyboardStateProps}
// eslint-disable-next-line react/jsx-props-no-spreading
{...(props as TProps)}
ref={ref}
/>
)}
</KeyboardStateContext.Consumer>
);
}
WithKeyboardState.displayName = `withKeyboardState(${getComponentDisplayName(WrappedComponent)})`;
return forwardRef(WithKeyboardState);
}

export {KeyboardStateProvider, keyboardStatePropTypes, type KeyboardStateContextValue, KeyboardStateContext};
11 changes: 0 additions & 11 deletions src/hooks/useKeyboardState.js

This file was deleted.

10 changes: 10 additions & 0 deletions src/hooks/useKeyboardState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {useContext} from 'react';
import {KeyboardStateContext, KeyboardStateContextValue} from '@components/withKeyboardState';

/**
* Hook for getting current state of keyboard
* whether the keyboard is open
*/
export default function useKeyboardState(): KeyboardStateContextValue | null {
return useContext(KeyboardStateContext);
}

0 comments on commit b1c6883

Please sign in to comment.