CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-responsive

Media queries in React for responsive design with hook and component APIs

Pending
Overview
Eval results
Files

component-api.mddocs/

Component API

The Component API provides declarative conditional rendering using React components. This is ideal for showing/hiding UI elements based on media queries with clean JSX syntax.

Capabilities

MediaQuery Component

React functional component for conditional rendering based on media queries. Supports both direct children and render prop patterns.

/**
 * React component for conditional rendering based on media queries
 */
const MediaQuery: FC<MediaQueryProps>;

interface MediaQueryProps extends MediaQueryAllQueryable {
  /** React component to render when media query matches */
  component?: ReactNode;
  /** Content to render - can be ReactNode or render function */
  children?: ReactNode | ((matches: boolean) => ReactNode);
  /** Raw CSS media query string */
  query?: string;
  /** CSS styles to apply to the wrapper element */
  style?: CSSProperties;
  /** CSS class name to apply to the wrapper element */
  className?: string;
  /** Device property overrides for SSR/testing */
  device?: MediaQueryMatchers;
  /** Alias for device prop (deprecated) */
  values?: Partial<MediaQueryMatchers>;
  /** Callback fired before media query match state changes */
  onBeforeChange?: (matches: boolean) => void;
  /** Callback fired when media query match state changes */
  onChange?: (matches: boolean) => void;
}

Props:

  • Media Query Properties: All properties from MediaQueryAllQueryable (width, height, orientation, etc.)
  • component?: React component to render when media query matches
  • children?: Content to render, either as ReactNode or render function (matches: boolean) => ReactNode
  • query?: Raw CSS media query string (alternative to property-based queries)
  • style?: CSS styles applied to wrapper element
  • className?: CSS class name applied to wrapper element
  • device?: Device property overrides for server-side rendering or testing
  • values?: Deprecated alias for device prop
  • onBeforeChange?: Callback fired before match state changes
  • onChange?: Callback fired when match state changes

Usage Examples:

import React from "react";
import MediaQuery from "react-responsive";

// Basic conditional rendering
const BasicExample = () => (
  <div>
    <MediaQuery minWidth={1224}>
      <p>This content shows on desktop screens (≥1224px)</p>
    </MediaQuery>

    <MediaQuery maxWidth={768}>
      <p>This content shows on mobile screens (≤768px)</p>
    </MediaQuery>
  </div>
);

// Using render prop pattern
const RenderPropExample = () => (
  <div>
    <MediaQuery minWidth={768}>
      {(matches) =>
        matches ? (
          <p>Desktop/Tablet view</p>
        ) : (
          <p>Mobile view</p>
        )
      }
    </MediaQuery>

    <MediaQuery orientation="landscape">
      {(isLandscape) => (
        <div className={isLandscape ? "landscape" : "portrait"}>
          <p>Orientation: {isLandscape ? "Landscape" : "Portrait"}</p>
        </div>
      )}
    </MediaQuery>
  </div>
);

// Using CSS query strings
const QueryStringExample = () => (
  <div>
    <MediaQuery query="(min-resolution: 2dppx)">
      <img src="high-res-image.png" alt="High DPI image" />
    </MediaQuery>

    <MediaQuery query="(max-width: 767px) and (orientation: portrait)">
      <p>Mobile portrait mode</p>
    </MediaQuery>
  </div>
);

// Nested media queries
const NestedExample = () => (
  <div>
    <MediaQuery minWidth={1224}>
      <p>Desktop content</p>
      <MediaQuery minWidth={1824}>
        <p>Large desktop additional content</p>
      </MediaQuery>
    </MediaQuery>
  </div>
);

// With styling and classes
const StyledExample = () => (
  <div>
    <MediaQuery
      minWidth={768}
      style={{ backgroundColor: "lightblue", padding: "1rem" }}
      className="desktop-container"
    >
      <p>Styled desktop content</p>
    </MediaQuery>
  </div>
);

