{"size": 2235, "ext": "js", "max_stars_repo_path": "packages/arwes/src/tools/createResponsive/index.js", "max_stars_repo_name": "AnnaGingle/arwes", "max_stars_repo_stars_event_min_datetime": "2019-03-16T03:42:47.000Z", "max_stars_repo_stars_event_max_datetime": "2022-03-31T19:28:43.000Z", "max_issues_repo_path": "packages/arwes/src/tools/createResponsive/index.js", "max_issues_repo_name": "AnnaGingle/arwes", "max_issues_repo_issues_event_min_datetime": "2019-03-24T19:47:59.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-06T19:47:46.000Z", "max_forks_repo_path": "packages/arwes/src/tools/createResponsive/index.js", "max_forks_repo_name": "AnnaGingle/arwes", "max_forks_repo_forks_event_min_datetime": "2019-03-20T09:37:35.000Z", "max_forks_repo_forks_event_max_datetime": "2022-03-29T09:14:01.000Z"}
{"max_stars_count": 4886, "max_issues_count": 115, "max_forks_count": 232, "avg_line_length": 27.9375, "max_line_length": 85, "alphanum_fraction": 0.5932885906}
import isNode from 'detect-node';
import getDimensions from '../get-dimensions';

// TODO: There should be a way to define the default viewport size when rendering
// from server-side or any other env.

/**
 * Create a handler for responsive functionalities.
 * @param  {Object} depencencies - Depencencies.
 * @param  {Function} depencencies.getTheme - Inject the theme settings.
 * @param  {Function} depencencies.getDimensions - Inject the get dimensions tool.
 * @return {Object} - Handler.
 */
export default depencencies => {
  const deps = {
    getTheme: () => ({}),
    getDimensions,
    ...depencencies
  };
  return {
    /**
     * Get the current responsive stats.
     * @return {Object} { small: Boolean, medium: Boolean, large: Boolean }
     */
    get () {
      const theme = deps.getTheme();
      const { width } = deps.getDimensions();
      const { small, medium, large } = theme.responsive;

      if (width <= small) {
        return { small: true, status: 'small' };
      }
      else if (width <= medium) {
        return { medium: true, status: 'medium' };
      }
      else if (width <= large) {
        return { large: true, status: 'large' };
      }

      return { xlarge: true, status: 'xlarge' };
    },

    /**
     * Register a on resize window callback to know when the current browser viewport
     * dimentions make the breakpoint change.
     * @param  {Function} callback - It's called on every change on the breakpoint
     * and receives and object defining the current viewport size.
     * @return {Function} The event listener.
     */
    on (callback) {
      const current = this.get();
      let state = current.status;

      const onChange = () => {
        const stats = this.get();
        if (stats.status !== state) {
          callback(stats);
          state = stats.status;
        }
      };

      if (!isNode) {
        window.addEventListener('resize', onChange, false);
      }

      return onChange;
    },

    /**
     * Turns off a window on resize callback previously created.
     * @param  {Function} - The event callback.
     */
    off (onChange) {
      if (!isNode) {
        window.removeEventListener('resize', onChange, false);
      }
    }
  };
};
