npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

lc-svelte-floating-ui

v1.0.3

Published

Svelte actions for working with floating ui

Downloads

10

Readme

🎈Svelte Floating UI

npm version npm downloads license

Floating UI for Svelte with actions. No wrapper components or component bindings required!

npm i svelte-floating-ui @floating-ui/core

Usage

createFloatingActions takes an optional options object for configuring the content placement. The content action also takes an optional options object for updating the options of the content placement.

createFloatingActions also returns an update method as it's third value which can be used to manually update the content position.

Example

<script lang="ts">
  import { offset, flip, shift } from "svelte-floating-ui/dom";
  import { createFloatingActions } from "svelte-floating-ui";

  const [ floatingRef, floatingContent ] = createFloatingActions({
    strategy: "absolute",
    placement: "top",
    middleware: [
      offset(6),
      flip(),
      shift(),
    ]
  });

  let showTooltip: boolean = false;
</script>

<button
  on:mouseenter={() => showTooltip = true}
  on:mouseleave={() => showTooltip = false}
  use:floatingRef
>Hover me</button>

{#if showTooltip}
  <div style="position:absolute" use:floatingContent>
    Tooltip
  </div>
{/if}

API

Setting Floating UI options

Floating UI options can be set statically when creating the actions, or dynamically on the content action.

If both are set, then the dynamic options will be merged with the initial options.

<script>
  // set once and no longer updated
  const [ floatingRef, floatingContent ] = createFloatingActions(initOptions);
</script>

<!-- will be merged with initOptions -->
<div use:floatingContent={ dynamicOptions }/>

Updating the Floating UI position

The content element's position can be manually updated by using the third value returned by createFloatingActions. This method takes an optional options object which will be merged with the initial options.

<script>
  // Get update method
  const [ floatingRef, floatingContent, update] = createFloatingActions(initOptions);

  update(updateOptions)
</script>

Floating UI autoUpdate

You can use autoUpdate options directly in initOptions for createFloatingActions or floatingContent, but not in update

<script>
  import { offset, flip, shift } from "svelte-floating-ui/dom";
  import { createFloatingActions } from "svelte-floating-ui";

  const [ floatingRef, floatingContent ] = createFloatingActions({
    strategy: "absolute",
    placement: "top",
    middleware: [
      offset(6),
      flip(),
      shift(),
    ],
    autoUpdate: { // or false to disable everything
      ancestorResize: false,
      elementResize: false
    }
  });
</script>

What values can autoUpdate have?

Partial<Options>

/**
* false: Don't initialize autoUpdate;
* true: Standard autoUpdate values from the documentation;
* object: All as in the autoUpdate documentation. Your parameters are added to the default ones;
* @default true
*/
autoUpdate?: boolean | Partial<Options>

Virtual Elements

Svelte Floating UI allows you to use the floatingRef (reference node) like VirtualElement

Svelte stores allow you to make these elements reactive and provide full support for them in the Svelte Floating UI

This is an example of creating a tooltip that runs behind the mouse cursor:

<script lang='ts'>
  import type { ClientRectObject, VirtualElement } from 'svelte-floating-ui/core'
  import { createFloatingActions } from 'svelte-floating-ui'
  import { writable } from 'svelte/store'
  
  const [floatingRef, floatingContent] = createFloatingActions({
    strategy: 'fixed', //or absolute
  })

  let x = 0
  let y = 0

  const mousemove = (ev: MouseEvent) => {
    x = ev.clientX
    y = ev.clientY
  }

  $: getBoundingClientRect = ():ClientRectObject => {
    return {
      x,
      y,
      top: y,
      left: x,
      bottom: y,
      right: x,
      width: 0,
      height: 0
    }
  }
  
  const virtualElement = writable<VirtualElement>({ getBoundingClientRect })

  $: virtualElement.set({ getBoundingClientRect })

  floatingRef(virtualElement)
</script>

<svelte:window on:mousemove={mousemove}/>

<main>
  <h2 use:floatingContent>Magic</h2>
</main>

Applying custom styles on compute

To apply styles manually, you can pass the onComputed option to createFloatingActions. This is a function that recieves a ComputePositionReturn. This function is called every time the tooltip's position is computed.

See Arrow Middleware for an example on it's usage.

Arrow Middleware

For convenience, a custom Arrow middleware is provided. Rather than accepting an HTMLElement, this takes a Writable<HTMLElement>. Otherwise, this middleware works exactly as the regular Floating UI one, including needing to manually set the arrow styles.

To set the styles, you can pass the onComputed option. The below implementation is copied from the Floating UI Tutorial.

<script>
  import { writable } from "svelte/store";
  import { arrow } from "svelte-floating-ui";

  const arrowRef = writable(null);
  const [ floatingRef, floatingContent, update] = createFloatingActions({
    strategy: "absolute",
    placement: "bottom",
    middleware: [
      arrow({ element: arrowRef })
    ],
    onComputed({ placement, middlewareData }) {
      const { x, y } = middlewareData.arrow;
      const staticSide = {
        top: 'bottom',
        right: 'left',
        bottom: 'top',
        left: 'right',
      }[placement.split('-')[0]];

      Object.assign($arrowRef.style, {
        left: x != null ? `${x}px` : "",
        top: y != null ? `${y}px` : "",
        [staticSide]: "-4px"
      });
    }
  });
</script>

<button
  on:mouseenter={() => showTooltip = true}
  on:mouseleave={() => showTooltip = false}
  use:floatingRef
>Hover me</button>

{#if showTooltip}
  <div class="tooltip" use:floatingContent>
    Tooltip this is some longer text than the button
    <div class="arrow" bind:this={$arrowRef} />
  </div>
{/if}

Thanks to TehNut/svelte-floating-ui for the foundation for this package