mirror of https://github.com/halo-dev/halo
78 lines
2.2 KiB
Vue
78 lines
2.2 KiB
Vue
<script lang="ts" setup>
|
|
import type { FormKitFrameworkContext } from "@formkit/core";
|
|
import { VButton, VPageHeader } from "@halo-dev/components";
|
|
import { useEventListener } from "@vueuse/core";
|
|
import { computed, ref, type PropType } from "vue";
|
|
import RiFullscreenLine from "~icons/ri/fullscreen-line";
|
|
|
|
const props = defineProps({
|
|
context: {
|
|
type: Object as PropType<FormKitFrameworkContext>,
|
|
required: true,
|
|
},
|
|
});
|
|
|
|
const codeInputWrapperRef = ref();
|
|
|
|
const language = props.context.language as string;
|
|
|
|
const onChange = (value: string) => {
|
|
props.context.node.input(value);
|
|
};
|
|
|
|
const fullscreen = ref(false);
|
|
|
|
const height = computed(() => {
|
|
return fullscreen.value ? "100%" : (props.context.height as string);
|
|
});
|
|
|
|
useEventListener(codeInputWrapperRef, "keydown", (e: KeyboardEvent) => {
|
|
if (e.key === "Escape" && fullscreen.value) {
|
|
fullscreen.value = false;
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<Suspense>
|
|
<div
|
|
ref="codeInputWrapperRef"
|
|
:style="{ height }"
|
|
:class="{ '!fixed inset-0 z-[999] !block bg-white': fullscreen }"
|
|
class="group relative w-full"
|
|
>
|
|
<VPageHeader v-if="fullscreen" :title="context.label" class="border-b">
|
|
<template #actions>
|
|
<VButton @click="fullscreen = false">
|
|
{{ $t("core.formkit.code.fullscreen.exit") }}
|
|
</VButton>
|
|
</template>
|
|
</VPageHeader>
|
|
|
|
<VCodemirror
|
|
:model-value="props.context._value"
|
|
v-bind="context.attrs"
|
|
height="100%"
|
|
:language="language"
|
|
class="block w-full"
|
|
@change="onChange"
|
|
/>
|
|
|
|
<button
|
|
v-if="!fullscreen"
|
|
v-tooltip="$t('core.formkit.code.fullscreen.enter')"
|
|
class="absolute bottom-2 right-2 inline-flex cursor-pointer items-center justify-center rounded-full bg-primary p-1.5 text-white opacity-0 transition-all hover:!opacity-90 hover:shadow group-hover:opacity-100"
|
|
@click="fullscreen = true"
|
|
>
|
|
<RiFullscreenLine class="text-xs" />
|
|
</button>
|
|
</div>
|
|
|
|
<template #fallback>
|
|
<span class="p-1 text-xs text-gray-400">
|
|
{{ $t("core.common.status.loading") }}...
|
|
</span>
|
|
</template>
|
|
</Suspense>
|
|
</template>
|