Skip to content

Commit

Permalink
feat(editor): 新增Layout
Browse files Browse the repository at this point in the history
  • Loading branch information
roymondchen authored and jia000 committed Sep 16, 2022
1 parent 22c57f4 commit 835189a
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 167 deletions.
2 changes: 0 additions & 2 deletions packages/editor/src/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,6 @@ export default defineComponent({
},
);
uiService.initColumnWidth();
onUnmounted(() => {
editorService.destroy();
historyService.destroy();
Expand Down
129 changes: 74 additions & 55 deletions packages/editor/src/layouts/Framework.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,77 +10,96 @@
@save="saveCode"
></magic-code-editor>

<div class="m-editor-content" v-else>
<div class="m-editor-framework-left" :style="`width: ${columnWidth?.left}px`">
<layout
v-else
class="m-editor-content"
left-class="m-editor-framework-left"
center-class="m-editor-framework-center"
right-class="m-editor-framework-right"
v-model:left="columnWidth.left"
v-model:right="columnWidth.right"
:min-left="45"
:min-right="1"
@change="columnWidthChange"
>
<template #left>
<slot name="sidebar"></slot>
</div>

<resizer type="left"></resizer>

<template v-if="pageLength > 0">
<div class="m-editor-framework-center" :style="`width: ${columnWidth?.center}px`">
<slot name="workspace"></slot>
</div>

<resizer type="right"></resizer>
</template>

<div class="m-editor-framework-right" :style="`width: ${columnWidth?.right}px`">
<el-scrollbar>
<slot name="props-panel"></slot>
</el-scrollbar>
</div>
<template #center>
<slot v-if="pageLength > 0" name="workspace"></slot>
<slot v-else name="empty">
<add-page-box></add-page-box>
</slot>
</template>

<slot v-else name="empty">
<add-page-box></add-page-box>
</slot>
</div>
<template v-if="pageLength > 0" #right>
<el-scrollbar>
<slot name="props-panel"></slot>
</el-scrollbar>
</template>
</layout>
</div>
</template>

<script lang="ts">
import { computed, defineComponent, inject } from 'vue';
<script lang="ts" setup>
import { computed, inject, ref } from 'vue';
import type { MApp } from '@tmagic/schema';
import { GetColumnWidth, Services } from '../type';
import AddPageBox from './AddPageBox.vue';
import Resizer from './Resizer.vue';
import Layout from './Layout.vue';
export default defineComponent({
components: {
AddPageBox,
Resizer,
},
const DEFAULT_LEFT_COLUMN_WIDTH = 310;
const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
props: {
codeOptions: {
type: Object,
default: () => ({}),
},
withDefaults(
defineProps<{
codeOptions?: Record<string, any>;
}>(),
{
codeOptions: () => ({}),
},
);
setup() {
const { editorService, uiService } = inject<Services>('services') || {};
const root = computed(() => editorService?.get<MApp>('root'));
return {
root,
pageLength: computed(() => editorService?.get<number>('pageLength') || 0),
showSrc: computed(() => uiService?.get<boolean>('showSrc')),
columnWidth: computed(() => uiService?.get<GetColumnWidth>('columnWidth')),
saveCode(value: string) {
try {
// eslint-disable-next-line no-eval
editorService?.set('root', eval(value));
} catch (e: any) {
console.error(e);
}
},
};
},
const { editorService, uiService } = inject<Services>('services') || {};
const root = computed(() => editorService?.get<MApp>('root'));
const pageLength = computed(() => editorService?.get<number>('pageLength') || 0);
const showSrc = computed(() => uiService?.get<boolean>('showSrc'));
const columnWidth = ref({
left: DEFAULT_LEFT_COLUMN_WIDTH,
center: globalThis.document.body.clientWidth - DEFAULT_LEFT_COLUMN_WIDTH - DEFAULT_RIGHT_COLUMN_WIDTH,
right: DEFAULT_RIGHT_COLUMN_WIDTH,
});
uiService?.set('columnWidth', columnWidth.value);
const saveCode = (value: string) => {
try {
// eslint-disable-next-line no-eval
editorService?.set('root', eval(value));
} catch (e: any) {
console.error(e);
}
};
const COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorColumnWidthData';
const columnWidthCacheData = globalThis.localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY);
if (columnWidthCacheData) {
try {
const columnWidthCache = JSON.parse(columnWidthCacheData);
columnWidth.value = columnWidthCache;
} catch (e) {
console.error(e);
}
}
const columnWidthChange = (columnWidth: GetColumnWidth) => {
uiService?.set('columnWidth', columnWidth);
globalThis.localStorage.setItem(COLUMN_WIDTH_STORAGE_KEY, JSON.stringify(columnWidth));
};
</script>
100 changes: 100 additions & 0 deletions packages/editor/src/layouts/Layout.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<template>
<div ref="el">
<template v-if="typeof props.left !== 'undefined'">
<div class="m-editor-layout-left" :class="leftClass" :style="`width: ${left}px`">
<slot name="left"></slot>
</div>
<Resizer @change="changeLeft"></Resizer>
</template>

<div class="m-editor-layout-center" :class="centerClass" :style="`width: ${center}px`">
<slot name="center"></slot>
</div>

<template v-if="typeof props.right !== 'undefined'">
<Resizer @change="changeRight"></Resizer>
<div class="m-editor-layout-right" :class="rightClass" :style="`width: ${right}px`">
<slot name="right"></slot>
</div>
</template>
</div>
</template>

<script lang="ts" setup>
import { onMounted, onUnmounted, ref } from 'vue';
import Resizer from './Resizer.vue';
const emit = defineEmits(['update:left', 'change', 'update:right']);
const props = withDefaults(
defineProps<{
left?: number;
right?: number;
minLeft?: number;
minRight?: number;
leftClass?: string;
rightClass?: string;
centerClass?: string;
}>(),
{
minLeft: 1,
minRight: 1,
},
);
const el = ref<HTMLElement>();
let clientWidth = 0;
const resizerObserver = new ResizeObserver((entries) => {
for (const { contentRect } of entries) {
clientWidth = contentRect.width;
center.value = clientWidth - (props.left || 0) - (props.right || 0);
emit('change', {
left: props.left,
center: center.value,
right: props.right,
});
}
});
onMounted(() => {
if (el.value) {
resizerObserver.observe(el.value);
}
});
onUnmounted(() => {
resizerObserver.disconnect();
});
const center = ref(0);
const changeLeft = (deltaX: number) => {
if (typeof props.left === 'undefined') return;
const left = Math.max(props.left + deltaX, props.minLeft) || 0;
emit('update:left', left);
center.value = clientWidth - left - (props.right || 0);
emit('change', {
left,
center: center.value,
right: props.right,
});
};
const changeRight = (deltaX: number) => {
if (typeof props.right === 'undefined') return;
const right = Math.max(props.right - deltaX, props.minRight) || 0;
emit('update:right', right);
center.value = clientWidth - (props.left || 0) - right;
emit('change', {
left: props.left,
center: center.value,
right,
});
};
</script>
63 changes: 17 additions & 46 deletions packages/editor/src/layouts/Resizer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,29 @@
</span>
</template>

<script lang="ts">
import { defineComponent, inject, onMounted, onUnmounted, ref, toRaw } from 'vue';
<script lang="ts" setup>
import { onMounted, onUnmounted, ref } from 'vue';
import Gesto from 'gesto';
import { Services } from '../type';
const emit = defineEmits(['change']);
export default defineComponent({
name: 'm-editor-resize',
const target = ref<HTMLSpanElement>();
props: {
type: {
type: String,
},
},
let getso: Gesto;
setup(props) {
const services = inject<Services>('services');
onMounted(() => {
if (!target.value) return;
getso = new Gesto(target.value, {
container: window,
pinchOutside: true,
}).on('drag', (e) => {
if (!target.value) return;
const target = ref<HTMLSpanElement>();
let getso: Gesto;
onMounted(() => {
if (!target.value) return;
getso = new Gesto(target.value, {
container: window,
pinchOutside: true,
}).on('drag', (e) => {
if (!target.value || !services) return;
let { left, right } = {
...toRaw(services.uiService.get('columnWidth')),
};
if (props.type === 'left') {
left += e.deltaX;
} else if (props.type === 'right') {
right -= e.deltaX;
}
services.uiService.set('columnWidth', {
left,
right,
});
});
});
onUnmounted(() => {
getso?.unset();
});
emit('change', e.deltaX);
});
});
return {
target,
};
},
onUnmounted(() => {
getso?.unset();
});
</script>
Loading

0 comments on commit 835189a

Please sign in to comment.