All Projects โ†’ wellyshen โ†’ React Cool Dimensions

wellyshen / React Cool Dimensions

Licence: mit
๐Ÿ˜Ž ๐Ÿ“ React hook to measure an element's size and handle responsive components.

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to React Cool Dimensions

React Cool Inview
๐Ÿ˜Ž ๐Ÿ–ฅ๏ธ React hook to monitor an element enters or leaves the viewport (or another element).
Stars: โœญ 830 (+98.09%)
Mutual labels:  hook, performance
Performance
โฑ PHP performance tool analyser your script on time, memory usage and db query. Support Laravel and Composer for web, web console and command line interfaces.
Stars: โœญ 429 (+2.39%)
Mutual labels:  measure, performance
Use Web Animations
๐Ÿ˜Ž ๐Ÿฟ React hook for highly-performant and manipulable animations using Web Animations API.
Stars: โœญ 802 (+91.41%)
Mutual labels:  hook, performance
React Intersection Observer
React implementation of the Intersection Observer API to tell you when an element enters or leaves the viewport.
Stars: โœญ 2,689 (+541.77%)
Mutual labels:  hook, performance
Packagephobia
โš–๏ธ Find the cost of adding a new dependency to your project
Stars: โœญ 1,110 (+164.92%)
Mutual labels:  size, performance
React Native Text Size
Measure text accurately before laying it out and get font information from your App.
Stars: โœญ 238 (-43.2%)
Mutual labels:  size, measure
Component Size
React hook for determining the size of a component
Stars: โœญ 224 (-46.54%)
Mutual labels:  size, hook
Use Resize Observer
A React hook that allows you to use a ResizeObserver to measure an element's size.
Stars: โœญ 305 (-27.21%)
Mutual labels:  size, measure
Objectbox Java
ObjectBox is a superfast lightweight database for objects
Stars: โœญ 3,950 (+842.72%)
Mutual labels:  performance
Sqlindexmanager
Free GUI Tool for Index Maintenance on SQL Server and Azure
Stars: โœญ 403 (-3.82%)
Mutual labels:  performance
Linux Steam Integration
Helper for enabling better Steam integration on Linux
Stars: โœญ 386 (-7.88%)
Mutual labels:  performance
Guider
Performance Analyzer
Stars: โœญ 393 (-6.21%)
Mutual labels:  performance
Neon
Intelยฎ Nervanaโ„ข reference deep learning framework committed to best performance on all hardware
Stars: โœญ 3,855 (+820.05%)
Mutual labels:  performance
Laravel Model Cleanup
Clean up unneeded records
Stars: โœญ 388 (-7.4%)
Mutual labels:  performance
Prerender.js
Fast webpages for all browsers.
Stars: โœญ 411 (-1.91%)
Mutual labels:  performance
Npm Consider
Check package dependencies before installing it
Stars: โœญ 386 (-7.88%)
Mutual labels:  size
Enlightn
Your performance & security consultant, an artisan command away.
Stars: โœญ 378 (-9.79%)
Mutual labels:  performance
Nuitka
Nuitka is a Python compiler written in Python. It's fully compatible with Python 2.6, 2.7, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, and 3.9. You feed it your Python app, it does a lot of clever things, and spits out an executable or extension module.
Stars: โœญ 6,173 (+1373.27%)
Mutual labels:  performance
Entitycomponentsystemsamples
No description or website provided.
Stars: โœญ 4,218 (+906.68%)
Mutual labels:  performance
Binjs Ref
Reference implementation for the JavaScript Binary AST format
Stars: โœญ 399 (-4.77%)
Mutual labels:  performance

REACT COOL DIMENSIONS

A React hook that measure an element's size and handle responsive components with highly-performant way, using ResizeObserver. Try it you will ๐Ÿ‘๐Ÿป it!

โค๏ธ it? โญ๏ธ it on GitHub or Tweet about it.

build status coverage status npm version npm downloads npm downloads npm bundle size MIT licensed All Contributors PRs welcome Twitter URL

demo

โšก๏ธ Try yourself: https://react-cool-dimensions.netlify.app

Features

Requirement

To use react-cool-dimensions, you must use [email protected] or greater which includes hooks.

Installation

This package is distributed via npm.

