lxsmnsyc / solid-floating-ui

SolidJS bindings for Floating UI
MIT License
82 stars 3 forks source link

update arrow element #5

Open Ladvace opened 1 year ago

Ladvace commented 1 year ago

I was trying to make a tooltip with an arrow, the problem is that arrowRef do not get updated in arrow, is there a way to work around it? what I did to workaround this was to reassign useFloating with arrowRef in a createEffect but this is not really the optimal solution

  createEffect(() => {
if(!arrowRef()) return;
    position = useFloating(elementRef, toolTipRef, {
      placement: props.placement || "top",
      middleware: [
        offset(10),
        flip(),
        shift(),
        hide(),
        size(),
        arrow({ element: arrowRef() as HTMLDivElement }),
      ],

      whileElementsMounted: (reference, floating, update) =>
        autoUpdate(reference, floating, update, {
          animationFrame: true,
        }),
    });
  });
gawdn commented 8 months ago

I had the same issue. I just overwrote the middleware so it takes an accessor instead

const solidArrow = ({
  element,
  padding,
}: {
  element: Accessor<HTMLElement>;
  padding: Padding | undefined;
}): Middleware => ({
  name: "arrow",
  fn(...args) {
    return arrow({
      element: element(),
      padding: padding,
    }).fn(...args);
  },
});

so something like this works nicely:

let referenceRef: HTMLElement;
let tooltipRef: HTMLDivElement;
let tooltipArrow: HTMLDivElement;

const position = useFloating(
    () => referenceRef,
    () => tooltipRef,
    {
      placement: "bottom",
      whileElementsMounted: autoUpdate,
      middleware: [
        flip(),
        offset(floatingOffset()),
        solidArrow({
          element: () => tooltipArrow,
          padding: 8,
        }),
      ],
    }
  );