|
1 | 1 | <script setup lang="ts"> |
2 | 2 | import type { DevToolsLogEntry, DevToolsLogEntryFrom, DevToolsLogLevel } from '@vitejs/devtools-kit' |
3 | 3 | import type { DocksContext } from '@vitejs/devtools-kit/client' |
4 | | -import { useTimeAgo } from '@vueuse/core' |
| 4 | +import { useClipboard, useTimeAgo } from '@vueuse/core' |
5 | 5 | import { computed, onMounted, ref } from 'vue' |
6 | 6 | import { markLogsAsRead, useLogs } from '../../state/logs' |
7 | 7 | import FilterToggles from '../display/FilterToggles.vue' |
@@ -162,6 +162,7 @@ const selectedEntry = computed(() => { |
162 | 162 | }) |
163 | 163 |
|
164 | 164 | const selectedTimeAgo = useTimeAgo(computed(() => selectedEntry.value?.timestamp ?? Date.now())) |
| 165 | +const { copy: copyStacktrace, copied: stacktraceCopied } = useClipboard() |
165 | 166 |
|
166 | 167 | async function openFile(entry: DevToolsLogEntry) { |
167 | 168 | if (!entry.filePosition) |
@@ -410,7 +411,19 @@ onMounted(() => { |
410 | 411 | <div class="op50 text-xs mb-1"> |
411 | 412 | Stack Trace |
412 | 413 | </div> |
413 | | - <pre class="text-xs bg-gray/5 rounded p-2 of-x-auto whitespace-pre-wrap font-mono">{{ selectedEntry.stacktrace }}</pre> |
| 414 | + <div class="group relative"> |
| 415 | + <pre class="text-xs bg-gray/5 rounded p-2 of-x-auto whitespace-pre-wrap font-mono">{{ selectedEntry.stacktrace }}</pre> |
| 416 | + <button |
| 417 | + class="group/bt absolute top-1.5 right-1.5 op0 group-hover:op100 p-1 rounded bg-base border border-base transition" |
| 418 | + title="Copy" |
| 419 | + @click="copyStacktrace(selectedEntry.stacktrace)" |
| 420 | + > |
| 421 | + <div |
| 422 | + :class="stacktraceCopied ? 'i-ph:check' : 'i-ph:copy'" |
| 423 | + class="op50 group-hover/bt:op100 size-3.5" |
| 424 | + /> |
| 425 | + </button> |
| 426 | + </div> |
414 | 427 | </div> |
415 | 428 |
|
416 | 429 | <!-- Timers --> |
|
0 commit comments