$ yarn add react-cool-dimensions
# or
$ npm install --save react-cool-dimensions

Usage

react-cool-dimensions has a flexible API design, it can cover simple to complex use cases for you. Here are some examples to show you how does it work.

โš ๏ธ Most modern browsers support ResizeObserver natively. You can also use polyfill for full browser support.

Basic Use Case

To report the size of an element by the width and height states.

import useDimensions from "react-cool-dimensions";

const App = () => {
  const { ref, width, height, entry, unobserve, observe } = useDimensions({
    onResize: ({ width, height, entry, unobserve, observe }) => {
      // Triggered whenever the size of the target is changed
    },
  });

  return (
    <div ref={ref}>
      Hi! My width is {width}px and height is {height}px
    </div>
  );
};

Responsive Components

We have media queries but those are based on the browser viewport not individual elements. In some cases, we'd like to style components based on the width of a containing element rather than the browser viewport. To meet this demand there's a proposal for container queries, but it still doesn't exist today...

No worries, react-cool-dimensions provides an alternative solution for us! We can activate the responsive mode by the breakpoints option. It's a width-based solution, once it's activated we can easily apply different styles to a component according to the currentBreakpoint state. The overall concept as below.

If you wish to update the state on the breakpoints changed, you can set the updateOnBreakpointChange option to true.

import useDimensions from "react-cool-dimensions";

const Card = () => {
  const { ref, currentBreakpoint } = useDimensions({
    // The "currentBreakpoint" will be the object key based on the target's width
    // for instance, 0px - 319px (currentBreakpoint = XS), 320px - 479px (currentBreakpoint = SM) and so on
    breakpoints: { XS: 0, SM: 320, MD: 480, LG: 640 },
    // Will only update the state on breakpoint changed, default is false
    updateOnBreakpointChange: true,
    onResize: ({ currentBreakpoint }) => {
      // Now the event callback will be triggered when breakpoint is changed
      // we can also access the "currentBreakpoint" here
    },
  });

  return (
    <div class={`card ${currentBreakpoint}`} ref={ref}>
      <div class="card-header">I'm ๐Ÿ˜Ž</div>
      <div class="card-body">I'm ๐Ÿ‘•</div>
      <div class="card-footer">I'm ๐Ÿ‘Ÿ</div>
    </div>
  );
};

Note: If the breakpoints option isn't set or there's no the defined breakpoint (object key) for a range of width. The currentBreakpoint will be empty string.

Conditionally Updating State

You can use the shouldUpdate option to conditionally update the state to reduce unnecessary re-renders as below.

const returnObj = useDimensions({
  shouldUpdate: ({ currentBreakpoint, width, height, entry }) => {
    // Will only update the state when the target element's width greater than 300px
    return state.width > 300;
  },
});

Note: updateOnBreakpointChange and shouldUpdate can't be used at the same time, shouldUpdate has a higher priority.

Border-box Size Measurement

By default, the hook reports the width and height based on the content rectangle of the target element. We can include the padding and border for measuring by the useBorderBoxSize option. Please note, the width and height states are rely on the ResizeObserverEntry.borderBoxSize but it hasn't widely implemented by browsers therefore we need to use polyfill for this feature.

import useDimensions from "react-cool-dimensions";
import { ResizeObserver } from "@juggle/resize-observer";

const App = () => {
  const { ref, width, height } = useDimensions({
    useBorderBoxSize: true, // Tell the hook to measure based on the border-box size, default is false
    polyfill: ResizeObserver, // Use polyfill to make this feature works on more browsers
  });

  return (
    <div
      style={{
        width: "100px",
        height: "100px",
        padding: "10px",
        border: "5px solid grey",
      }}
      ref={ref}
    >
      {/* Now the width and height will be: 100px + 10px + 5px = 115px */}
      Hi! My width is {width}px and height is {height}px
    </div>
  );
};

Conditional Component

There're two ways to use react-cool-dimensions with a conditional component.

Option 1, we can lazily start observing via the observe method:

import { useState } from "react";
import useDimensions from "react-cool-dimensions";

const App = () => {
  const [show, setShow] = useState(false);
  const { width, height, observe } = useDimensions();

  return (
    <>
      <button onClick={() => setShow(!show)}>Toggle</button>
      {show && (
        <div ref={observe}>
          Hi! My width is {width}px and height is {height}px
        </div>
      )}
    </>
  );
};

