mirror of https://github.com/halo-dev/halo
pref: improve code block styling in editor (#6089)
#### What type of PR is this? /kind improvement /area editor #### What this PR does / why we need it: 优化编辑器代码块样式。 before: <img width="907" alt="image" src="https://github.com/halo-dev/halo/assets/31335418/11ad91a9-75ce-42ec-a947-effca7b42f30"> after: <img width="932" alt="image" src="https://github.com/halo-dev/halo/assets/31335418/d0b3275b-a269-4104-aea8-0d8726ce32e7"> #### How to test it? 测试复制功能是否正常。 #### Does this PR introduce a user-facing change? ```release-note 优化默认编辑器代码块样式 ```pull/6081/head
parent
10f3157258
commit
1e37768b35
|
@ -4,6 +4,10 @@ import type { Editor, Node } from "@/tiptap/vue-3";
|
|||
import { NodeViewContent, NodeViewWrapper } from "@/tiptap/vue-3";
|
||||
import lowlight from "./lowlight";
|
||||
import { computed } from "vue";
|
||||
import BxBxsCopy from "~icons/bx/bxs-copy";
|
||||
import IconCheckboxCircle from "~icons/ri/checkbox-circle-line";
|
||||
import { useTimeout } from "@vueuse/core";
|
||||
import { i18n } from "@/locales";
|
||||
|
||||
const props = defineProps<{
|
||||
editor: Editor;
|
||||
|
@ -28,24 +32,53 @@ const selectedLanguage = computed({
|
|||
props.updateAttributes({ language: language });
|
||||
},
|
||||
});
|
||||
|
||||
const { ready, start } = useTimeout(2000, { controls: true, immediate: false });
|
||||
|
||||
const handleCopyCode = () => {
|
||||
if (!ready.value) return;
|
||||
const code = props.node.textContent;
|
||||
navigator.clipboard.writeText(code).then(() => {
|
||||
start();
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<node-view-wrapper as="div" class="code-node">
|
||||
<div class="py-1.5">
|
||||
<select
|
||||
v-model="selectedLanguage"
|
||||
contenteditable="false"
|
||||
class="block px-2 py-1.5 text-sm text-gray-900 border border-gray-300 rounded-md bg-gray-50 focus:ring-blue-500 focus:border-blue-500"
|
||||
>
|
||||
<option :value="null">auto</option>
|
||||
<option
|
||||
v-for="(language, index) in languages"
|
||||
:key="index"
|
||||
:value="language"
|
||||
<node-view-wrapper as="div" class="code-node border-[1px] rounded mt-3">
|
||||
<div
|
||||
class="bg-neutral-100 border-b-[1px] border-b-gray-100 py-1 flex items-center justify-between rounded-t"
|
||||
>
|
||||
<div class="flex-1 flex items-center pl-3">
|
||||
<select
|
||||
v-model="selectedLanguage"
|
||||
contenteditable="false"
|
||||
class="block !leading-8 text-sm text-gray-900 border select-none border-transparent rounded-md bg-transparent focus:ring-blue-500 focus:border-blue-500 cursor-pointer hover:bg-zinc-200"
|
||||
>
|
||||
{{ language }}
|
||||
</option>
|
||||
</select>
|
||||
<option :value="null">auto</option>
|
||||
<option
|
||||
v-for="(language, index) in languages"
|
||||
:key="index"
|
||||
:value="language"
|
||||
>
|
||||
{{ language }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="pr-3 flex items-center">
|
||||
<div
|
||||
v-tooltip="
|
||||
ready
|
||||
? i18n.global.t('editor.common.codeblock.copy_code')
|
||||
: i18n.global.t('editor.common.codeblock.copy_code_success')
|
||||
"
|
||||
class="w-8 h-8 cursor-pointer rounded flex items-center justify-center"
|
||||
:class="{ 'hover:bg-zinc-200': ready }"
|
||||
@click="handleCopyCode"
|
||||
>
|
||||
<IconCheckboxCircle v-if="!ready" class="w-4 h-4 text-green-500" />
|
||||
<BxBxsCopy v-else class="w-4 h-4 text-gray-500" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<pre><node-view-content as="code" class="hljs" /></pre>
|
||||
</node-view-wrapper>
|
||||
|
|
|
@ -205,7 +205,7 @@ export default CodeBlockLowlight.extend<
|
|||
editor,
|
||||
isActive: editor.isActive("codeBlock"),
|
||||
icon: markRaw(MdiCodeBracesBox),
|
||||
title: i18n.global.t("editor.common.codeblock"),
|
||||
title: i18n.global.t("editor.common.codeblock.title"),
|
||||
action: () => editor.chain().focus().toggleCodeBlock().run(),
|
||||
},
|
||||
};
|
||||
|
@ -214,7 +214,7 @@ export default CodeBlockLowlight.extend<
|
|||
return {
|
||||
priority: 80,
|
||||
icon: markRaw(MdiCodeBracesBox),
|
||||
title: "editor.common.codeblock",
|
||||
title: "editor.common.codeblock.title",
|
||||
keywords: ["codeblock", "daimakuai"],
|
||||
command: ({ editor, range }: { editor: Editor; range: Range }) => {
|
||||
editor.chain().focus().deleteRange(range).setCodeBlock().run();
|
||||
|
@ -229,7 +229,7 @@ export default CodeBlockLowlight.extend<
|
|||
props: {
|
||||
editor,
|
||||
icon: markRaw(MdiCodeBracesBox),
|
||||
title: i18n.global.t("editor.common.codeblock"),
|
||||
title: i18n.global.t("editor.common.codeblock.title"),
|
||||
action: () => {
|
||||
editor.chain().focus().setCodeBlock().run();
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@ import "./styles/index.scss";
|
|||
import "./styles/tailwind.css";
|
||||
import "floating-vue/dist/style.css";
|
||||
import "github-markdown-css/github-markdown-light.css";
|
||||
import "highlight.js/styles/github-dark.css";
|
||||
import "highlight.js/styles/github.css";
|
||||
|
||||
const plugin: Plugin = {
|
||||
install(app: App) {
|
||||
|
|
|
@ -104,7 +104,10 @@ editor:
|
|||
code: Code
|
||||
superscript: Super Script
|
||||
subscript: Sub Script
|
||||
codeblock: Code block
|
||||
codeblock:
|
||||
title: Code block
|
||||
copy_code: Copy code
|
||||
copy_code_success: Copy success
|
||||
image: Image
|
||||
heading:
|
||||
title: Text type
|
||||
|
|
|
@ -104,7 +104,10 @@ editor:
|
|||
code: 行内代码
|
||||
superscript: 上角标
|
||||
subscript: 下角标
|
||||
codeblock: 代码块
|
||||
codeblock:
|
||||
title: 代码块
|
||||
copy_code: 复制代码
|
||||
copy_code_success: 复制成功
|
||||
image: 图片
|
||||
heading:
|
||||
title: 文本类型
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
}
|
||||
|
||||
pre {
|
||||
background: #0d0d0d;
|
||||
background-color: transparent;
|
||||
padding: 0.75rem 1rem;
|
||||
margin: 0;
|
||||
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
@import "./columns.scss";
|
||||
@import "./search.scss";
|
||||
@import "./format-brush.scss";
|
||||
@import "./node-select.scss";
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
.halo-rich-text-editor {
|
||||
$editorNodeCardBorderSelected: rgba(47, 142, 244);
|
||||
|
||||
.has-node-selected {
|
||||
&.code-node {
|
||||
border-color: $editorNodeCardBorderSelected;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue