From a6322fa0238f4c692fc60b64d7cfead6d1e73d5a Mon Sep 17 00:00:00 2001 From: Ryan Wang Date: Fri, 4 Jul 2025 12:31:41 +0800 Subject: [PATCH] fix: prevent code input content from being obscured in fullscreen mode (#7599) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /area ui /kind bug /milestone 2.21.x #### What this PR does / why we need it: Prevent code input content from being obscured in fullscreen mode #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/7574 #### Does this PR introduce a user-facing change? ```release-note 修复代码输入框在全屏时,底部内容被遮挡的问题。 ``` --- ui/src/components/codemirror/Codemirror.vue | 33 +++++++++++++++------ ui/src/formkit/inputs/code/CodeInput.vue | 12 +++++++- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/ui/src/components/codemirror/Codemirror.vue b/ui/src/components/codemirror/Codemirror.vue index c675c667f..55bbcc49a 100644 --- a/ui/src/components/codemirror/Codemirror.vue +++ b/ui/src/components/codemirror/Codemirror.vue @@ -6,7 +6,7 @@ import { json } from "@codemirror/lang-json"; import { LanguageSupport, StreamLanguage } from "@codemirror/language"; import { yaml } from "@codemirror/legacy-modes/mode/yaml"; import type { EditorStateConfig } from "@codemirror/state"; -import { EditorState } from "@codemirror/state"; +import { Compartment, EditorState } from "@codemirror/state"; import { EditorView } from "@codemirror/view"; import { basicSetup } from "codemirror"; import { onBeforeUnmount, onMounted, shallowRef, watch } from "vue"; @@ -42,17 +42,21 @@ const emit = defineEmits<{ (e: "change", value: string): void; }>(); -const customTheme = EditorView.theme({ - "&": { - height: props.height, - width: "100%", - }, -}); - const wrapper = shallowRef(); const cmState = shallowRef(); const cmView = shallowRef(); +const themeCompartment = new Compartment(); + +const createCustomTheme = (height: string) => { + return EditorView.theme({ + "&": { + height, + width: "100%", + }, + }); +}; + const createCmEditor = () => { const language = typeof props.language === "string" @@ -62,7 +66,7 @@ const createCmEditor = () => { let extensions = [ basicSetup, EditorView.lineWrapping, - customTheme, + themeCompartment.of(createCustomTheme(props.height)), language, EditorView.updateListener.of((viewUpdate) => { if (viewUpdate.docChanged) { @@ -106,6 +110,17 @@ onMounted(() => { } } ); + + watch( + () => props.height, + (newHeight) => { + if (cmView.value) { + cmView.value.dispatch({ + effects: themeCompartment.reconfigure(createCustomTheme(newHeight)), + }); + } + } + ); }); // Destroy codemirror editor when component unmounts diff --git a/ui/src/formkit/inputs/code/CodeInput.vue b/ui/src/formkit/inputs/code/CodeInput.vue index 592c4c19c..2551442bd 100644 --- a/ui/src/formkit/inputs/code/CodeInput.vue +++ b/ui/src/formkit/inputs/code/CodeInput.vue @@ -31,6 +31,15 @@ useEventListener(codeInputWrapperRef, "keydown", (e: KeyboardEvent) => { fullscreen.value = false; } }); + +const editorHeight = computed(() => { + if (fullscreen.value) { + // VPageHeader height is 3.5rem + return "calc(100vh - 3.5rem)"; + } + + return "100%"; +});