Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/refzlund/floating-runes


https://github.com/refzlund/floating-runes

Last synced: 14 days ago
JSON representation

Awesome Lists containing this project

README

        

# Floating Runes

Svelte 5 Runes powered wrapper for [@floating-ui](https://floating-ui.com). An alternative approach to [svelte-floating-ui](https://github.com/fedorovvvv/svelte-floating-ui) which approx. does the same thing.

floating-runes will also:

- Position arrow/floater automatically (unless `autoPosition: false` is provided)
- [Access the elements](#floatreferenced-floattethered-and-floatattached) via `$state` for `.referenced`, `.tethered`, `.attached` (tethered ?? referenced)
- [Tethering](#tethering) (temporary element reference)
- [Conditional reference/tethering](#floatref-and-floattether)
- A [`portal`](#bonus) action

Other than that, just use it as you would use `@floating-ui`🎉

Happy coding!🦒


**Usage**

1. [Simple example](#usage)
1. [Tethering](#tethering)
1. [Advanced use](#advanced)
1. [Portal action](#bonus)


**Options and properties**
1. [floatingUI](#floatingui)
1. [use:float](#floatingui)
1. [float.ref and float.tether](#floatref-and-floattether)
1. [float.untether](#floatuntether)


### Usage

`bun add floating-runes`

- `use:float` - Designating the floating elements
- `use:float.arrow` - Designated arrow element; must be a direct child element of `use:float`
- `use:float.ref` - The thing the floated element(s) is referencing

[Svelte Playground - Usage example](https://svelte.dev/playground/98b0d71e31a0432fa853e8edefb555bf?version=5.14.0)

```html

import floatingUI, { flip, shift, arrow } from 'floating-runes'

const float = floatingUI({
placement: 'top',
middleware: [
flip(),
shift(),
arrow()
]
})





Hover me

```

> [!TIP]
> P.S. you can use multiple `use:float` from the same declaration.


#### Tethering

You can use `float.tether(element)` to float to another element than the `float.ref`. Then use `float.untether()` and it returns to `float.ref`.

[Svelte Playground - Tethering example](https://svelte.dev/playground/7fd33cfe7a084f289253c30eb9eb79c2?version=5.14.0)

```html

import floatingUI, { flip, shift, arrow } from 'floating-runes'

let url = '/a' // demo example

const float = floatingUI()

{#snippet href(ref, text)}
ref === url}
use:float.tether={'pointerenter'}
href={ref}
>
{text}

{/snippet}

{#if float.tethered}


{/if}


{@render href('/a', 'Hover me')}
{@render href('/b', 'I want attention')}
{@render href('/c', 'Guys... what about meeEeEe')}
{@render href('/d', 'Ignore my brother')}

```


#### Advanced

As per the documentation of [@floating-ui](https://floating-ui.com/docs/middleware#data),
you can access the [.then(...)](#then) which works in the same way as their documentation.

So you can go wild🦒

```html

import floatingUI, { ... } from 'floating-runes'

const float = floatingUI({
placement: 'top',
middleware: [
...
]
}).then(computedData => {
const { middlewareData } = computedData
...
})

```


#### Bonus

As a bonus, you can use `portal` to move an element to another (such as the body).

When the component is destroyed, the element that was portalled, will naturally, also get destroyed.

```html

import { portal } from 'floating-runes'

I'm in the body😏

I'm in another element

```




### Options

#### floatingUI

**FloatingRuneOptions** extends [ComputePositionConfig](https://floating-ui.com/docs/computeposition#options)

| Property | Type | Description |
| --- | --- | --- |
| middleware? | [Middleware](https://floating-ui.com/docs/middleware)[] | Array of middleware objects to modify the positioning or provide data for rendering |
| platform? | [Platform](https://floating-ui.com/docs/platform) | Custom or extended platform object |
| placement? | `\| 'top' `
`\| 'top-start' `
`\| 'top-end' `
`\| 'right' `
`\| 'right-start' `
`\| 'right-end' `
`\| 'bottom' `
`\| 'bottom-start' `
`\| 'bottom-end' `
`\| 'left' `
`\| 'left-start' `
`\| 'left-end'` | Where to place the floating element relative to its reference element
**Default**: `'bottom'` |
| strategy? | `'absolute' \| 'fixed'` | The type of CSS position property to use
**Default**: `absolute` |
| autoUpdate? | [AutoUpdateOptions](https://floating-ui.com/docs/autoUpdate#options) | Whether or not to auto-update the floating element's position |
| autoPosition? | `boolean` | Whether or not to auto-position the floating element and the arrow, and auto-assign the `position:` to the strategy (absolute/fixed)
**Default**: `true` |

> [!NOTE]
> The `arrow` middleware does not take an `element` property. Instead apply the Svelte action `use:float.arrow`

##### `.then(...)`

Read more about
const float = floatingUI(...).then((data: ComputePositionReturn) => void)

##### `float.referenced`, `float.tethered` and `float.attached`

The element that has been referenced to, or tethered to. Attached will return `tethered ?? referenced`


#### float

`use:float`

This Svelte action creates a floater, that floats relative to the reference- and tethered element.

`use:float={FloatOptions}`

| Property | Type | Description |
| --- | --- | --- |
| `tether` | `boolean` | Whether-to-tether.
**Default**: `true` |
| `untether` | `boolean` | If `false` it will stick to the last tethered target,
instead of going back to the reference.
**Default**: `true` |


#### `float.arrow`

`use:float.arrow`

This Svelte action creates reference to the element that serves as the arrow to a `use:float` element. Must be a direct child.

```html


...
...

```

> [!TIP]
> Remember to include the `arrow` middleware,
> and **put it after other middlewares if needed**.


#### `float.ref` and `float.tether`

`use:float.ref` and `use:float.tether`

These Svelte actions sets the reference point for the `use:float` element.

Additionally, they accept a trigger parameter: A conditional callback (`() => boolean`) or an event (keyof WindowEventMap).

Ex.

`use:float.ref={() => url === href}`

or

`use:float.tether={'pointerenter'}`


#### `float.untether`

`float.untether` removes the tethering, so that the floating element will return to the reference (unless `untether: false` is provided).

It can be used directly: `float.untether()`

Or like `float.ref` and `float.tether` have a condition to trigger;

Ex.

`use:float.untether={() => condition}`

or

`use:float.untether={'pointerleave'}`