livewire 에서 alpinejs 로 popper.js 사용하기

Updated on

livewire 에서 blade 템플릿으로 alpinejs 를 사용하면서 popper.js 를 사용하는 방법이다.

app.css
#tooltip {
    display: none;
}

#tooltip[data-show] {
    display: block;
}

#arrow,
#arrow::before {
    position: absolute;
    width: 8px;
    height: 8px;
    background: inherit;
}

#arrow {
    visibility: hidden;
}

#arrow::before {
    visibility: visible;
    content: '';
    transform: rotate(45deg);
}

#tooltip[data-popper-placement^='top'] > #arrow {
    bottom: -4px;
}

#tooltip[data-popper-placement^='bottom'] > #arrow {
    top: -4px;
}

#tooltip[data-popper-placement^='left'] > #arrow {
    right: -4px;
}

#tooltip[data-popper-placement^='right'] > #arrow {
    left: -4px;
}
app.js
import './bootstrap';
import { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';
import { createPopper } from '@popperjs/core';

import.meta.glob([
  '../assets/**',
  '../images/**',
  '../fonts/**',
]);

// Initialize popper.js tooltip functionality
document.addEventListener("alpine:init", () => {
  Alpine.data("popperTooltip", (options = {}) => ({
      init() {
          this.$nextTick(() => {
              const popperOptions = {
                  ...options
              };
              this.popper = createPopper(this.$el, this.$refs.tooltip,
                  popperOptions);
          });
      },

      show() {
          this.$refs
              .tooltip.setAttribute("data-show", "");

          this.popper.setOptions((options) => ({
              ...options,
              modifiers: [
                  ...options.modifiers,
                  {
                      name: "eventListeners",
                      enabled: true
                  }
              ]
          }));

          this.popper.update();
      },

      hide() {
          this.$refs
              .tooltip.removeAttribute("data-show");

          this.popper.setOptions((options) => ({
              ...options,
              modifiers: [
                  ...options.modifiers,
                  {
                      name: "eventListeners",
                      enabled: false
                  }
              ]
          }));
      }
  }));
});

Livewire.start()
<div x-data="popperTooltip({
		modifiers: [{
				name: 'offset',
				options: {
						offset: [0, 8]
				}
		}]
})" @mouseenter="show" @mouseleave="hide">
		<a href="https://ggami.net" target="_blank" rel="noopener noreferrer"
				class="text-main-base hover:text-main-base flex items-center rounded-full p-1 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-500">
				<span class="sr-only">Open blog</span>
				<x-svg.icon class="size-6" />
		</a>
		<div x-ref="tooltip" class="z-10 rounded bg-gray-900 px-2 py-1 text-sm text-white shadow-md"
				id="tooltip">
				블로그 이동
				<div id="arrow" data-popper-arrow></div>
		</div>
</div>

이렇게 사용 할 수 있고, popperTooltip 로 재사용하여 다른 곳에서도 언제든지 사용 할 수 있다.