use:popper action (instead of component based API)
FezVrasta opened this issue · comments
The existing <Popper />
component doesn't feel right, it does absolutely nothing, if not allow the consumers to pass props down and retrieve the result.
The README example could be written as follows and everything would still work:
<Popper
reference={referenceElement}
popper={popperElement}
options={popperOptions}
bind:styles
bind:attributes
/>
<button bind:this={referenceElement}>Reference Element</button>
<div
bind:this={popperElement}
class="tooltip"
style={css(styles.popper)}
{...attributes.popper}>
Popper Element
<div bind:this={arrowElement} class="arrow" style={css(styles.arrow)} />
</div>
A cleaner approach could be the use:action
API.
<script>
let styles = {};
let attributes = {};
</script>
<button
use:popper={{ popperElement, options }}
on:popperUpdate={evt => {
styles = evt.detail.styles;
attributes = evt.detail.attributes;
}}
>
Reference Element
</button>
Here's a basic example:
https://codesandbox.io/s/trusting-butterfly-704gd?file=/popperAction.js
Thoughts?
I just found out about this issue, and I’ve actually just published a package that uses two actions to attach Popper!
https://github.com/bryanmylee/svelte-popperjs
The idea is to wrap both actions in an object such that there is some shared state, then attach Popper there.
For my package, I have a createPopperActions
function which returns two functions – refAction
and popperAction
, that are used on the reference and popper element.
popperAction
takes the popper options config object, and while it doesn’t emit any event to update styles or attributes yet, that is definitely a possibility.
Perhaps that could be of some help!
<script>
import { createPopperActions } from ‘svelte-popperjs’;
const [ popperRef, popperContent ] = createPopperActions();
</script>
<button use:popperRef>
Reference Element
</button>
<div use:popperContent={{ placement: ‘right’ }}>
Popper Element
</div>
Here’s an example of how my package is used.