feat: playground 支持主题切换

This commit is contained in:
roymondchen 2026-07-22 19:03:05 +08:00
parent 8699dc12af
commit ee5247ca94
6 changed files with 83 additions and 9 deletions

View File

@ -12,7 +12,6 @@ export default {
html,
body,
#app {
--el-color-primary: #0054e1;
padding: 0;
margin: 0;
width: 100%;

View File

@ -0,0 +1,38 @@
<template>
<TMagicForm size="small" label-position="right" style="margin-left: 10px">
<TMagicFormItem label="主题">
<TMagicSelect v-model="theme" size="small" style="width: 150px" @change="themeChange">
<TMagicOption value="default">默认</TMagicOption>
<TMagicOption value="magic-admin">magic-admin</TMagicOption>
</TMagicSelect>
</TMagicFormItem>
</TMagicForm>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { TMagicForm, TMagicFormItem, TMagicOption, TMagicSelect } from '@tmagic/design';
import { DEFAULT_THEME, loadTheme } from '../theme-loader';
const theme = ref(sessionStorage.getItem('tmagic-playground-theme') || DEFAULT_THEME);
const emit = defineEmits<{
change: [theme: string];
}>();
const themeChange = async (value: string) => {
await loadTheme(value);
sessionStorage.setItem('tmagic-playground-theme', value);
emit('change', value);
};
</script>
<style lang="scss">
.m-editor-nav-menu {
.tmagic-design-form-item {
margin-bottom: 0;
}
}
</style>

View File

@ -27,9 +27,7 @@ import editorPlugin from '@tmagic/editor';
import App from './App.vue';
import router from './route';
// import '@tmagic/editor/dist/style.css';
import '@tmagic/editor/dist/themes/magic-admin.css';
import { DEFAULT_THEME, loadTheme } from './theme-loader';
// @ts-ignore
globalThis.MonacoEnvironment = {
@ -51,6 +49,7 @@ globalThis.MonacoEnvironment = {
};
const adapter = sessionStorage.getItem('tmagic-playground-ui-adapter') || 'element-plus';
const theme = sessionStorage.getItem('tmagic-playground-theme') || DEFAULT_THEME;
let adapterModule;
@ -62,9 +61,9 @@ if (adapter === 'tdesign-vue-next') {
adapterModule = import('@tmagic/element-plus-adapter');
}
adapterModule.then((module: any) => {
Promise.all([adapterModule, loadTheme(theme)]).then(([module]) => {
const app = createApp(App);
app.use(router);
app.use(editorPlugin, { ...module.default, flat: true });
app.use(editorPlugin, { ...module.default, flat: theme !== DEFAULT_THEME });
app.mount('#app');
});

View File

@ -11,7 +11,7 @@
:datasource-event-method-list="datasourceEventMethodList"
:datasource-configs="datasourceConfigs"
:datasource-values="datasourceValues"
theme="magic-admin"
:theme="theme"
:component-group-list="componentGroupList"
:datasource-list="datasourceList"
:default-selected="defaultSelected"
@ -69,6 +69,7 @@ import {
import DeviceGroup from '../components/DeviceGroup.vue';
import componentGroupList from '../configs/componentGroupList';
import dsl from '../configs/dsl';
import { DEFAULT_THEME } from '../theme-loader';
import { useEditorContentMenuData } from './composables/use-editor-content-menu-data';
import { useEditorMenu } from './composables/use-editor-menu';
@ -88,8 +89,19 @@ const { contentMenuData } = useEditorContentMenuData();
const editor = shallowRef<InstanceType<typeof TMagicEditor>>();
const value = ref<MApp>();
const theme = ref(sessionStorage.getItem('tmagic-playground-theme') || DEFAULT_THEME);
const defaultSelected = ref(dsl.items[0].id);
const updateThemeVariables = (themeName: string) => {
if (themeName === 'magic-admin') {
document.documentElement.style.setProperty('--el-color-primary', '#0054e1');
} else {
document.documentElement.style.removeProperty('--el-color-primary');
}
};
updateThemeVariables(theme.value);
const stageRect = ref({
width: 375,
height: 817,
@ -108,7 +120,12 @@ const save = () => {
historyService.markSaved('page');
};
const { menu, deviceGroup, iframe, previewVisible } = useEditorMenu(value, save);
const themeChangeHandler = (value: string) => {
theme.value = value;
updateThemeVariables(value);
};
const { menu, deviceGroup, iframe, previewVisible } = useEditorMenu(value, save, themeChangeHandler);
editorService.usePlugin({
beforeDoAdd: (config: MNode, parent: MContainer) => {
@ -193,6 +210,7 @@ onBeforeUnmount(() => {
window.removeEventListener('pagehide', persistHistory);
editorService.removeAllPlugins();
editorService.off('root-change', rootChangeHandler);
document.documentElement.style.removeProperty('--el-color-primary');
});
const propsSubmitErrorHandler = async (e: any) => {

View File

@ -7,9 +7,14 @@ import { type MenuBarData, tMagicMessage, tMagicMessageBox } from '@tmagic/edito
import AdapterSelect from '../../components/AdapterSelect.vue';
import DeviceGroup from '../../components/DeviceGroup.vue';
import ThemeSelect from '../../components/ThemeSelect.vue';
import { uaMap } from '../../const';
export const useEditorMenu = (value: Ref<MApp | undefined>, save: () => void) => {
export const useEditorMenu = (
value: Ref<MApp | undefined>,
save: () => void,
onThemeChange: (theme: string) => void,
) => {
const router = useRouter();
const deviceGroup = shallowRef<InstanceType<typeof DeviceGroup>>();
@ -56,6 +61,13 @@ export const useEditorMenu = (value: Ref<MApp | undefined>, save: () => void) =>
type: 'component',
component: AdapterSelect,
},
{
type: 'component',
component: ThemeSelect,
listeners: {
change: onThemeChange,
},
},
],
center: ['delete', 'undo', 'redo', 'history-list', 'guides', 'rule', 'zoom'],
right: [

View File

@ -0,0 +1,8 @@
export const DEFAULT_THEME = 'magic-admin';
const themeLoaders: Record<string, () => Promise<unknown>> = {
default: () => import('@tmagic/editor/dist/style.css'),
'magic-admin': () => import('@tmagic/editor/dist/themes/magic-admin.css'),
};
export const loadTheme = (theme: string) => themeLoaders[theme]?.() ?? Promise.resolve();