Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

headlessui-float-vue

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

headlessui-float-vue

Eazy use Headless UI for Vue 3 with Floating UI (Popper.js)

  • 0.3.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
12
increased by9.09%
Maintainers
1
Weekly downloads
 
Created
Source

Headless UI Float Vue

English | 繁體中文

Eazy use Headless UI for Vue 3 with Floating UI (Popper.js) to position floating elements.

This package is adapted from headlessui#154 example.

  • Eazy use Headless UI & Tailwind CSS
  • Floating UI (New version Popper.js) position floating elements
  • Auto-update floating elements
  • Support Transition
  • Support Portal (Teleport)
  • Support Arrow

Example repository

Installation

# npm
npm i headlessui-float-vue
# yarn
yarn add headlessui-float-vue

Usage

First finding a Headless UI component that needs to positioning element, such as the <Menu> component here. Import <Float> component:

<script setup>
import { Float } from 'headlessui-float-vue'
</script>

Then wrap <Float> around <MenuButton> and <MenuItems>:

<Menu>
+ <Float>
    <MenuButton class="...">
      Options
    </MenuButton>

    <MenuItems class="...">
      ...
    </MenuItems>
+ </Float>
</Menu>

Note that <Float> must contain 2 child elements, the first being a reference element, either a Headless UI component or an HTML element, and the second being a float element.

Then remove the "absolute", "right-0" and other positioning class from <MenuItems>, and add the placement="bottom-end" attribute:

<Menu>
  <Float placement="bottom-end">
    ...
  </Float>
</Menu>

Remove the "mt-2" class from <MenuItems>, and add the :offset="4" attribute:

<Menu>
  <Float placement="bottom-end" :offset="4">
    ...
  </Float>
</Menu>

Then <Menu> can be automatically position the inner <MenuItems>.

In addition to <Menu>, the same can be used on <Listbox>, <Popover> or <Combobox> components, and you can use <Float> on any element that requires floating positioning.

Floating UI Options

placement

Floating positioning placement:

<Float placement="left-start">

All 12 placement in the Floating UI can be used:

  • top
  • top-start
  • top-end
  • right
  • right-start
  • right-end
  • bottom
  • bottom-start
  • bottom-end
  • left
  • left-start
  • left-end

strategy

The type of CSS position property, absolute or fixed

<Float strategy="fixed">

offset

Offset of the floating element from the reference element (px):

<Float :offset="8">

More options supported by offset, refer to Floating UI's offset documentation: https://floating-ui.com/docs/offset

shift

Move the reference elements back into the view:

<Float shift>

Set the offset (px) of the floating element from the view border:

<Float :shift="8">

More options supported by shift, refer to Floating UI's shift documentation: https://floating-ui.com/docs/shift

flip

Change to the opposite placement to keep it in view:

flip cannot be used with autoPlacement

<Float flip>

More options supported by flip, refer to Floating UI's flip documentation: https://floating-ui.com/docs/flip

autoPlacement

Floating elements chooses the placement with more space left:

autoPlacement cannot be used with flip

<Float auto-placement>

More options supported by autoPlacement, refer to Floating UI's autoPlacement documentation: https://floating-ui.com/docs/autoPlacement

autoUpdate

Automatically update floating elements when needed, the default value is true. Can be set to false to disable autoUpdate:

<Float :auto-update="false">

More options supported by autoUpdate, refer to Floating UI's autoUpdate documentation: https://floating-ui.com/docs/autoUpdate

middleware

If the above basic settings do not satisfy your needs, you can add the Floating UI middleware yourself:

<Float :middleware="middleware">

<script setup>
import { offset } from '@floating-ui/dom'

const middleware = [
  offset({
    mainAxis: 10,
    crossAxis: 6,
  }),
]
</script>

Or pass a function to get reference elements and floating elements in the parameters:

const middleware = ({ referenceEl, floatingEl }) => [
  ...
]

Transition

<Float> use the <transition> component, just adds the classes of transition:

<Float
  enter="transition duration-200 ease-out"
  enter-from="scale-95 opacity-0"
  enter-to="scale-100 opacity-100"
  leave="transition duration-150 ease-in"
  leave-from="scale-100 opacity-100"
  leave-to="scale-95 opacity-0"
  tailwindcss-origin-class
>

When tailwindcss-origin-class is enabled, the corresponding Tailwind CSS origin class will be automatically added according to the placement (e.g. top corresponds to origin-bottom class, bottom-start corresponds to origin-top-left class).

If use the tailwindcss-origin-class, also need to add the origin class to the safelist:

tailwind.config.js

const { tailwindcssOriginSafelist } = require('headlessui-float-vue')

module.exports = {
  safelist: [...tailwindcssOriginSafelist],
}

If need to override the origin class, can use origin-class.

<Float origin-class="origin-top-left">

Arrow

First import the <FloatArrow> component, and palce it inside the floating element, then add the class:

<Popover>
  <Float>
    ...
    <PopoverPanel>
      <!-- add arrow -->
      <FloatArrow class="absolute bg-white w-5 h-5 rotate-45 border border-gray-200" />
      <div>
        Popover & arrow, content...
      </div>
    </PopoverPanel>
  </Float>
</Popover>

<script setup>
...
import { Float, FloatArrow } from 'headlessui-float-vue'
</script>

Then add the arrow prop in <Float>, and add :offset="15" to keep the arrow away from the reference element:

<Float arrow :offset="15">

Full example of arrow:

<template>
  <Popover>
    <Float
      placement="bottom-start"
      :offset="15"
      arrow
    >
      <PopoverButton class="px-5 py-2 bg-rose-50 hover:bg-rose-100 text-rose-500 rounded">
        Button
      </PopoverButton>

      <PopoverPanel class="w-[240px] h-[70px] bg-white border border-gray-200 rounded-md shadow-lg focus:outline-none">
        <FloatArrow class="absolute bg-white w-5 h-5 rotate-45 border border-gray-200" />
        <div class="relative h-full bg-white p-3 text-rose-500 rounded-md">
          Popover & arrow, content...
        </div>
      </PopoverPanel>
    </Float>
  </Popover>
</template>

<script setup>
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
import { Float, FloatArrow } from 'headlessui-float-vue'
</script>

z-index

Set z-index CSS property for the floating element, the default value is 9999, and other numbers can be set:

<Float :z-index="100">

Portal (Teleport)

Append the floating element to <body>:

<Float portal>

Or can select other elements that already exist:

<Float portal="#other-root-element">

High-Order Component

High-order component, can be easily applied in projects after custom of <Float> component:

HighOrderFloat.vue

<template>
  <Float
    :offset="8"
    flip
    :shift="6"
    portal
    enter="transition duration-200 ease-out"
    enter-from="scale-95 opacity-0"
    enter-to="scale-100 opacity-100"
    leave="transition duration-150 ease-in"
    leave-from="scale-100 opacity-100"
    leave-to="scale-95 opacity-0"
    tailwindcss-origin-class
  >
    <slot></slot>
  </Float>
</template>

<script setup>
import { Float } from 'headlessui-float-vue'
</script>

Used in the same way as <Float>. It can also override the defined prop in high-order component:

<Menu>
  <HighOrderFloat placement="bottom-end" :offset="12">
    <MenuButton>
      Options
    </MenuButton>
    <MenuItems>
      ...
    </MenuItems>
  </HighOrderFloat>
</Menu>

License

Under the MIT LICENSE

Keywords

FAQs

Package last updated on 11 Mar 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc