Skip to content

Commit e59e631

Browse files
feat: add copy button for Shiki Magic Move code block (#2289)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent dc6b3ae commit e59e631

File tree

4 files changed

+66
-1
lines changed

4 files changed

+66
-1
lines changed

packages/client/builtin/ShikiMagicMove.vue

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import type { KeyedTokensInfo } from 'shiki-magic-move/types'
33
import type { PropType } from 'vue'
44
import { sleep } from '@antfu/utils'
5+
import { useClipboard } from '@vueuse/core'
56
import lz from 'lz-string'
67
import { ShikiMagicMovePrecompiled } from 'shiki-magic-move/vue'
78
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
@@ -43,6 +44,33 @@ const id = makeId()
4344
const stepIndex = ref(0)
4445
const container = ref<HTMLElement>()
4546
47+
const showCopyButton = computed(() => {
48+
if (!configs.codeCopy)
49+
return false
50+
51+
const magicCopy = configs.magicMoveCopy
52+
if (!magicCopy)
53+
return false
54+
55+
if (magicCopy === true || magicCopy === 'always')
56+
return true
57+
58+
if (magicCopy === 'final')
59+
return stepIndex.value === steps.length - 1
60+
61+
return false
62+
})
63+
const { copied, copy } = useClipboard()
64+
65+
function copyCode() {
66+
// Use the code property directly from KeyedTokensInfo
67+
const currentStep = steps[stepIndex.value]
68+
if (!currentStep || !currentStep.code)
69+
return
70+
71+
copy(currentStep.code.trim())
72+
}
73+
4674
// Normalized the ranges, to at least have one range
4775
const ranges = computed(() => props.stepRanges.map(i => i.length ? i : ['all']))
4876
@@ -116,7 +144,7 @@ onMounted(() => {
116144
</script>
117145

118146
<template>
119-
<div ref="container" class="slidev-code-wrapper slidev-code-magic-move relative">
147+
<div ref="container" class="slidev-code-wrapper slidev-code-magic-move relative group">
120148
<div v-if="title" class="slidev-code-block-title">
121149
<TitleIcon :title="title" />
122150
<div class="leading-1em">
@@ -135,6 +163,15 @@ onMounted(() => {
135163
stagger: 1,
136164
}"
137165
/>
166+
<button
167+
v-if="showCopyButton"
168+
class="slidev-code-copy absolute right-0 transition opacity-0 group-hover:opacity-20 hover:!opacity-100"
169+
:class="title ? 'top-10' : 'top-0'"
170+
:title="copied ? 'Copied' : 'Copy'" @click="copyCode()"
171+
>
172+
<ph-check-circle v-if="copied" class="p-2 w-8 h-8" />
173+
<ph-clipboard v-else class="p-2 w-8 h-8" />
174+
</button>
138175
</div>
139176
</template>
140177

packages/parser/src/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export function getDefaultConfig(): SlidevConfig {
3232
drawings: {} as ResolvedDrawingsOptions,
3333
plantUmlServer: 'https://www.plantuml.com/plantuml',
3434
codeCopy: true,
35+
magicMoveCopy: true,
3536
author: '',
3637
record: 'dev',
3738
css: 'unocss',

packages/types/src/frontmatter.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ export interface HeadmatterConfig extends TransitionOptions {
5252
* @default true
5353
*/
5454
codeCopy?: boolean
55+
/**
56+
* Show copy button in magic move code blocks
57+
*
58+
* `'final'` for only show copy button on the final step
59+
* `'always'` or `true` for show copy button on all steps
60+
*
61+
* @default true
62+
*/
63+
magicMoveCopy?: boolean | 'final' | 'always'
5564
/**
5665
* The author of the slides
5766
*/

packages/vscode/schema/headmatter.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,24 @@
174174
"markdownDescription": "Show a copy button in code blocks",
175175
"default": true
176176
},
177+
"magicMoveCopy": {
178+
"anyOf": [
179+
{
180+
"type": "boolean"
181+
},
182+
{
183+
"type": "string",
184+
"const": "final"
185+
},
186+
{
187+
"type": "string",
188+
"const": "always"
189+
}
190+
],
191+
"description": "Show copy button in magic move code blocks\n\n`'final'` for only show copy button on the final step `'always'` or `true` for show copy button on all steps",
192+
"markdownDescription": "Show copy button in magic move code blocks\n\n`'final'` for only show copy button on the final step\n`'always'` or `true` for show copy button on all steps",
193+
"default": true
194+
},
177195
"author": {
178196
"type": "string",
179197
"description": "The author of the slides",

0 commit comments

Comments
 (0)