4.0.0-rc.2 • Published 5 months ago

@opensea/react-media v4.0.0-rc.2

Weekly downloads
-
License
MIT
Repository
-
Last release
5 months ago

react-media

Coverage Status styled with prettier

@opensea/react-media is a Javascript library to deal with media queries in isomorphic React applications.

Its heavily inspired by https://github.com/artsy/fresnel but is compatible with React 18.

Installation

npm

npm i @opensea/react-media

yarn

yarn add @opensea/react-media

Usage

// media/setup.ts

import { createMedia } from "@opensea/react-media"

const { createMediaStyle, prepareComponents } = createMedia({
  sm: 640,
  md: 768,
  lg: 1024,
  xl: 1280,
  "2xl": 1536,
  container: 1600,
  "3xl": 1910,
})

export const mediaStyle = createMediaStyle()
// media/components.ts

import { prepareComponents } from "./setup"

const { Media, SizeProvider, useSizeContextSelector } = prepareComponents()

export { Media, SizeProvider, useSizeContextSelector }
// ComponentX.react.tsx
import { Media } from "./media/components"

export function ComponentX() {
  return <Media greaterThan="md">Render if greater than md</Media>
}

NextJS ~ Pages router

// __app.tsx

import React from "react"
import { SizeProvider } from "./media/components"
import type { AppProps } from "next/app"

export default function App({ Component, pageProps }: AppProps) {
  return (
    <SizeProvider>
      <Component {...pageProps} />
    </SizeProvider>
  )
}
// _document.tsx

import { Html, Head, Main, NextScript } from "next/document"
import { mediaStyles } from "./media/setup"

export default function Document() {
  return (
    <Html>
      <Head>
        <style
          dangerouslySetInnerHTML={{ __html: mediaStyles }}
          type="text/css"
        />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

NextJS ~ App router / RSC

// client-providers.tsx

"use client"

import { SizeProvider } from "./media/components"

export function ClientProviders(props: { children: React.ReactNode }) {
  return <SizeProvider>{props.children}</SizeProvider>
}
// layout.tsx
import { ClientProviders } from "./client-providers"
import { mediaStyles } from "./media/setup"

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <head>
        <style
          dangerouslySetInnerHTML={{ __html: mediaStyles }}
          type="text/css"
        />
      </head>
      <body>
        <ClientProviders>{children}</ClientProviders>
      </body>
    </html>
  )
}

Using breakpoints in javascript code

Note: useSizeContextSelector hook relies on the window width/height which is not accessible on the server. As such its not suitable for rendering content based on it as it will lead to server-client miss-matches.

// ComponentX.react.tsx
import { breakpoints } from "./media/setup"
import { useSizeContextSelector } from "./media/components"

const useIsLessThanLg = () => {
  return useSizeContextSelector(value => value.width < breakpoints.lg)
}

export function ComponentX() {
  const isLessThanLg = useIsLessThanLg()

  return (
    <button
      onClick={() => {
        if (isLessThanLg) {
          console.log("less than lg")
        } else {
          console.log("not less than lg")
        }
      }}
    >
      Click me
    </button>
  )
}
4.0.0-rc.1

5 months ago

4.0.0-rc.0

5 months ago

4.0.0-rc.2

5 months ago

3.0.0

5 months ago

1.0.9-rc5

7 months ago

1.0.9-rc4

7 months ago

1.0.9-rc7

7 months ago

1.0.9-rc6

7 months ago

1.0.9-rc1

7 months ago

1.0.9-rc0

7 months ago

1.0.9-rc3

7 months ago

2.0.0

7 months ago

1.0.9-rc2

7 months ago

1.0.9

1 year ago

1.0.8

1 year ago

1.0.6

1 year ago

1.0.5

1 year ago

1.0.4

1 year ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago