@blocz/react-responsive
Version:
🔍 <Only /> displays some contents for a specific screen size
1 lines • 11.2 kB
Source Map (JSON)
{"version":3,"file":"react-responsive.modern.mjs","sources":["../src/sanitize.ts","../src/BreakpointsContext.tsx","../src/useMediaQuery.ts","../src/useBreakpoint.ts","../src/mediaQueryBuilder.ts","../src/fromBreakpointToMedia.ts","../src/Only.tsx"],"sourcesContent":["export type Units =\n | \"em\"\n | \"ex\"\n | \"%\"\n | \"px\"\n | \"cm\"\n | \"mm\"\n | \"in\"\n | \"pt\"\n | \"pc\"\n | \"ch\"\n | \"rem\"\n | \"vh\"\n | \"vw\"\n | \"vmin\"\n | \"vmax\";\n\nconst listOfSupportedUnits: Units[] = [\n \"em\",\n \"ex\",\n \"%\",\n \"px\",\n \"cm\",\n \"mm\",\n \"in\",\n \"pt\",\n \"pc\",\n \"ch\",\n \"rem\",\n \"vh\",\n \"vw\",\n \"vmin\",\n \"vmax\",\n];\n\ntype Directions = \"width\" | \"height\";\n\nconst listOfSupportedDirections: Directions[] = [\"width\", \"height\"];\n\nexport type ExposedBreakpoint =\n | [number, number]\n | [number, number, Units]\n | [number, number, { unit?: Units; direction?: Directions }];\n\nexport interface ExposedBreakpoints {\n [key: string]: ExposedBreakpoint;\n}\n\nexport type Breakpoint = [number, number, Units, Directions];\n\nexport interface Breakpoints {\n [breakpoint: string]: Breakpoint;\n}\n\nexport const sanitize = (inBreakpoints: ExposedBreakpoints): Breakpoints => {\n return Object.keys(inBreakpoints).reduce<Breakpoints>((breakpoints, breakpointName) => {\n const breakpoint = inBreakpoints[breakpointName];\n\n if (!Array.isArray(breakpoint) || breakpoint.length <= 1) {\n return breakpoints;\n }\n\n const [supposedMin, supposedMax, options, ...rest] = breakpoint;\n if (rest.length > 0) {\n const error = new Error(`The following fields \"${rest}\" have been ignored`);\n console.error(error);\n }\n\n if (typeof supposedMin !== \"number\" || typeof supposedMax !== \"number\") {\n return breakpoints;\n }\n\n let supposedUnit: Units | undefined;\n let supposedDirection: Directions | undefined;\n if (typeof options === \"string\") {\n supposedUnit = options;\n } else if (typeof options === \"object\") {\n supposedDirection = options.direction;\n supposedUnit = options.unit;\n }\n\n const min = Math.min(supposedMin, supposedMax);\n const max = Math.max(supposedMin, supposedMax);\n const unit = supposedUnit && listOfSupportedUnits.includes(supposedUnit) ? supposedUnit : \"px\";\n const direction =\n supposedDirection && listOfSupportedDirections.includes(supposedDirection) ? supposedDirection : \"width\";\n\n breakpoints[breakpointName] = [min, max, unit, direction];\n breakpoints[`${breakpointName}Up`] = [min, Infinity, unit, direction];\n breakpoints[`${breakpointName}Down`] = [0, max, unit, direction];\n\n return breakpoints;\n }, {});\n};\n","import * as React from \"react\";\n\nimport { sanitize, ExposedBreakpoints, Breakpoints } from \"./sanitize\";\n\nconst defaultBreakpoints: ExposedBreakpoints = {\n xs: [0, 575, \"px\"], // Extra small devices (portrait phones)\n sm: [576, 767, \"px\"], // Small devices (landscape phones)\n md: [768, 991, \"px\"], // Medium devices (tablets)\n lg: [992, 1199, \"px\"], // Large devices (desktops)\n xl: [1200, Infinity, \"px\"], // Extra large devices (large desktops)\n};\n\nexport const BreakpointsContext: React.Context<Breakpoints> = React.createContext<Breakpoints>(\n sanitize(defaultBreakpoints),\n);\n\ninterface BreakpointsProviderProps {\n breakpoints?: ExposedBreakpoints;\n additionalBreakpoints?: ExposedBreakpoints;\n}\n\nexport const BreakpointsProvider: React.FunctionComponent<React.PropsWithChildren<BreakpointsProviderProps>> = ({\n breakpoints = defaultBreakpoints,\n additionalBreakpoints,\n children,\n}) => {\n return (\n <BreakpointsContext.Provider\n value={sanitize({\n ...breakpoints,\n ...additionalBreakpoints,\n })}\n >\n {children}\n </BreakpointsContext.Provider>\n );\n};\n\nBreakpointsProvider.displayName = \"BreakpointsProvider\";\n","import * as React from \"react\";\n\nexport const useMediaQuery = (mediaQuery: string): boolean => {\n const mediaQueryList = React.useMemo(() => matchMedia(mediaQuery), [mediaQuery]);\n const [isShown, setIsShown] = React.useState<boolean>(mediaQueryList.matches);\n\n React.useLayoutEffect(() => {\n setIsShown(mediaQueryList.matches);\n const listener = (event: MediaQueryListEvent) => {\n // Those are important updates, so we don't want to use transitions on them\n setIsShown(event.matches);\n };\n\n // cannot use addEventListener for IE 11 and safari 13-\n mediaQueryList.addListener(listener);\n return () => {\n mediaQueryList.removeListener(listener);\n };\n }, [mediaQueryList]);\n\n return isShown;\n};\n","import * as React from \"react\";\n\nimport { BreakpointsContext } from \"./BreakpointsContext\";\n\nimport { mediaQueryBuilder } from \"./mediaQueryBuilder\";\n\nimport { useMediaQuery } from \"./useMediaQuery\";\n\nexport const useBreakpoint = (on?: string): boolean => {\n const breakpoints = React.useContext(BreakpointsContext);\n const toMediaQuery = React.useMemo(() => mediaQueryBuilder(breakpoints), [breakpoints]);\n\n const mediaQuery = React.useMemo(() => toMediaQuery(on), [toMediaQuery, on]);\n\n return useMediaQuery(mediaQuery || \"-\");\n};\n","import { Breakpoints } from \"./sanitize\";\nimport { fromBreakpointToMedia } from \"./fromBreakpointToMedia\";\n\nexport const mediaQueryBuilder =\n (breakpoints: Breakpoints) =>\n (on = \"\"): string => {\n if (!on) {\n return \"\";\n }\n const rawBreakpointNames = on.split(\" \");\n const filteredBreakpoints = rawBreakpointNames.map((breakpointName) => breakpoints[breakpointName]).filter(Boolean);\n const mediaQuery = filteredBreakpoints\n .map((breakpoint) => fromBreakpointToMedia(breakpoint))\n .filter(Boolean)\n .join(\",\");\n if (!mediaQuery) {\n const isUniqBreakpoint = rawBreakpointNames.length === 1;\n console.error(\n `\"${rawBreakpointNames.join('\", \"')}\" ${isUniqBreakpoint ? \"is\" : \"are\"}n't ${\n isUniqBreakpoint ? \"a \" : \"\"\n }valid breakpoint${isUniqBreakpoint ? \"\" : \"s\"}`,\n );\n }\n return mediaQuery;\n };\n","import { Breakpoint } from \"./sanitize\";\n\nexport const fromBreakpointToMedia = (breakpoint: Breakpoint): string => {\n const mediaList: string[] = [];\n const [minValue, maxValue, unit, direction] = breakpoint;\n let str;\n\n // Min value\n if (minValue !== 0) {\n str = `${minValue}${unit}`;\n mediaList.push(`(min-${direction}:${str})`);\n }\n\n // Max value\n if (maxValue !== Infinity) {\n str = `${maxValue}${unit}`;\n mediaList.push(`(max-${direction}:${str})`);\n }\n\n return \" \" + mediaList.join(\" and \");\n};\n","import * as React from \"react\";\n\nimport { useBreakpoint } from \"./useBreakpoint\";\nimport { useMediaQuery } from \"./useMediaQuery\";\n\nexport type OnlyProps<OtherProps = Record<string, never>> = OtherProps & {\n matchMedia?: string;\n on?: string;\n as?: string | React.ComponentType<OtherProps>;\n};\n\nexport function Only<OtherProps = Record<string, never>>({\n matchMedia,\n on,\n as,\n children,\n ...props\n}: React.PropsWithChildren<OnlyProps<OtherProps>>): React.ReactElement | null {\n const matchOn = useBreakpoint(on);\n const matchQuery = useMediaQuery(matchMedia || \"-\");\n const isShown = matchOn || matchQuery;\n\n if (!isShown) {\n return null;\n }\n\n return React.createElement(\n // @ts-expect-error – this is a complex type\n as || React.Fragment,\n as ? (props as OtherProps) : undefined,\n children,\n );\n}\n"],"names":["listOfSupportedUnits","listOfSupportedDirections","sanitize","inBreakpoints","Object","keys","reduce","breakpoints","breakpointName","breakpoint","Array","isArray","length","supposedMin","supposedMax","options","rest","error","Error","console","supposedUnit","supposedDirection","direction","unit","min","Math","max","includes","Infinity","defaultBreakpoints","xs","sm","md","lg","xl","BreakpointsContext","React","createContext","BreakpointsProvider","additionalBreakpoints","children","Provider","value","_extends","displayName","useMediaQuery","mediaQuery","mediaQueryList","useMemo","matchMedia","isShown","setIsShown","useState","matches","useLayoutEffect","listener","event","addListener","removeListener","useBreakpoint","on","useContext","toMediaQuery","rawBreakpointNames","split","map","filter","Boolean","mediaList","minValue","maxValue","str","push","join","fromBreakpointToMedia","isUniqBreakpoint","mediaQueryBuilder","Only","_ref","as","props","_objectWithoutPropertiesLoose","_excluded","matchOn","matchQuery","createElement","Fragment","undefined"],"mappings":"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"}