Skip to content
Snippets Groups Projects
CopyToClipboardIcon.vue 2.21 KiB
Newer Older
  • Learn to ignore specific revisions
  • <script setup lang="ts">
    import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
    import { onMounted } from "vue";
    import { Toast, Tooltip } from "bootstrap";
    
    const props = defineProps<{
      text: string;
    }>();
    
    let successToast: Toast | null = null;
    let failToast: Toast | null = null;
    const randomIDSuffix = Math.random().toString(16).substr(2, 8);
    
    function copyToClipboard() {
      if (!navigator.clipboard) {
        failToast?.show();
      }
      navigator.clipboard
        .writeText(props.text)
        .then(() => {
          successToast?.show();
        })
        .catch(() => {
          failToast?.show();
        });
    }
    
    onMounted(() => {
      new Tooltip("#tooltip-" + randomIDSuffix);
      successToast = new Toast("#successToast-" + randomIDSuffix);
      failToast = new Toast("#failToast-" + randomIDSuffix);
    });
    </script>
    
    <template>
      <div class="toast-container position-fixed top-toast end-0 p-3">
        <div
          role="alert"
          aria-live="assertive"
          aria-atomic="true"
          class="toast text-bg-success align-items-center border-0"
          data-bs-autohide="true"
          :id="'successToast-' + randomIDSuffix"
        >
          <div class="d-flex">
            <div class="toast-body">Successfully copied to clipboard</div>
            <button
              type="button"
              class="btn-close btn-close-white me-2 m-auto"
              data-bs-dismiss="toast"
              aria-label="Close"
            ></button>
          </div>
        </div>
        <div
          role="alert"
          aria-live="assertive"
          aria-atomic="true"
          class="toast text-bg-danger align-items-center border-0"
          data-bs-autohide="true"
          :id="'failToast-' + randomIDSuffix"
        >
          <div class="d-flex">
            <div class="toast-body">Can't copy to clipboard</div>
            <button
              type="button"
              class="btn-close btn-close-white me-2 m-auto"
              data-bs-dismiss="toast"
              aria-label="Close"
            ></button>
          </div>
        </div>
      </div>
      <span
        class="hover-info cursor-pointer"
        data-bs-toggle="tooltip"
        data-bs-title="Copy to Clipboard"
        :id="'tooltip-' + randomIDSuffix"
      >
        <font-awesome-icon icon="fa-solid fa-clipboard" @click="copyToClipboard" />
      </span>
    </template>
    
    <style scoped>
    .hover-info:hover {
      color: var(--bs-info) !important;
    }
    </style>