Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
refactor(utils): refactored UserInteractionMode hooks and components
This moved all the "logic" into a single hook and added new tests for this behavior. This also renamed the `InteractionModeListener` to `UserInteractionModeListener` for more consistency, but still has the old name available until the next major release. It has been marked as deprecated which _should_ be caught by editors/IDEs. > This also reduces the bundle size... by a small amount ```sh The gizipped UMD bundle sizes are: - dist/umd/react-md.production.min.js 97.35 KB (- 1 B) - dist/umd/react-md-with-font-icons.production.min.js 120.39 KB (- 4 B) - dist/umd/react-md-with-svg-icons.production.min.js 186.74 KB (- 6 B) ```
- Loading branch information
Showing
13 changed files
with
388 additions
and
241 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
105 changes: 105 additions & 0 deletions
105
packages/utils/src/mode/UserInteractionModeListener.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import React, { | ||
createContext, | ||
ReactElement, | ||
ReactNode, | ||
useContext, | ||
} from "react"; | ||
|
||
import { UserInteractionMode } from "./types"; | ||
import { useInteractionMode } from "./useInteractionMode"; | ||
|
||
/** | ||
* @private | ||
*/ | ||
const modeContext = createContext<UserInteractionMode>("mouse"); | ||
|
||
/** | ||
* @private | ||
*/ | ||
const parentContext = createContext(false); | ||
|
||
/** | ||
* @private | ||
*/ | ||
const { Provider: UserInteractionModeProvider } = modeContext; | ||
|
||
/** | ||
* @private | ||
*/ | ||
const { Provider: ParentProvider } = parentContext; | ||
|
||
/** | ||
* Returns the current user interaction mode. | ||
* | ||
* @return {@link UserInteractionMode} | ||
*/ | ||
export function useUserInteractionMode(): UserInteractionMode { | ||
return useContext(modeContext); | ||
} | ||
|
||
/** | ||
* Example: | ||
* | ||
* ```ts | ||
* const isKeyboard = useIsUserInteractionMode("keyboard"); | ||
* // do stuff if keyboard only | ||
* ``` | ||
* | ||
* @param mode The {@link UserInteractionMode} to check against. | ||
* @return `true` if the current user interaction mode matches the provided | ||
* mode. | ||
*/ | ||
export function useIsUserInteractionMode(mode: UserInteractionMode): boolean { | ||
return useInteractionMode() === mode; | ||
} | ||
|
||
export interface UserInteractionModeListenerProps { | ||
/** | ||
* The `children` are required since this component basically does nothing | ||
* other than providing a `className` to the `document.body` otherwise. | ||
*/ | ||
children: ReactNode; | ||
} | ||
|
||
/** | ||
* This component is used to determine how the user is current interacting with | ||
* your app as well as modifying the `document.body`'s `className` with the | ||
* current mode. This is what allows the `rmd-utils-phone-only`, | ||
* `rmd-utils-keyboard-only`, and `rmd-utils-mouse-only` mixins to work. | ||
* | ||
* @since 2.6.0 Renamed from `InteractionModeListener` | ||
* @throws When this component has been mounted multiple times in your app. | ||
*/ | ||
export function UserInteractionModeListener({ | ||
children, | ||
}: UserInteractionModeListenerProps): ReactElement { | ||
const mode = useInteractionMode(); | ||
if (useContext(parentContext)) { | ||
throw new Error( | ||
"Mounted multiple `UserInteractionModeListener` components." | ||
); | ||
} | ||
|
||
return ( | ||
<UserInteractionModeProvider value={mode}> | ||
<ParentProvider value>{children}</ParentProvider> | ||
</UserInteractionModeProvider> | ||
); | ||
} | ||
|
||
/** | ||
* @deprecated Use the `UserInteractionModeListener` component instead. | ||
* @since 2.6.0 | ||
*/ | ||
export const InteractionModeListener = UserInteractionModeListener; | ||
|
||
/* istanbul ignore next */ | ||
if (process.env.NODE_ENV !== "production") { | ||
try { | ||
const PropTypes = require("prop-types"); | ||
|
||
UserInteractionModeListener.propTypes = { | ||
children: PropTypes.node.isRequired, | ||
}; | ||
} catch (e) {} | ||
} |
Oops, something went wrong.