Skip to content

Breakpoints

Simple use

To use breakpoints in your application, you need to wrap it in a <Breakpoints /> component. And then you can get the value of the media query in any part of your application through the context.

TIP

Resize the window to see the changes.

tsx
import React from 'react';
import Breakpoints from 'intergalactic/breakpoints';
import Button from 'intergalactic/button';

const buttonSizes = ['m', 'l'] as const;

const Example = () => {
  const index = React.useContext(Breakpoints.Context);

  return <Button size={buttonSizes[index]}>Button size {buttonSizes[index]}</Button>;
};

const Demo = () => {
  return (
    <Breakpoints>
      <Example />
    </Breakpoints>
  );
};

export default Demo;
import React from 'react';
import Breakpoints from 'intergalactic/breakpoints';
import Button from 'intergalactic/button';

const buttonSizes = ['m', 'l'] as const;

const Example = () => {
  const index = React.useContext(Breakpoints.Context);

  return <Button size={buttonSizes[index]}>Button size {buttonSizes[index]}</Button>;
};

const Demo = () => {
  return (
    <Breakpoints>
      <Example />
    </Breakpoints>
  );
};

export default Demo;

Manual control

You can use an instance of the MediaList class, it has methods matches/addListener/removeListener and destructor.

tsx
import React from 'react';
import Breakpoints from 'intergalactic/breakpoints';
import Button from 'intergalactic/button';

const Demo = () => {
  const [index, setIndex] = React.useState(Breakpoints.mediaList.matches());

  React.useEffect(() => {
    const unsubscribe = Breakpoints.mediaList.addListener((index) => {
      setIndex(index);
    });
    return () => {
      unsubscribe();
    };
  }, []);

  return <Button size={(['m', 'l'] as const)[index]}>Button size {['M', 'L'][index]}</Button>;
};

export default Demo;
import React from 'react';
import Breakpoints from 'intergalactic/breakpoints';
import Button from 'intergalactic/button';

const Demo = () => {
  const [index, setIndex] = React.useState(Breakpoints.mediaList.matches());

  React.useEffect(() => {
    const unsubscribe = Breakpoints.mediaList.addListener((index) => {
      setIndex(index);
    });
    return () => {
      unsubscribe();
    };
  }, []);

  return <Button size={(['m', 'l'] as const)[index]}>Button size {['M', 'L'][index]}</Button>;
};

export default Demo;

Custom media

If you want to create a custom breakpoint component you need to call the createBreakpoints() function and pass an array of media queries.

TIP

The 'Breakpoints.mediaList.matches()' will return the intex of the first matching media query. From left to right.

tsx
import React from 'react';
import { createBreakpoints } from 'intergalactic/breakpoints';

const MEDIA = [
  '(max-width: 300px)',
  '(max-width: 500px)',
  '(max-width: 700px)',
  '(max-width: 900px)',
  '(max-width: 1100px)',
];
const Breakpoints = createBreakpoints(MEDIA);

const Example = () => {
  const index = React.useContext(Breakpoints.Context);

  return <div>Media matches "{MEDIA[index] || 'ZOOM WINDOW'}"</div>;
};

const Demo = () => {
  return (
    <Breakpoints>
      <Example />
    </Breakpoints>
  );
};

export default Demo;
import React from 'react';
import { createBreakpoints } from 'intergalactic/breakpoints';

const MEDIA = [
  '(max-width: 300px)',
  '(max-width: 500px)',
  '(max-width: 700px)',
  '(max-width: 900px)',
  '(max-width: 1100px)',
];
const Breakpoints = createBreakpoints(MEDIA);

const Example = () => {
  const index = React.useContext(Breakpoints.Context);

  return <div>Media matches "{MEDIA[index] || 'ZOOM WINDOW'}"</div>;
};

const Demo = () => {
  return (
    <Breakpoints>
      <Example />
    </Breakpoints>
  );
};

export default Demo;

Mocking

You can mock global media queries for testing purposes.

WARNING

It will work if you use createBreakpoints function only.

tsx
import React from 'react';
import { createBreakpoints } from 'intergalactic/breakpoints';

const meadiaQueries = [
  '(max-width: 300px)',
  '(max-width: 500px)',
  '(max-width: 700px)',
  '(max-width: 900px)',
  '(max-width: 1100px)',
];

const mockedScreenQuery = '(max-width: 700px)';
const noop: any = () => {};
if (globalThis.window) {
  const realMatchMedia = window.matchMedia;
  window.matchMedia = (query): any => {
    if (meadiaQueries.includes(query)) {
      return {
        matches: query === mockedScreenQuery,
        meadia: query,
        onchange: null,
        addListener: noop,
        removeListener: noop,
        addEventListener: noop,
        removeEventListener: noop,
        dispatchEvent: noop,
      };
    }
    return realMatchMedia(query);
  };
}

const Breakpoints = createBreakpoints(meadiaQueries);

const Example = () => {
  const index = React.useContext(Breakpoints.Context);

  return <div>Media matches "{meadiaQueries[index] || 'ZOOM WINDOW'}"</div>;
};

const Demo = () => {
  return (
    <Breakpoints>
      <Example />
    </Breakpoints>
  );
};

export default Demo;
import React from 'react';
import { createBreakpoints } from 'intergalactic/breakpoints';

const meadiaQueries = [
  '(max-width: 300px)',
  '(max-width: 500px)',
  '(max-width: 700px)',
  '(max-width: 900px)',
  '(max-width: 1100px)',
];

const mockedScreenQuery = '(max-width: 700px)';
const noop: any = () => {};
if (globalThis.window) {
  const realMatchMedia = window.matchMedia;
  window.matchMedia = (query): any => {
    if (meadiaQueries.includes(query)) {
      return {
        matches: query === mockedScreenQuery,
        meadia: query,
        onchange: null,
        addListener: noop,
        removeListener: noop,
        addEventListener: noop,
        removeEventListener: noop,
        dispatchEvent: noop,
      };
    }
    return realMatchMedia(query);
  };
}

const Breakpoints = createBreakpoints(meadiaQueries);

const Example = () => {
  const index = React.useContext(Breakpoints.Context);

  return <div>Media matches "{meadiaQueries[index] || 'ZOOM WINDOW'}"</div>;
};

const Demo = () => {
  return (
    <Breakpoints>
      <Example />
    </Breakpoints>
  );
};

export default Demo;

Released under the MIT License.

Released under the MIT License.