Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.

Commit

Permalink
[react-hooks] initialize Media hooks with correct matches value (#2809)
Browse files Browse the repository at this point in the history
  • Loading branch information
melnikov-s authored Jul 15, 2024
1 parent 9613191 commit 5546b1d
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-days-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/react-hooks': major
---

Media hooks initialized with correct matches value
8 changes: 6 additions & 2 deletions packages/react-hooks/src/hooks/media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ import {useState, useEffect, useLayoutEffect} from 'react';
type EffectHook = typeof useEffect | typeof useLayoutEffect;

function createUseMediaFactory(useEffectHook: EffectHook) {
return (query: string) => {
const [match, setMatch] = useState(false);
return (query: string, {initialValue}: {initialValue?: boolean}) => {
const [match, setMatch] = useState(() =>
initialValue === undefined
? window.matchMedia(query).matches
: Boolean(initialValue),
);

useEffectHook(() => {
if (!window || !window.matchMedia) {
Expand Down
44 changes: 42 additions & 2 deletions packages/react-hooks/src/hooks/tests/media.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import {mount} from '@shopify/react-testing';
import {useMedia, useMediaLayout} from '../media';

describe('useMedia and useMediaLayout', () => {
let matches: boolean[] = [];

beforeEach(() => {
matchMedia.mock();
matches = [];
});

afterEach(() => {
Expand All @@ -17,8 +20,15 @@ describe('useMedia and useMediaLayout', () => {
['useMedia', useMedia],
['useMediaLayout', useMediaLayout],
])('%s', (_, useEffectHook) => {
function MockComponent({mediaQuery}: {mediaQuery: string}) {
const matchedQuery = useEffectHook(mediaQuery);
function MockComponent({
mediaQuery,
initialValue,
}: {
mediaQuery: string;
initialValue?: boolean;
}) {
const matchedQuery = useEffectHook(mediaQuery, {initialValue});
matches.push(matchedQuery);
const message = matchedQuery ? 'matched' : 'did not match';
return <div>{message}</div>;
}
Expand Down Expand Up @@ -66,6 +76,35 @@ describe('useMedia and useMediaLayout', () => {
);

const mockComponent = mount(<MockComponent mediaQuery="print" />);
expect(matches).toStrictEqual([true]);
expect(mockComponent.text()).toContain('matched');
});

it('initial render with initialValue true', () => {
matchMedia.setMedia(() =>
mediaQueryList({
matches: true,
}),
);

const mockComponent = mount(
<MockComponent mediaQuery="print" initialValue />,
);
expect(matches).toStrictEqual([true]);
expect(mockComponent.text()).toContain('matched');
});

it('initial render with initialValue false', () => {
matchMedia.setMedia(() =>
mediaQueryList({
matches: true,
}),
);

const mockComponent = mount(
<MockComponent mediaQuery="print" initialValue={false} />,
);
expect(matches).toStrictEqual([false, true]);
expect(mockComponent.text()).toContain('matched');
});

Expand All @@ -77,6 +116,7 @@ describe('useMedia and useMediaLayout', () => {
);

const mockComponent = mount(<MockComponent mediaQuery="print" />);
expect(matches).toStrictEqual([false]);
expect(mockComponent.text()).toContain('did not match');
});

Expand Down

0 comments on commit 5546b1d

Please sign in to comment.