import { ReactNode, useMemo } from 'react'; import { objectOf, oneOf, number, string } from 'prop-types'; import { BreakpointsContext } from './BreakpointsContext'; import { useMatchMediaBreakpoints } from './useMatchMediaBreakpoints'; import { validateBreakpoints } from './helpers/validateBreakpoints'; import { BreakpointKey, Breakpoints, BreakpointsProps, BreakpointUnit, } from './breakpoints'; /** * Props for ReactBreakpoints */ export interface MatchMediaBreakpointsProps< K extends BreakpointKey = BreakpointKey, > { /** * Your breakpoints object. */ breakpoints: Breakpoints; /** * The type of unit that your breakpoints should use - px or em. * @default "px" */ breakpointUnit?: BreakpointUnit; /** * Default breakpoint that is used * if no breakpoint matches * * Defaults to smallest breakpoint if not set */ defaultBreakpoint?: K; /** * Children props */ children?: ReactNode; } /** * Alias for MatchMediaBreakpointsProps default export */ export type ReactBreakpointsProps = MatchMediaBreakpointsProps; /** * Provides the breakpoints for the Consumer components * * Detects current breakpoint using media queries * - [matchMedia]( https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) * - [MediaQueryList](https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList) * * Uses CSS media queries [level 3](https://www.w3.org/TR/css3-mediaqueries/) * - min-width * - max-width */ export function MatchMediaBreakpoints( props: MatchMediaBreakpointsProps, ) { validateBreakpoints(props.breakpoints); const { children, breakpoints, breakpointUnit = 'px', defaultBreakpoint, } = props; const currentBreakpoint = useMatchMediaBreakpoints({ breakpoints, breakpointUnit, defaultBreakpoint, }); const contextProps = useMemo(() => { return { breakpoints, currentBreakpoint, }; }, [breakpoints, currentBreakpoint]); return ( {children} ); } MatchMediaBreakpoints.propTypes = { breakpoints: objectOf(number).isRequired, breakpointUnit: oneOf(['px', 'em']), defaultBreakpoint: string, }; export default MatchMediaBreakpoints;