Fast & Versatile Positioning Library – Floating UI

Category: Javascript , Recommended | May 29, 2023
Author:floating-ui
Views Total:10 views
Official Page:Go to website
Last Update:May 29, 2023
License:MIT

Preview:

Fast & Versatile Positioning Library – Floating UI

Description:

A great alternative to the Popper.js library.

Floating UI is a blazing-fast, feature-rich positioning library for positioning any type of “floating” elements (like tooltips, popovers, dropdowns) to a given reference element.

Key Features:

  • Auto placement.
  • Supports virtual elements.
  • Auto flips floating elements to prevent overflow.
  • Compatible with React.

Basic Usage:

1. Install and import the Floating UI.

# Yarn
$ yarn add @floating-ui/dom
# NPM
$ npm i @floating-ui/dom
import {computePosition} from '@floating-ui/dom';

2. Or load the Floating UI from a CDN.

<script type="module">
  import * as FloatingUIDOM from 'https://cdn.skypack.dev/@floating-ui/[email protected]';
</script>
// OR
<script src="https://unpkg.com/@floating-ui/[email protected]"></script>
<script src="https://unpkg.com/@floating-ui/[email protected]"></script>

3. Compute the necessary coordinates to position the floating element next to a given reference element.

<button id="button">My button</button>
<div id="tooltip">My tooltip</div>
const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');
computePosition(button, tooltip).then(({x, y}) => {
  Object.assign(tooltip.style, {
    left: `${x}px`,
    top: `${y}px`,
  });
});

4. Possible options for the computePosition.

computePosition(referenceEl, floatingEl, {
  // top', 'top-start', 'top-end', 'right'
  // 'right-start', 'right-end'
  // 'bottom', 'bottom-start', 'bottom-end'
  // 'left', 'left-start', 'left-end';
  placement: 'bottom', 
  // 'absolute' | 'fixed'
  strategy: 'default'
  // autoPlacement
  // arrow
  // flip
  // hide
  // offset
  // shift
  // size
  // or a custom function
  middleware: [],
});

5. Modify the positioning coordinates or provide useful data using the middleware option.

// offset in px
import {computePosition, offset} from '@floating-ui/dom';
computePosition(referenceEl, floatingEl, {
  middleware: [offset(10)],
});
// move the floating element along the specified axes
import {computePosition, shift} from '@floating-ui/dom';
computePosition(referenceEl, floatingEl, {
  middleware: [shift()],
});
// changes the placement of the floating element to the opposite one by default
import {computePosition, flip} from '@floating-ui/dom';
computePosition(referenceEl, floatingEl, {
  middleware: [flip()],
});
// auto placement
import {computePosition, autoPlacement} from '@floating-ui/dom';
computePosition(referenceEl, floatingEl, {
  middleware: [autoPlacement()],
});
// hide the floating element in applicable situations
import {computePosition, hide} from '@floating-ui/dom';
computePosition(referenceEl, floatingEl, {
  middleware: [hide()],
}).then(({middlewareData}) => {
  const {referenceHidden} = middlewareData.hide;
  Object.assign(floatingEl.style, {
    visibility: referenceHidden ? 'hidden' : 'visible',
  });
});
// improved positioning for inline reference elements that span over multiple lines, such as hyperlinks or range selections
import {computePosition, inline} from '@floating-ui/dom';
computePosition(referenceEl, floatingEl, {
  middleware: [inline()],
});
// position an inner element of the floating element (usually a triangle or caret) so that it is centered to the reference element
<div id="tooltip">
  Tooltip text
  <div id="arrow"></div>
</div>
import {computePosition, arrow} from '@floating-ui/dom';
const arrowEl = document.querySelector('#arrow');
computePosition(referenceEl, floatingEl, {
  middleware: [
    arrow({
      element: arrowEl,
    }),
  ],
}).then(({middlewareData}) => {
  const {x, y} = middlewareData.arrow;
  Object.assign(arrowEl.style, {
    left: x != null ? `${x}px` : '',
    top: y != null ? `${y}px` : '',
  });
});
// change the size of the floating element
import {computePosition, size} from '@floating-ui/dom';
computePosition(referenceEl, floatingEl, {
  middleware: [
    size({
      apply({width, height, reference, floating}) {
        // Do things with the data, e.g.
        Object.assign(floatingEl.style, {
          maxWidth: `${width}px`,
          maxHeight: `${height}px`,
        });
      },
    }),
  ],
});

6. Automatically update the position of the floating element when required.

import {computePosition, autoUpdate} from '@floating-ui/dom';
async function update() {
  const {x, y} = await computePosition(referenceEl, floatingEl);
}
const cleanup = autoUpdate(referenceEl, floatingEl, update);

7. Compute the overflow offsets of either the reference or floating element relative to any clipping boundaries.

import {detectOverflow} from '@floating-ui/dom';
const middleware = {
  name: 'middleware',
  async fn(middlewareArguments) {
    const overflow = await detectOverflow(middlewareArguments);
    return {};
  },
};

Changelog:

05/29/2023

  • v1.2.9: bugfixes

05/14/2023

  • v1.2.8: bugfixes

04/27/2023

  • v1.2.7: bugfixes

04/07/2023

  • v1.2.6: bugfixes

03/20/2023

  • v1.2.5: bugfixes

03/13/2023

  • v1.2.4: bugfixes

03/01/2023

  • v1.2.3: bugfixes

02/12/2023

  • v1.2.1: bugfixes

02/05/2023

  • v1.2.0: feat(platform): add ability to polyfill offsetParent access (in a pure way) to fix a platform gap where the incorrect value is returned inside shadow DOM; feat(detectOverflow): accept virtual Rect boundaries.

01/28/2023

  • v1.1.1: bugfixes

12/27/2022

  • v1.1.0: bugfixes

12/16/2022

  • v1.0.12: bugfixes

12/12/2022

  • v1.0.10: bugfixes; performance improvements

12/07/2022

  • v1.0.9: fix: correctly handle parent scale transforms when detecting clipping

12/06/2022

  • v1.0.8: Bugfix

11/24/2022

  • v1.0.7: Bugfix

11/16/2022

  • v1.0.5: Bugfix

10/30/2022

  • v1.0.4: fix(autoUpdate): add event listeners to a VirtualElement’s contextElement if present

10/19/2022

  • v1.0.3: Bugfixes

09/19/2022

  • v1.0.2: Performance Improvements

08/09/2022

  • v1.0.1

07/19/2022

  • v1.0.0

06/12/2022

  • v0.5.3: Bugfix

05/28/2022

  • v0.5.2: Bugfix

05/19/2022

  • v0.5.1: Bugfix

You Might Be Interested In:


Leave a Reply