// With device overrides for SSR
const SSRExample = () => (
  <MediaQuery minWidth={1224} device={{ width: 1400 }}>
    <p>This will render on server with forced desktop width</p>
  </MediaQuery>
);

Advanced Component Patterns

Responsive Layout Components:

import MediaQuery from "react-responsive";

// Create reusable responsive layout components
const Desktop = ({ children }: { children: React.ReactNode }) => (
  <MediaQuery minWidth={992}>
    {children}
  </MediaQuery>
);

const Tablet = ({ children }: { children: React.ReactNode }) => (
  <MediaQuery minWidth={768} maxWidth={991}>
    {children}
  </MediaQuery>
);

const Mobile = ({ children }: { children: React.ReactNode }) => (
  <MediaQuery maxWidth={767}>
    {children}
  </MediaQuery>
);

// Usage
const ResponsiveLayout = () => (
  <div>
    <Desktop>
      <div className="desktop-layout">Desktop Layout</div>
    </Desktop>
    <Tablet>
      <div className="tablet-layout">Tablet Layout</div>
    </Tablet>
    <Mobile>
      <div className="mobile-layout">Mobile Layout</div>
    </Mobile>
  </div>
);

Conditional Component Rendering:

const ConditionalComponents = () => (
  <div>
    {/* Show different navigation components based on screen size */}
    <MediaQuery minWidth={768}>
      <DesktopNavigation />
    </MediaQuery>

    <MediaQuery maxWidth={767}>
      <MobileNavigation />
    </MediaQuery>

    {/* Show different image sizes based on resolution */}
    <MediaQuery minResolution="2dppx">
      <img src="image@2x.jpg" alt="High DPI" />
    </MediaQuery>

    <MediaQuery maxResolution="1dppx">
      <img src="image.jpg" alt="Standard DPI" />
    </MediaQuery>
  </div>
);

Interactive Media Query Components:

const InteractiveExample = () => {
  const [showDetails, setShowDetails] = useState(false);

  return (
    <div>
      <MediaQuery minWidth={768}>
        {(isDesktop) => (
          <div>
            <h2>Product Information</h2>
            {isDesktop && <button onClick={() => setShowDetails(!showDetails)}>
              {showDetails ? "Hide" : "Show"} Details
            </button>}
            {(showDetails || !isDesktop) && (
              <div className="product-details">
                <p>Detailed product information...</p>
              </div>
            )}
          </div>
        )}
      </MediaQuery>
    </div>
  );
};

Event Handling

Change Detection:

const ChangeDetectionExample = () => {
  const [matchHistory, setMatchHistory] = useState<string[]>([]);

  const handleMediaQueryChange = (matches: boolean) => {
    const timestamp = new Date().toLocaleTimeString();
    setMatchHistory(prev => [
      ...prev,
      `${timestamp}: Desktop ${matches ? "matched" : "unmatched"}`
    ]);
  };

  return (
    <div>
      <MediaQuery 
        minWidth={1024}
        onChange={handleMediaQueryChange}
        onBeforeChange={(matches) => {
          console.log("About to change to:", matches);
        }}
      >
        <p>Desktop content with change tracking</p>
      </MediaQuery>

      <div>
        <h3>Match History:</h3>
        {matchHistory.map((entry, index) => (
          <p key={index}>{entry}</p>
        ))}
      </div>
    </div>
  );
};

Type Definitions

import { ReactNode, CSSProperties, FC } from "react";

interface MediaQueryProps extends MediaQueryAllQueryable {
  component?: ReactNode;
  children?: ReactNode | ((matches: boolean) => ReactNode);
  query?: string;
  style?: CSSProperties;
  className?: string;
  device?: MediaQueryMatchers;
  values?: Partial<MediaQueryMatchers>;
  onBeforeChange?: (matches: boolean) => void;
  onChange?: (matches: boolean) => void;
}

const MediaQuery: FC<MediaQueryProps>;

Install with Tessl CLI

npx tessl i tessl/npm-react-responsive

docs

component-api.md

context-utilities.md

hook-api.md

index.md

tile.json