diff --git a/packages/react-responsive/src/BreakpointsContext.tsx b/packages/react-responsive/src/BreakpointsContext.tsx index 5ba8e1d..c2d4635 100644 --- a/packages/react-responsive/src/BreakpointsContext.tsx +++ b/packages/react-responsive/src/BreakpointsContext.tsx @@ -19,11 +19,11 @@ interface BreakpointsProviderProps { additionalBreakpoints?: ExposedBreakpoints; } -export const BreakpointsProvider: React.FunctionComponent> = ({ +export function BreakpointsProvider({ breakpoints = defaultBreakpoints, additionalBreakpoints, children, -}) => { +}: React.PropsWithChildren): React.ReactElement { return ( ); -}; - -BreakpointsProvider.displayName = "BreakpointsProvider"; +} diff --git a/packages/react-responsive/src/fromBreakpointToMedia.ts b/packages/react-responsive/src/fromBreakpointToMedia.ts index 79949fd..19e8b89 100644 --- a/packages/react-responsive/src/fromBreakpointToMedia.ts +++ b/packages/react-responsive/src/fromBreakpointToMedia.ts @@ -1,6 +1,6 @@ import { Breakpoint } from "./sanitize"; -export const fromBreakpointToMedia = (breakpoint: Breakpoint): string => { +export function fromBreakpointToMedia(breakpoint: Breakpoint): string { const mediaList: string[] = []; const [minValue, maxValue, unit, direction] = breakpoint; let str; @@ -18,4 +18,4 @@ export const fromBreakpointToMedia = (breakpoint: Breakpoint): string => { } return " " + mediaList.join(" and "); -}; +} diff --git a/packages/react-responsive/src/mediaQueryBuilder.ts b/packages/react-responsive/src/mediaQueryBuilder.ts index 362ef34..7f44fb7 100644 --- a/packages/react-responsive/src/mediaQueryBuilder.ts +++ b/packages/react-responsive/src/mediaQueryBuilder.ts @@ -1,9 +1,8 @@ import { Breakpoints } from "./sanitize"; import { fromBreakpointToMedia } from "./fromBreakpointToMedia"; -export const mediaQueryBuilder = - (breakpoints: Breakpoints) => - (on = ""): string => { +export function mediaQueryBuilder(breakpoints: Breakpoints) { + return function toMediaQuery(on = ""): string { if (!on) { return ""; } @@ -23,3 +22,4 @@ export const mediaQueryBuilder = } return mediaQuery; }; +} diff --git a/packages/react-responsive/src/sanitize.ts b/packages/react-responsive/src/sanitize.ts index 1cd3b11..a6d8b99 100644 --- a/packages/react-responsive/src/sanitize.ts +++ b/packages/react-responsive/src/sanitize.ts @@ -52,7 +52,7 @@ export interface Breakpoints { [breakpoint: string]: Breakpoint; } -export const sanitize = (inBreakpoints: ExposedBreakpoints): Breakpoints => { +export function sanitize(inBreakpoints: ExposedBreakpoints): Breakpoints { return Object.keys(inBreakpoints).reduce((breakpoints, breakpointName) => { const breakpoint = inBreakpoints[breakpointName]; @@ -91,4 +91,4 @@ export const sanitize = (inBreakpoints: ExposedBreakpoints): Breakpoints => { return breakpoints; }, {}); -}; +} diff --git a/packages/react-responsive/src/useBreakpoint.ts b/packages/react-responsive/src/useBreakpoint.ts index 06c8db0..5e001ed 100644 --- a/packages/react-responsive/src/useBreakpoint.ts +++ b/packages/react-responsive/src/useBreakpoint.ts @@ -6,11 +6,11 @@ import { mediaQueryBuilder } from "./mediaQueryBuilder"; import { useMediaQuery } from "./useMediaQuery"; -export const useBreakpoint = (on?: string): boolean => { +export function useBreakpoint(on?: string): boolean { const breakpoints = React.useContext(BreakpointsContext); const toMediaQuery = React.useMemo(() => mediaQueryBuilder(breakpoints), [breakpoints]); const mediaQuery = React.useMemo(() => toMediaQuery(on), [toMediaQuery, on]); return useMediaQuery(mediaQuery || "-"); -}; +} diff --git a/packages/react-responsive/src/useMediaQuery.ts b/packages/react-responsive/src/useMediaQuery.ts index b468191..f9cf854 100644 --- a/packages/react-responsive/src/useMediaQuery.ts +++ b/packages/react-responsive/src/useMediaQuery.ts @@ -1,22 +1,19 @@ import * as React from "react"; -export const useMediaQuery = (mediaQuery: string): boolean => { +export function useMediaQuery(mediaQuery: string): boolean { const mediaQueryList = React.useMemo(() => matchMedia(mediaQuery), [mediaQuery]); - const [isShown, setIsShown] = React.useState(mediaQueryList.matches); - React.useLayoutEffect(() => { - setIsShown(mediaQueryList.matches); - const listener = (event: MediaQueryListEvent) => { - // Those are important updates, so we don't want to use transitions on them - setIsShown(event.matches); - }; - - // cannot use addEventListener for IE 11 and safari 13- - mediaQueryList.addListener(listener); - return () => { - mediaQueryList.removeListener(listener); - }; - }, [mediaQueryList]); - - return isShown; -}; + // Those are important updates, so we don't want to use transitions on them + return React.useSyncExternalStore( + React.useCallback( + (callback) => { + // cannot use addEventListener for IE 11 and safari 13- + mediaQueryList.addListener(callback); + return () => mediaQueryList.removeListener(callback); + }, + [mediaQueryList], + ), + () => mediaQueryList.matches, + // Don't add `() => false`, so that node implementations can define their own behavior for server-side rendering via `mock-match-media` + ); +}