Skip to content

v2.0.0

Compare
Choose a tag to compare
@everweij everweij released this 13 Dec 16:42
· 39 commits to master since this release

🎉 Finally... after more than a year after the initial release, I'm proud to preset to you v2.0.0! 🎉

The past months I've been really busy with a complete rewrite of this project. The result is cleaner and better documented code 👨🏼‍💻, better performance 🚀, and the most important part: everything is a hook!

⚠️ Note: This is a major release with a lot of breaking stuff. Be sure to read the migration instructions below before upgrading your project from v1.x.x to v2.0.0.

Migration guide

<ToggleLayer />

The thing that definitely will have to most impact is <ToggleLayer /> (and useToggleLayer() in some sense). However, I'm optimistic in the amount of work it will take to migrate.

Let's do a comparison of the before and after:

// old
import { ToggleLayer } from "react-laag";

function Old() {
  return (
    <ToggleLayer
      renderLayer={({ isOpen, layerProps }) =>
        isOpen && <div {...layerProps}>Layer</div>
      }
    >
      {({ triggerRef, toggle }) => (
        <button ref={triggerRef} onClick={toggle}>
          Trigger
        </button>
      )}
    </ToggleLayer>
  );
}

// new
import { useLayer } from "react-laag";

function New() {
  const [isOpen, setOpen] = React.useState(false);

  const { layerProps, triggerProps, renderLayer } = useLayer({ isOpen });

  return (
    <>
      <button {...triggerProps} onClick={() => setOpen(!isOpen)}>Trigger</button>
      {isOpen && renderLayer(<div {...layerProps}>Layer</div>)}
    </>
  );
}

As you can see a lot of concepts still remain the same. One of the big differences is that the rendering of the layer now happens in a different place -> under the trigger element and wrapped inside a renderLayer() function.
This reads a lot nicer, because mentally the layer will follow after the trigger. Also this pattern opens the door for better composition.

anchors -> placements

The previously known 'anchors' have been renamed to the 'placement' prop. Possible placements are now: top-start, top-center, top-end, right-start, right-center, ...etc

So, before it was "BOTTOM_LEFT", now it is "bottom-start".

Options

The new option-object has been flattened and some properties have been renamed. Here's a map from old to new:

old new notes
isOpen isOpen now controlled by default
fixed overflowContainer now true by default
placement.anchor placement
placement.possibleAnchors possiblePlacements
placement.autoAdjust auto
placement.snapToAnchor snap
placement.preferX preferX
placement.preferY preferY
placement.triggerOffset triggerOffset
placement.scrollOffset containerOffset this option has been renamed
placement.arrowOffset arrowOffset
placement.layerDimensions layerDimensions
onDisappear onDisappear
onOutsideClick onOutsideClick
closeOnDisappear x this option has been removed
closeOnOutsideClick x this option has been removed
ResizeObserver ResizeObserver
container container
environment environment

useTooltip()

This hook has been removed. Fortunately is pretty easy to replace this hook with useLayer() and useHover:

// before
import { useTooltip } from "react-laag";

function Before() {
  const [element, triggerProps] = useTooltip(
    ({ isOpen, layerProps }) =>
      isOpen && <div {...layerProps}>I'm a tooltip!</div>,
    {
      delayEnter: 100,
      delayLeave: 100
    }
  );

  return (
    <>
      {element}
      <div {...triggerProps}>Hover me</div>
    </>
  );
}

// after
import { useLayer, useHover } from "react-laag";

function After() {
  const [isOpen, hoverProps] = useHover({ delayEnter: 100, delayLeave: 100 });

  const { renderLayer, triggerProps, layerProps } = useLayer({ isOpen });

  return (
    <>
      <div {...triggerProps} {...hoverProps}>
        Hover me...
      </div>
      {isOpen && renderLayer(<div {...layerProps}>I'm a tooltip!</div>)}
    </>
  );
}

<Transition />

This small utility component has been marked as deprecated and will be removed somewhere in de upcoming releases. I recommend to look for alternatives like framer-motion, react-spring or react-transition-group.