From 59ae517a31ec241321ba926b150b52612739d469 Mon Sep 17 00:00:00 2001 From: Douglas Fabris Date: Thu, 3 Dec 2020 16:12:33 -0300 Subject: [PATCH] feat: usePrefersReducedData hook (#340) --- packages/fuselage-hooks/README.md | 7 +++ .../fuselage-hooks/docs/fuselage-hooks.md | 1 + .../fuselage-hooks.useprefersreduceddata.md | 13 ++++ packages/fuselage-hooks/src/index.ts | 1 + .../src/usePrefersReducedData.server.spec.ts | 34 +++++++++++ .../src/usePrefersReducedData.spec.ts | 59 +++++++++++++++++++ .../src/usePrefersReducedData.ts | 11 ++++ 7 files changed, 126 insertions(+) create mode 100644 packages/fuselage-hooks/docs/fuselage-hooks.useprefersreduceddata.md create mode 100644 packages/fuselage-hooks/src/usePrefersReducedData.server.spec.ts create mode 100644 packages/fuselage-hooks/src/usePrefersReducedData.spec.ts create mode 100644 packages/fuselage-hooks/src/usePrefersReducedData.ts diff --git a/packages/fuselage-hooks/README.md b/packages/fuselage-hooks/README.md index d26564be..80ead6ce 100644 --- a/packages/fuselage-hooks/README.md +++ b/packages/fuselage-hooks/README.md @@ -66,6 +66,7 @@ yarn add @rocket.chat/fuselage-hooks - [Parameters](#parameters-10) - [usePosition](#useposition) - [Parameters](#parameters-11) +- [usePrefersReducedData](#useprefersreduceddata) - [usePrefersReducedMotion](#useprefersreducedmotion) - [useResizeObserver](#useresizeobserver) - [Parameters](#parameters-12) @@ -227,6 +228,12 @@ Hook to deal and position an element using an anchor Returns **PositionResult** The style containing top and left position +### usePrefersReducedData + +Hook to get the prefers-reduce-data value. + +Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** `true` if the prefers-reduce-data is set reduce in the media queries that matches + ### usePrefersReducedMotion Hook to get the prefers-reduce-motion value. diff --git a/packages/fuselage-hooks/docs/fuselage-hooks.md b/packages/fuselage-hooks/docs/fuselage-hooks.md index fe510e8b..12ba6984 100644 --- a/packages/fuselage-hooks/docs/fuselage-hooks.md +++ b/packages/fuselage-hooks/docs/fuselage-hooks.md @@ -34,6 +34,7 @@ | [useMergedRefs](./fuselage-hooks.usemergedrefs.md) | Hook to merge refs and callbacks refs into a single callback ref. Useful when your component need a internal ref while receiving a forwared ref. | | [useMutableCallback](./fuselage-hooks.usemutablecallback.md) | Hook to create a stable callback from a mutable one. | | [usePosition](./fuselage-hooks.useposition.md) | Hook to deal and position an element using an anchor | +| [usePrefersReducedData](./fuselage-hooks.useprefersreduceddata.md) | Hook to get the prefers-reduce-data value. | | [usePrefersReducedMotion](./fuselage-hooks.useprefersreducedmotion.md) | Hook to get the prefers-reduce-motion value. | | [useResizeObserver](./fuselage-hooks.useresizeobserver.md) | Hook to track dimension changes in a DOM element using the ResizeObserver API. | | [useSafely](./fuselage-hooks.usesafely.md) | Hook that wraps pairs of state and dispatcher to provide a new dispatcher which can be safe and asynchronically called even after the component unmounted. | diff --git a/packages/fuselage-hooks/docs/fuselage-hooks.useprefersreduceddata.md b/packages/fuselage-hooks/docs/fuselage-hooks.useprefersreduceddata.md new file mode 100644 index 00000000..b5f47af1 --- /dev/null +++ b/packages/fuselage-hooks/docs/fuselage-hooks.useprefersreduceddata.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [@rocket.chat/fuselage-hooks](./fuselage-hooks.md) > [usePrefersReducedData](./fuselage-hooks.useprefersreduceddata.md) + +## usePrefersReducedData variable + +Hook to get the prefers-reduce-data value. + +Signature: + +```typescript +usePrefersReducedData: () => boolean +``` diff --git a/packages/fuselage-hooks/src/index.ts b/packages/fuselage-hooks/src/index.ts index da8539df..41d4bb8a 100644 --- a/packages/fuselage-hooks/src/index.ts +++ b/packages/fuselage-hooks/src/index.ts @@ -12,6 +12,7 @@ export * from './useMediaQuery'; export * from './useMergedRefs'; export * from './useMutableCallback'; export * from './usePosition'; +export * from './usePrefersReducedData'; export * from './usePrefersReducedMotion'; export * from './useResizeObserver'; export * from './useSafely'; diff --git a/packages/fuselage-hooks/src/usePrefersReducedData.server.spec.ts b/packages/fuselage-hooks/src/usePrefersReducedData.server.spec.ts new file mode 100644 index 00000000..2747801f --- /dev/null +++ b/packages/fuselage-hooks/src/usePrefersReducedData.server.spec.ts @@ -0,0 +1,34 @@ +/** + * @jest-environment node + */ + +import { FunctionComponent, createElement, StrictMode } from 'react'; +import { renderToString } from 'react-dom/server'; + +import { usePrefersReducedData } from '.'; + +describe('usePrefersReducedData hook on server', () => { + it('should return false without matchMedia mocked', () => { + let matches: boolean; + const TestComponent: FunctionComponent = () => { + matches = usePrefersReducedData(); + return null; + }; + + renderToString(createElement(StrictMode, {}, createElement(TestComponent))); + + expect(matches).toBe(false); + }); + + it('should return false with matchMedia mocked', () => { + let matches: boolean; + const TestComponent: FunctionComponent = () => { + matches = usePrefersReducedData(); + return null; + }; + + renderToString(createElement(StrictMode, {}, createElement(TestComponent))); + + expect(matches).toBe(false); + }); +}); diff --git a/packages/fuselage-hooks/src/usePrefersReducedData.spec.ts b/packages/fuselage-hooks/src/usePrefersReducedData.spec.ts new file mode 100644 index 00000000..76c73049 --- /dev/null +++ b/packages/fuselage-hooks/src/usePrefersReducedData.spec.ts @@ -0,0 +1,59 @@ +import { createElement, FunctionComponent, StrictMode } from 'react'; +import { render } from 'react-dom'; +import { act } from 'react-dom/test-utils'; + +import { usePrefersReducedData } from '.'; +import matchMediaMock from './__mocks__/matchMedia'; + +describe('usePrefersReducedData hook', () => { + let container: HTMLDivElement; + + beforeEach(() => { + container = document.createElement('div'); + document.body.appendChild(container); + }); + + afterEach(() => { + container.remove(); + container = null; + }); + + it('should return false on the initial call', () => { + let matches: boolean; + + const TestComponent: FunctionComponent = () => { + matches = usePrefersReducedData(); + return null; + }; + + act(() => { + render( + createElement(StrictMode, {}, createElement(TestComponent)), + container + ); + }); + + expect(matches).toBe(false); + }); + + it('should returns true with matchMedia mocked', () => { + window.matchMedia = jest.fn((media) => + matchMediaMock(media, '(prefers-reduced-data: reduce)') + ); + + let matches: boolean; + const TestComponent: FunctionComponent = () => { + matches = usePrefersReducedData(); + return null; + }; + + act(() => { + render( + createElement(StrictMode, {}, createElement(TestComponent)), + document.createElement('div') + ); + }); + + expect(matches).toBe(true); + }); +}); diff --git a/packages/fuselage-hooks/src/usePrefersReducedData.ts b/packages/fuselage-hooks/src/usePrefersReducedData.ts new file mode 100644 index 00000000..2c7d930b --- /dev/null +++ b/packages/fuselage-hooks/src/usePrefersReducedData.ts @@ -0,0 +1,11 @@ +import { useMediaQuery } from '.'; + +/** + * Hook to get the prefers-reduce-data value. + * + * @returns `true` if the prefers-reduce-data is set reduce in the media queries that matches + * @public + */ + +export const usePrefersReducedData = (): boolean => + useMediaQuery('(prefers-reduced-data: reduce)'); -- GitLab