QuickConfirm.vue 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. <script setup lang="ts">
  2. import { ref } from "vue";
  3. defineProps({
  4. placement: { type: String, default: "top" }
  5. });
  6. const emit = defineEmits(["confirm"]);
  7. const clickedOnce = ref(false);
  8. const body = ref(document.body);
  9. const quickConfirm = ref();
  10. const confirm = event => {
  11. if (
  12. !event ||
  13. event.type !== "click" ||
  14. event.altKey ||
  15. event.ctrlKey ||
  16. event.metaKey
  17. )
  18. return;
  19. clickedOnce.value = false;
  20. emit("confirm");
  21. setTimeout(() => {
  22. quickConfirm.value?.tippy.hide();
  23. }, 25);
  24. };
  25. const click = event => {
  26. if (clickedOnce.value) confirm(event);
  27. else clickedOnce.value = true;
  28. };
  29. const shiftClick = event => {
  30. confirm(event);
  31. };
  32. const delayedHide = () => {
  33. setTimeout(() => {
  34. clickedOnce.value = false;
  35. }, 25);
  36. };
  37. </script>
  38. <template>
  39. <tippy
  40. :interactive="true"
  41. :touch="true"
  42. :placement="placement"
  43. theme="quickConfirm"
  44. ref="quickConfirm"
  45. trigger="click"
  46. :append-to="body"
  47. @hide="delayedHide()"
  48. >
  49. <div
  50. @click.shift.stop="shiftClick($event)"
  51. @click.exact="click($event)"
  52. >
  53. <slot ref="trigger" />
  54. </div>
  55. <template #content>
  56. <a @click="confirm($event)"> Click to Confirm </a>
  57. </template>
  58. </tippy>
  59. </template>