Option 2, wrap the hook into the conditional component:

import { useState } from "react";
import useDimensions from "react-cool-dimensions";

const MyComponent = () => {
  const { ref, width, height } = useDimensions();

  return (
    <div ref={ref}>
      Hi! My width is {width}px and height is {height}px
    </div>
  );
};

const App = () => {
  const [show, setShow] = useState(false);

  return (
    <>
      <button onClick={() => setShow(!show)}>Toggle</button>
      {show && <MyComponent />}
    </>
  );
};

Use Your Own ref

In case of you had a ref already or you want to share a ref for other purposes. You can pass in the ref instead of using the one provided by this hook.

const ref = useRef();
const { width, height } = useDimensions({ ref });

Performance Optimization

The onResize event will be triggered whenever the size of the target element is changed. We can reduce the frequency of the event callback by activating the responsive mode or implementing our own throttled/debounced function as below.

import _ from "lodash";

const { ref, width, height } = useDimensions({
  onResize: _.throttle(() => {
    // Triggered once per every 500 milliseconds
  }, 500),
});

Working in TypeScript

This hook supports TypeScript, you can tell the hook what type of element you are going to observe via the generic type:

import useInView from "react-cool-dimensions";

const App = () => {
  const { ref } = useDimensions<HTMLDivElement>();

  return <div ref={ref} />;
};

API

const returnObj = useDimensions(options?: object);

Return object

It's returned with the following properties.

Key Type Default Description
ref object Used to set the target element for measuring.
width number The width of the target element in pixel.
height number The height of the target element in pixel.
currentBreakpoint string Indicates the current breakpoint of the responsive components.
entry object The ResizeObserverEntry of the target element.
unobserve function To stop observing the target element.
observe function To lazily start or re-start observing the target element once it's stopped observing.

Parameter

The options provides the following configurations and event callback for you.

Key Type Default Description
ref object For some reasons, you can pass in your own ref instead of using the built-in.
breakpoints object Activates the responsive mode for responsive components or performance optimization.
updateOnBreakpointChange boolean false Tells the hook to update the state on breakpoint changed.
useBorderBoxSize boolean false Tells the hook to measure the target element based on the border-box size.
shouldUpdate function Tells the hook to conditionally update the state.
onResize function It's invoked whenever the size of the target element is changed. But in responsive mode, it's invoked based on the changing of the breakpoint rather than the size.
polyfill ResizeObserver It's used for injecting a polyfill.

ResizeObserver Polyfill

ResizeObserver has good support amongst browsers, but it's not universal. You'll need to use polyfill for browsers that don't support it. Polyfills is something you should do consciously at the application level. Therefore react-cool-dimensions doesn't include it.

We recommend using @juggle/resize-observer:

$ yarn add @juggle/resize-observer
# or
$ npm install --save @juggle/resize-observer

Then inject it by the polyfill option:

import { ResizeObserver } from "@juggle/resize-observer";

const { width, height } = useDimensions(ref, { polyfill: ResizeObserver });

Or pollute the window object:

import { ResizeObserver, ResizeObserverEntry } from "@juggle/resize-observer";

if (!("ResizeObserver" in window)) {
  window.ResizeObserver = ResizeObserver;
  // Only use it when you have this trouble: https://github.com/wellyshen/react-cool-dimensions/issues/45
  // window.ResizeObserverEntry = ResizeObserverEntry;
}

You could use dynamic imports to only load the file when the polyfill is required:

(async () => {
  if (!("ResizeObserver" in window)) {
    const module = await import("@juggle/resize-observer");
    window.ResizeObserver = module.ResizeObserver;
    // Only use it when you have this trouble: https://github.com/wellyshen/react-cool-dimensions/issues/45
    // window.ResizeObserverEntry = module.ResizeObserverEntry;
  }
})();

Contributors โœจ

Thanks goes to these wonderful people (emoji key):


Welly

๐Ÿ’ป ๐Ÿ“– ๐Ÿšง

Runar Kristoffersen

๐Ÿ“– ๐Ÿ’ป ๐Ÿค”

This project follows the all-contributors specification. Contributions of any kind welcome!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].