mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-05-19 03:49:31 +08:00
feat(editor): 代码块编辑区改为使用弹窗,代码块slot完善
This commit is contained in:
parent
0c2c33f854
commit
f1242ee3f4
@ -47,9 +47,6 @@
|
|||||||
<template #props-panel-header>
|
<template #props-panel-header>
|
||||||
<slot name="props-panel-header"></slot>
|
<slot name="props-panel-header"></slot>
|
||||||
</template>
|
</template>
|
||||||
<template #props-panel-code-block>
|
|
||||||
<slot name="props-panel-code-block"></slot>
|
|
||||||
</template>
|
|
||||||
</props-panel>
|
</props-panel>
|
||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="m-editor-props-panel">
|
<div class="m-editor-props-panel">
|
||||||
<slot name="props-panel-header"></slot>
|
<slot name="props-panel-header"></slot>
|
||||||
<slot name="props-panel-code-block">
|
|
||||||
<code-block-editor />
|
|
||||||
</slot>
|
|
||||||
<m-form
|
<m-form
|
||||||
ref="configForm"
|
ref="configForm"
|
||||||
:class="`m-editor-props-panel ${propsPanelSize}`"
|
:class="`m-editor-props-panel ${propsPanelSize}`"
|
||||||
@ -26,8 +23,6 @@ import type StageCore from '@tmagic/stage';
|
|||||||
|
|
||||||
import type { Services } from '../type';
|
import type { Services } from '../type';
|
||||||
|
|
||||||
import CodeBlockEditor from './sidebar/code-block/CodeBlockEditor.vue';
|
|
||||||
|
|
||||||
const emit = defineEmits(['mounted']);
|
const emit = defineEmits(['mounted']);
|
||||||
|
|
||||||
const internalInstance = getCurrentInstance();
|
const internalInstance = getCurrentInstance();
|
||||||
|
@ -30,6 +30,11 @@
|
|||||||
<component v-else-if="config.slots?.layerPanelHeader" :is="config.slots.layerPanelHeader" />
|
<component v-else-if="config.slots?.layerPanelHeader" :is="config.slots.layerPanelHeader" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #code-block-panel-header v-if="data === 'code-block' || config.slots?.codeBlockPanelHeader">
|
||||||
|
<slot v-if="data === 'code-block'" name="code-block-panel-header"></slot>
|
||||||
|
<component v-else-if="config.slots?.codeBlockPanelHeader" :is="config.slots.codeBlockPanelHeader" />
|
||||||
|
</template>
|
||||||
|
|
||||||
<template
|
<template
|
||||||
#layer-node-content="{ data: nodeData, node }"
|
#layer-node-content="{ data: nodeData, node }"
|
||||||
v-if="data === 'layer' || config.slots?.layerNodeContent"
|
v-if="data === 'layer' || config.slots?.layerNodeContent"
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="codeBlockEditor" class="m-editor-code-block-editor-panel" v-if="state.isShowCodeBlockEditor">
|
<el-dialog v-model="state.isShowCodeBlockEditor" title="代码块编辑面板" :fullscreen="true">
|
||||||
<div class="header">
|
<div ref="codeBlockEditor" class="m-editor-code-block-editor-panel">
|
||||||
<h3 class="title">代码块编辑面板</h3>
|
<el-row class="code-name-wrapper" justify="start">
|
||||||
<el-button class="close-btn" circle :icon="Close" type="danger" bg :text="false" @click="closePanel"></el-button>
|
<el-col :span="2">
|
||||||
</div>
|
|
||||||
<el-row :gutter="20" class="code-name-wrapper">
|
|
||||||
<el-col :span="6">
|
|
||||||
<span>代码块名称</span>
|
<span>代码块名称</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-input size="small" v-model="state.codeConfig.name" />
|
<el-input size="small" v-model="state.codeConfig.name" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="m-editor-content" :class="isFullScreen ? 'fullScreen' : 'normal'">
|
<div class="m-editor-content">
|
||||||
<magic-code-editor
|
<magic-code-editor
|
||||||
ref="codeEditor"
|
ref="codeEditor"
|
||||||
class="m-editor-content"
|
class="m-editor-content"
|
||||||
@ -25,27 +22,23 @@
|
|||||||
}"
|
}"
|
||||||
></magic-code-editor>
|
></magic-code-editor>
|
||||||
<div class="m-editor-content-bottom clearfix">
|
<div class="m-editor-content-bottom clearfix">
|
||||||
<el-button type="primary" class="button" @click="toggleFullScreen">
|
|
||||||
{{ isFullScreen ? '退出全屏' : '全屏' }}
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" class="button" @click="saveCode">保存</el-button>
|
<el-button type="primary" class="button" @click="saveCode">保存</el-button>
|
||||||
|
<el-button type="primary" class="button" @click="saveAndClose">保存并关闭</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { inject, ref, watchEffect } from 'vue';
|
import { inject, ref, watchEffect } from 'vue';
|
||||||
import { Close } from '@element-plus/icons-vue';
|
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
import type { Services } from '../type';
|
import type { Services } from '../../../type';
|
||||||
|
|
||||||
import useCodeBlock from './useCodeBlock';
|
import useCodeBlock from './useCodeBlock';
|
||||||
|
|
||||||
const { state, closePanel } = useCodeBlock();
|
const { state, closePanel } = useCodeBlock();
|
||||||
let parentElement: HTMLElement | null = null;
|
|
||||||
const isFullScreen = ref(false);
|
|
||||||
const codeBlockEditor = ref<HTMLElement | null>(null);
|
const codeBlockEditor = ref<HTMLElement | null>(null);
|
||||||
const codeEditor = ref<any | null>(null);
|
const codeEditor = ref<any | null>(null);
|
||||||
const services = inject<Services>('services');
|
const services = inject<Services>('services');
|
||||||
@ -55,28 +48,13 @@ watchEffect(() => {
|
|||||||
if (!codeBlockEditor.value) {
|
if (!codeBlockEditor.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
parentElement = codeBlockEditor.value.parentElement;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 切换全屏
|
// 保存并关闭
|
||||||
const toggleFullScreen = () => {
|
const saveAndClose = () => {
|
||||||
isFullScreen.value = !isFullScreen.value;
|
saveCode();
|
||||||
|
closePanel();
|
||||||
if (!codeBlockEditor.value) return;
|
|
||||||
if (isFullScreen.value) {
|
|
||||||
globalThis.document.body.appendChild(codeBlockEditor.value);
|
|
||||||
} else if (parentElement) {
|
|
||||||
parentElement.appendChild(codeBlockEditor.value);
|
|
||||||
} else {
|
|
||||||
codeBlockEditor.value.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!codeEditor.value) return;
|
|
||||||
codeEditor.value.focus();
|
|
||||||
codeEditor.value.getEditor().layout();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 保存代码
|
// 保存代码
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="m-editor-code-block-list">
|
<div class="m-editor-code-block-list">
|
||||||
|
<slot name="code-block-panel-header"></slot>
|
||||||
<div class="create-code-button">
|
<div class="create-code-button">
|
||||||
<el-button type="primary" size="small" @click="createCodeBlock">新增代码块</el-button>
|
<el-button type="primary" size="small" @click="createCodeBlock">新增代码块</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -7,10 +8,14 @@
|
|||||||
|
|
||||||
<!-- 代码块列表 -->
|
<!-- 代码块列表 -->
|
||||||
<div class="list-container"></div>
|
<div class="list-container"></div>
|
||||||
|
|
||||||
|
<!-- 代码块编辑区 -->
|
||||||
|
<code-block-editor />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import codeBlockEditor from './CodeBlockEditor.vue';
|
||||||
import useCodeBlock from './useCodeBlock';
|
import useCodeBlock from './useCodeBlock';
|
||||||
const { createCodeBlock } = useCodeBlock();
|
const { createCodeBlock } = useCodeBlock();
|
||||||
</script>
|
</script>
|
||||||
|
@ -19,35 +19,12 @@
|
|||||||
z-index: 10;
|
z-index: 10;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 8px 20px;
|
|
||||||
h3.title {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.close-btn {
|
|
||||||
background: rgb(213, 71, 71);
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.code-name-wrapper {
|
.code-name-wrapper {
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.m-editor-content {
|
|
||||||
&.fullScreen {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.m-editor-content-bottom {
|
.m-editor-content-bottom {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user