mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-04-05 19:41:40 +08:00
feat: 完善tdesign-vue-next适配
This commit is contained in:
parent
26835f6a29
commit
ea4af425f3
23
packages/design/src/Badge.vue
Normal file
23
packages/design/src/Badge.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<component class="tmagic-design-badge" :is="uiComponent.component" v-bind="uiProps">
|
||||
<slot></slot>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="TMBadge">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { getConfig } from './config';
|
||||
|
||||
const props = defineProps<{
|
||||
value?: string | number;
|
||||
type?: 'primary' | 'success' | 'warning' | 'danger' | 'info';
|
||||
max?: number;
|
||||
isDot?: boolean;
|
||||
hidden?: boolean;
|
||||
}>();
|
||||
|
||||
const uiComponent = getConfig('components').badge;
|
||||
|
||||
const uiProps = computed(() => uiComponent.props(props));
|
||||
</script>
|
@ -13,6 +13,12 @@
|
||||
<template #append v-if="$slots.append">
|
||||
<slot name="append"></slot>
|
||||
</template>
|
||||
<template #prefix v-if="$slots.prefix">
|
||||
<slot name="prefix"></slot>
|
||||
</template>
|
||||
<template #suffix v-if="$slots.suffix">
|
||||
<slot name="suffix"></slot>
|
||||
</template>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
|
21
packages/design/src/RadioButton.vue
Normal file
21
packages/design/src/RadioButton.vue
Normal file
@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<component class="tmagic-design-radio-button" :is="uiComponent.component" v-bind="uiProps">
|
||||
<slot></slot>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="TMRadioButton">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { getConfig } from './config';
|
||||
|
||||
const props = defineProps<{
|
||||
label?: string | number | boolean;
|
||||
disabled?: boolean;
|
||||
name?: string;
|
||||
}>();
|
||||
|
||||
const uiComponent = getConfig('components').radioButton;
|
||||
|
||||
const uiProps = computed(() => uiComponent.props(props));
|
||||
</script>
|
@ -32,6 +32,7 @@ const props = defineProps<{
|
||||
allowCreate?: boolean;
|
||||
valueKey?: string;
|
||||
remoteMethod?: any;
|
||||
loading?: boolean;
|
||||
size?: 'large' | 'default' | 'small';
|
||||
}>();
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
export default {
|
||||
components: {
|
||||
badge: {
|
||||
component: 'el-badge',
|
||||
props: (props: any) => props,
|
||||
},
|
||||
|
||||
button: {
|
||||
component: 'el-button',
|
||||
props: (props: any) => props,
|
||||
@ -130,6 +135,11 @@ export default {
|
||||
props: (props: any) => props,
|
||||
},
|
||||
|
||||
radioButton: {
|
||||
component: 'el-radio-button',
|
||||
props: (props: any) => props,
|
||||
},
|
||||
|
||||
radioGroup: {
|
||||
component: 'el-radio-group',
|
||||
props: (props: any) => props,
|
||||
|
@ -7,6 +7,7 @@ export * from './type';
|
||||
export * from './config';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
export { default as TMagicBadge } from './Badge.vue';
|
||||
export { default as TMagicButton } from './Button.vue';
|
||||
export { default as TMagicCard } from './Card.vue';
|
||||
export { default as TMagicCascader } from './Cascader.vue';
|
||||
@ -33,6 +34,7 @@ export { default as TMagicOptionGroup } from './OptionGroup.vue';
|
||||
export { default as TMagicPagination } from './Pagination.vue';
|
||||
export { default as TMagicPopover } from './Popover.vue';
|
||||
export { default as TMagicRadio } from './Radio.vue';
|
||||
export { default as TMagicRadioButton } from './RadioButton.vue';
|
||||
export { default as TMagicRadioGroup } from './RadioGroup.vue';
|
||||
export { default as TMagicRow } from './Row.vue';
|
||||
export { default as TMagicScrollbar } from './Scrollbar.vue';
|
||||
@ -95,6 +97,10 @@ export default {
|
||||
tMagicMessageBox.close = options.messageBox?.close;
|
||||
}
|
||||
|
||||
if (options.loading) {
|
||||
app.directive('loading', options.loading);
|
||||
}
|
||||
|
||||
app.config.globalProperties.$MAGIC_DESIGN = options;
|
||||
setConfig(options);
|
||||
},
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { Directive } from 'vue';
|
||||
|
||||
export interface CascaderOption {
|
||||
/** 指定选项的值为选项对象的某个属性值 */
|
||||
value: any;
|
||||
@ -33,9 +35,20 @@ export interface TMagicMessageBox {
|
||||
close(): void;
|
||||
}
|
||||
|
||||
export type LoadingBinding = boolean;
|
||||
|
||||
const INSTANCE_KEY = Symbol('TdesignLoading');
|
||||
|
||||
export interface ElementLoading extends HTMLElement {
|
||||
[INSTANCE_KEY]?: {
|
||||
instance: any;
|
||||
};
|
||||
}
|
||||
|
||||
export interface PluginOptions {
|
||||
message?: TMagicMessage;
|
||||
messageBox?: TMagicMessageBox;
|
||||
components?: Record<string, any>;
|
||||
loading?: Directive<ElementLoading, LoadingBinding>;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
@ -5,16 +5,19 @@
|
||||
size="small"
|
||||
placeholder="输入关键字进行过滤"
|
||||
clearable
|
||||
:prefix-icon="Search"
|
||||
@input="filterTextChangeHandler"
|
||||
></TMagicInput>
|
||||
>
|
||||
<template #prefix>
|
||||
<TMagicIcon><Search /></TMagicIcon>
|
||||
</template>
|
||||
</TMagicInput>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { Search } from '@element-plus/icons-vue';
|
||||
|
||||
import { TMagicInput } from '@tmagic/design';
|
||||
import { TMagicIcon, TMagicInput } from '@tmagic/design';
|
||||
|
||||
const emit = defineEmits(['search']);
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<TMagicTabs
|
||||
<component
|
||||
v-if="data.type === 'tabs' && data.items.length"
|
||||
class="m-editor-sidebar"
|
||||
v-model="activeTabName"
|
||||
type="card"
|
||||
tab-position="left"
|
||||
class="m-editor-sidebar tmagic-design-tabs"
|
||||
v-bind="tabsComponent.props({ type: 'card', tabPosition: 'left' })"
|
||||
:is="tabsComponent.component"
|
||||
>
|
||||
<component
|
||||
:is="uiComponent.component"
|
||||
v-for="(config, index) in sideBarItems"
|
||||
v-bind="tabPaneComponent.props({ name: config.text })"
|
||||
:is="tabPaneComponent.component"
|
||||
:key="config.$key || index"
|
||||
:name="config.text"
|
||||
>
|
||||
<template #label>
|
||||
<div :key="config.text">
|
||||
@ -80,14 +80,14 @@
|
||||
</template>
|
||||
</component>
|
||||
</component>
|
||||
</TMagicTabs>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="MEditorSidebar">
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { Coin, EditPen, Files } from '@element-plus/icons-vue';
|
||||
|
||||
import { getConfig, TMagicTabs } from '@tmagic/design';
|
||||
import { getConfig } from '@tmagic/design';
|
||||
|
||||
import MIcon from '@editor/components/Icon.vue';
|
||||
import type { MenuButton, MenuComponent, SideComponent, SideItem } from '@editor/type';
|
||||
@ -107,7 +107,8 @@ const props = withDefaults(
|
||||
},
|
||||
);
|
||||
|
||||
const uiComponent = getConfig('components').tabPane;
|
||||
const tabPaneComponent = getConfig('components').tabPane;
|
||||
const tabsComponent = getConfig('components').tabs;
|
||||
|
||||
const activeTabName = ref(props.data?.status);
|
||||
|
||||
|
@ -1,11 +1,24 @@
|
||||
.m-editor-sidebar {
|
||||
.m-editor-sidebar.tmagic-design-tabs {
|
||||
height: 100%;
|
||||
|
||||
&.el-tabs--left .el-tabs__header {
|
||||
.el-tabs__header,
|
||||
.t-tabs__header {
|
||||
background: $--sidebar-heder-background-color;
|
||||
border: 0;
|
||||
height: 100%;
|
||||
|
||||
&.is-left {
|
||||
.t-tabs__nav--card {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.t-tabs__nav--card.t-tabs__nav-item:not(.t-is-disabled):not(
|
||||
.t-is-active
|
||||
):hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&.is-left,
|
||||
&.t-is-left {
|
||||
width: 40px;
|
||||
margin-right: 0;
|
||||
}
|
||||
@ -23,7 +36,8 @@
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.el-tabs__item.is-left {
|
||||
.el-tabs__item.is-left,
|
||||
.t-tabs__nav-item {
|
||||
line-height: 15px;
|
||||
border: 0;
|
||||
height: auto;
|
||||
@ -31,8 +45,10 @@
|
||||
color: rgb(255, 255, 255);
|
||||
box-sizing: border-box;
|
||||
|
||||
&.is-left {
|
||||
&.is-active {
|
||||
&.is-left,
|
||||
&.t-is-left {
|
||||
&.is-active,
|
||||
&.t-is-active {
|
||||
background: $--sidebar-content-background-color;
|
||||
border: 0;
|
||||
|
||||
@ -51,6 +67,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.t-tabs__nav-item {
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 25px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {
|
||||
ElBadge,
|
||||
ElButton,
|
||||
ElCard,
|
||||
ElCascader,
|
||||
@ -27,6 +28,7 @@ import {
|
||||
ElPagination,
|
||||
ElPopover,
|
||||
ElRadio,
|
||||
ElRadioButton,
|
||||
ElRadioGroup,
|
||||
ElRow,
|
||||
ElScrollbar,
|
||||
@ -49,6 +51,11 @@ const adapter: any = {
|
||||
message: ElMessage,
|
||||
messageBox: ElMessageBox,
|
||||
components: {
|
||||
badge: {
|
||||
component: ElBadge,
|
||||
props: (props: any) => props,
|
||||
},
|
||||
|
||||
button: {
|
||||
component: ElButton,
|
||||
props: (props: any) => props,
|
||||
@ -179,6 +186,11 @@ const adapter: any = {
|
||||
props: (props: any) => props,
|
||||
},
|
||||
|
||||
radioButton: {
|
||||
component: ElRadioButton,
|
||||
props: (props: any) => props,
|
||||
},
|
||||
|
||||
radioGroup: {
|
||||
component: ElRadioGroup,
|
||||
props: (props: any) => props,
|
||||
|
@ -1,71 +1,77 @@
|
||||
<template>
|
||||
<TMagicTabs
|
||||
<component
|
||||
v-model="activeTabName"
|
||||
:class="config.dynamic ? 'magic-form-dynamic-tab' : 'magic-form-tab'"
|
||||
:type="config.tabType"
|
||||
:editable="config.editable || false"
|
||||
:tab-position="config.tabPosition || 'top'"
|
||||
v-bind="
|
||||
tabsComponent.props({
|
||||
type: config.tabType,
|
||||
editable: config.editable || false,
|
||||
tabPosition: config.tabPosition || 'top',
|
||||
})
|
||||
"
|
||||
:is="tabsComponent.component"
|
||||
:class="`tmagic-design-tabs ${config.dynamic ? 'magic-form-dynamic-tab' : 'magic-form-tab'}`"
|
||||
@tab-click="tabClickHandler"
|
||||
@tab-add="onTabAdd"
|
||||
@tab-remove="onTabRemove"
|
||||
>
|
||||
<template v-for="(tab, tabIndex) in tabs">
|
||||
<component
|
||||
v-if="display(tab.display) && tabItems(tab).length"
|
||||
:is="uiComponent.component"
|
||||
:key="tab[mForm?.keyProp || '__key'] ?? tabIndex"
|
||||
:name="filter(tab.status) || tabIndex.toString()"
|
||||
:lazy="tab.lazy || false"
|
||||
>
|
||||
<template #label>
|
||||
<span>
|
||||
{{ filter(tab.title)
|
||||
}}<el-badge :hidden="!diffCount[tabIndex]" :value="diffCount[tabIndex]" class="diff-count-badge"></el-badge>
|
||||
</span>
|
||||
</template>
|
||||
<Container
|
||||
v-for="item in tabItems(tab)"
|
||||
:key="item[mForm?.keyProp || '__key']"
|
||||
:config="item"
|
||||
:disabled="disabled"
|
||||
:model="
|
||||
config.dynamic
|
||||
? (name ? model[name] : model)[tabIndex]
|
||||
: tab.name
|
||||
? (name ? model[name] : model)[tab.name]
|
||||
: name
|
||||
? model[name]
|
||||
: model
|
||||
"
|
||||
:last-values="
|
||||
isEmpty(lastValues)
|
||||
? {}
|
||||
: config.dynamic
|
||||
? (name ? lastValues[name] : lastValues)[tabIndex]
|
||||
: tab.name
|
||||
? (name ? lastValues[name] : lastValues)[tab.name]
|
||||
: name
|
||||
? lastValues[name]
|
||||
: lastValues
|
||||
"
|
||||
:is-compare="isCompare"
|
||||
:prop="config.dynamic ? `${prop}${prop ? '.' : ''}${String(tabIndex)}` : prop"
|
||||
:size="size"
|
||||
:label-width="tab.labelWidth || labelWidth"
|
||||
:expand-more="expandMore"
|
||||
@change="changeHandler"
|
||||
@addDiffCount="onAddDiffCount(tabIndex)"
|
||||
></Container>
|
||||
</component>
|
||||
</template>
|
||||
</TMagicTabs>
|
||||
<component
|
||||
v-for="(tab, tabIndex) in tabs"
|
||||
:is="tabPaneComponent.component"
|
||||
:key="tab[mForm?.keyProp || '__key'] ?? tabIndex"
|
||||
v-bind="tabPaneComponent.props({ name: filter(tab.status) || tabIndex.toString(), lazy: tab.lazy || false })"
|
||||
>
|
||||
<template #label>
|
||||
<span>
|
||||
{{ filter(tab.title)
|
||||
}}<TMagicBadge
|
||||
:hidden="!diffCount[tabIndex]"
|
||||
:value="diffCount[tabIndex]"
|
||||
class="diff-count-badge"
|
||||
></TMagicBadge>
|
||||
</span>
|
||||
</template>
|
||||
<Container
|
||||
v-for="item in tabItems(tab)"
|
||||
:key="item[mForm?.keyProp || '__key']"
|
||||
:config="item"
|
||||
:disabled="disabled"
|
||||
:model="
|
||||
config.dynamic
|
||||
? (name ? model[name] : model)[tabIndex]
|
||||
: tab.name
|
||||
? (name ? model[name] : model)[tab.name]
|
||||
: name
|
||||
? model[name]
|
||||
: model
|
||||
"
|
||||
:last-values="
|
||||
isEmpty(lastValues)
|
||||
? {}
|
||||
: config.dynamic
|
||||
? (name ? lastValues[name] : lastValues)[tabIndex]
|
||||
: tab.name
|
||||
? (name ? lastValues[name] : lastValues)[tab.name]
|
||||
: name
|
||||
? lastValues[name]
|
||||
: lastValues
|
||||
"
|
||||
:is-compare="isCompare"
|
||||
:prop="config.dynamic ? `${prop}${prop ? '.' : ''}${String(tabIndex)}` : prop"
|
||||
:size="size"
|
||||
:label-width="tab.labelWidth || labelWidth"
|
||||
:expand-more="expandMore"
|
||||
@change="changeHandler"
|
||||
@addDiffCount="onAddDiffCount(tabIndex)"
|
||||
></Container>
|
||||
</component>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="MFormTabs">
|
||||
import { computed, inject, ref, watchEffect } from 'vue';
|
||||
import { cloneDeep, isEmpty } from 'lodash-es';
|
||||
|
||||
import { getConfig, TMagicTabs } from '@tmagic/design';
|
||||
import { getConfig, TMagicBadge } from '@tmagic/design';
|
||||
|
||||
import { FormState, TabConfig, TabPaneConfig } from '../schema';
|
||||
import { display as displayFunc, filterFunction } from '../utils/form';
|
||||
@ -76,7 +82,8 @@ type DiffCount = {
|
||||
[tabIndex: number]: number;
|
||||
};
|
||||
|
||||
const uiComponent = getConfig('components').tabPane;
|
||||
const tabPaneComponent = getConfig('components').tabPane;
|
||||
const tabsComponent = getConfig('components').tabs;
|
||||
|
||||
const getActive = (mForm: FormState | undefined, props: any, activeTabName: string) => {
|
||||
const { config, model, prop } = props;
|
||||
@ -135,7 +142,7 @@ const tabs = computed(() => {
|
||||
if (!props.config.name) throw new Error('dynamic tab 必须配置name');
|
||||
return props.model[props.config.name] || [];
|
||||
}
|
||||
return props.config.items;
|
||||
return props.config.items.filter((item) => displayFunc(mForm, item.display, props));
|
||||
});
|
||||
|
||||
const filter = (config: any) => filterFunction(mForm, config, props);
|
||||
@ -193,8 +200,6 @@ const onTabRemove = (tabName: string) => {
|
||||
mForm?.$emit('field-change', props.prop, props.model[props.config.name]);
|
||||
};
|
||||
|
||||
const display = (displayConfig: any) => displayFunc(mForm, displayConfig, props);
|
||||
|
||||
const changeHandler = () => {
|
||||
emit('change', props.model);
|
||||
if (typeof props.config.onChange === 'function') {
|
||||
|
@ -11,14 +11,14 @@
|
||||
>
|
||||
<template #append v-if="config.append">
|
||||
<span v-if="typeof config.append === 'string'">{{ config.append }}</span>
|
||||
<el-button
|
||||
<TMagicButton
|
||||
v-if="typeof config.append === 'object' && config.append.type === 'button'"
|
||||
style="color: #409eff"
|
||||
:size="size"
|
||||
@click.prevent="buttonClickHandler"
|
||||
>
|
||||
{{ config.append.text }}
|
||||
</el-button>
|
||||
</TMagicButton>
|
||||
</template>
|
||||
</TMagicInput>
|
||||
</template>
|
||||
@ -26,7 +26,7 @@
|
||||
<script lang="ts" setup name="MFormText">
|
||||
import { inject } from 'vue';
|
||||
|
||||
import { TMagicInput } from '@tmagic/design';
|
||||
import { TMagicButton, TMagicInput } from '@tmagic/design';
|
||||
import { isNumber } from '@tmagic/utils';
|
||||
|
||||
import { FormState, TextConfig } from '../schema';
|
||||
|
@ -37,12 +37,12 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"element-plus": "^2.2.32",
|
||||
"tdesign-vue-next": "^0.26.0",
|
||||
"tdesign-vue-next": "^1.3.1",
|
||||
"vue": "^3.2.37"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"element-plus": "^2.2.32",
|
||||
"tdesign-vue-next": "^0.26.0",
|
||||
"tdesign-vue-next": "^1.3.1",
|
||||
"vue": "^3.2.37"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
7
packages/tdesign-vue-next-adapter/src/Icon.vue
Normal file
7
packages/tdesign-vue-next-adapter/src/Icon.vue
Normal file
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<i style="width: 1em; height: 1em">
|
||||
<slot></slot>
|
||||
</i>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
@ -18,7 +18,14 @@
|
||||
@keypress="inputHandler"
|
||||
@change="changeHandler"
|
||||
@update:modelValue="updateModelValue"
|
||||
></TInput>
|
||||
>
|
||||
<template #prefix-icon v-if="$slots.prefix">
|
||||
<slot name="prefix"></slot>
|
||||
</template>
|
||||
<template #suffix v-if="$slots.suffix">
|
||||
<slot name="suffix"></slot>
|
||||
</template>
|
||||
</TInput>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -1,20 +1,19 @@
|
||||
import { h } from 'vue';
|
||||
import {
|
||||
ElDrawer,
|
||||
ElDropdown,
|
||||
ElDropdownItem,
|
||||
ElDropdownMenu,
|
||||
ElIcon,
|
||||
ElMessageBox,
|
||||
ElPagination,
|
||||
ElPopover,
|
||||
ElScrollbar,
|
||||
ElTable,
|
||||
ElTableColumn,
|
||||
ElTabPane,
|
||||
ElTabs,
|
||||
ElTree,
|
||||
} from 'element-plus';
|
||||
import {
|
||||
Badge as TBadge,
|
||||
Button as TButton,
|
||||
Card as TCard,
|
||||
Cascader as TCascader,
|
||||
@ -33,12 +32,15 @@ import {
|
||||
Option as TOption,
|
||||
OptionGroup as TOptionGroup,
|
||||
Radio as TRadio,
|
||||
RadioButton as TRadioButton,
|
||||
RadioGroup as TRadioGroup,
|
||||
Row as TRow,
|
||||
Select as TSelect,
|
||||
StepItem as TStepItem,
|
||||
Steps as TSteps,
|
||||
Switch as TSwitch,
|
||||
TabPanel as TTabPanel,
|
||||
Tabs as TTabs,
|
||||
Tag as TTag,
|
||||
TimePicker as TTimePicker,
|
||||
Tooltip as TTooltip,
|
||||
@ -46,18 +48,30 @@ import {
|
||||
} from 'tdesign-vue-next';
|
||||
|
||||
import DatePicker from './DatePicker.vue';
|
||||
import Icon from './Icon.vue';
|
||||
import Input from './Input.vue';
|
||||
import { vLoading } from './loading';
|
||||
|
||||
const adapter: any = {
|
||||
message: MessagePlugin,
|
||||
messageBox: ElMessageBox,
|
||||
loading: vLoading,
|
||||
components: {
|
||||
badge: {
|
||||
component: TBadge,
|
||||
props: (props: any) => ({
|
||||
count: props.value,
|
||||
dot: props.isDot,
|
||||
maxCount: props.max,
|
||||
}),
|
||||
},
|
||||
|
||||
button: {
|
||||
component: TButton,
|
||||
props: (props: any) => ({
|
||||
theme: props.type,
|
||||
size: props.size === 'default' ? 'medium' : props.size,
|
||||
icon: props.icon,
|
||||
icon: () => (props.icon ? h(props.icon) : null),
|
||||
variant: props.text ? 'text' : 'base',
|
||||
}),
|
||||
},
|
||||
@ -209,7 +223,7 @@ const adapter: any = {
|
||||
},
|
||||
|
||||
icon: {
|
||||
component: ElIcon,
|
||||
component: Icon,
|
||||
props: (props: any) => props,
|
||||
},
|
||||
|
||||
@ -263,6 +277,13 @@ const adapter: any = {
|
||||
}),
|
||||
},
|
||||
|
||||
radioButton: {
|
||||
component: TRadioButton,
|
||||
props: (props: any) => ({
|
||||
label: props.label,
|
||||
}),
|
||||
},
|
||||
|
||||
radioGroup: {
|
||||
component: TRadioGroup,
|
||||
props: (props: any) => ({
|
||||
@ -336,13 +357,21 @@ const adapter: any = {
|
||||
},
|
||||
|
||||
tabPane: {
|
||||
component: ElTabPane,
|
||||
props: (props: any) => props,
|
||||
component: TTabPanel,
|
||||
props: (props: any) => ({
|
||||
label: props.label,
|
||||
value: props.name,
|
||||
}),
|
||||
},
|
||||
|
||||
tabs: {
|
||||
component: ElTabs,
|
||||
props: (props: any) => props,
|
||||
component: TTabs,
|
||||
props: (props: any) => ({
|
||||
addable: props.editable,
|
||||
theme: props.type === 'card' ? 'card' : 'normal',
|
||||
placement: props.tabPosition,
|
||||
value: props.modelValue,
|
||||
}),
|
||||
},
|
||||
|
||||
tag: {
|
||||
|
45
packages/tdesign-vue-next-adapter/src/loading.ts
Normal file
45
packages/tdesign-vue-next-adapter/src/loading.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import type { Directive } from 'vue';
|
||||
import { LoadingInstance, LoadingPlugin } from 'tdesign-vue-next';
|
||||
|
||||
export type LoadingBinding = boolean;
|
||||
|
||||
const INSTANCE_KEY = Symbol('TdesignLoading');
|
||||
|
||||
export interface ElementLoading extends HTMLElement {
|
||||
[INSTANCE_KEY]?: {
|
||||
instance: LoadingInstance;
|
||||
};
|
||||
}
|
||||
|
||||
const createInstance = (el: ElementLoading) =>
|
||||
(el[INSTANCE_KEY] = {
|
||||
instance: LoadingPlugin({
|
||||
attach: () => el,
|
||||
showOverlay: true,
|
||||
size: '20px',
|
||||
}),
|
||||
});
|
||||
|
||||
export const vLoading: Directive<ElementLoading, LoadingBinding> = {
|
||||
mounted(el, binding) {
|
||||
const { value } = binding;
|
||||
if (value) {
|
||||
createInstance(el);
|
||||
}
|
||||
},
|
||||
|
||||
updated(el, binding) {
|
||||
const instance = el[INSTANCE_KEY];
|
||||
if (binding.oldValue !== binding.value) {
|
||||
if (binding.value && !binding.oldValue) {
|
||||
createInstance(el);
|
||||
} else {
|
||||
instance?.instance.hide();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
unmounted(el) {
|
||||
el[INSTANCE_KEY]?.instance.hide();
|
||||
},
|
||||
};
|
@ -1,15 +1,16 @@
|
||||
<template>
|
||||
<el-radio-group size="small" v-model="viewerDevice" :class="viewerDevice" @change="deviceSelect">
|
||||
<el-radio-button label="phone">Phone</el-radio-button>
|
||||
<el-radio-button label="pad">Pad</el-radio-button>
|
||||
<el-radio-button label="pc">PC</el-radio-button>
|
||||
</el-radio-group>
|
||||
<TMagicRadioGroup size="small" v-model="viewerDevice" :class="viewerDevice" @change="deviceSelect">
|
||||
<TMagicRadioButton label="phone">Phone</TMagicRadioButton>
|
||||
<TMagicRadioButton label="pad">Pad</TMagicRadioButton>
|
||||
<TMagicRadioButton label="pc">PC</TMagicRadioButton>
|
||||
</TMagicRadioGroup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, ref } from 'vue';
|
||||
|
||||
import Core from '@tmagic/core';
|
||||
import { TMagicRadioButton, TMagicRadioGroup } from '@tmagic/design';
|
||||
import { editorService } from '@tmagic/editor';
|
||||
|
||||
import { DeviceType, uaMap } from '../const';
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="m-editor-nav-menu">
|
||||
<el-button
|
||||
<TMagicButton
|
||||
v-for="(item, index) in data"
|
||||
class="menu-item button"
|
||||
:key="index"
|
||||
@ -8,25 +8,26 @@
|
||||
text
|
||||
@click="item.handler"
|
||||
>
|
||||
<el-icon><component :is="item.icon"></component></el-icon><span>{{ item.text }}</span>
|
||||
</el-button>
|
||||
<TMagicIcon><component :is="item.icon"></component></TMagicIcon><span>{{ item.text }}</span>
|
||||
</TMagicButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
import { TMagicButton, TMagicIcon } from '@tmagic/design';
|
||||
import { MenuButton } from '@tmagic/editor';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'nav-menu',
|
||||
|
||||
props: {
|
||||
data: {
|
||||
type: Array as PropType<MenuButton[]>,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
components: { TMagicIcon, TMagicButton },
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
</template>
|
||||
</m-editor>
|
||||
|
||||
<el-dialog
|
||||
<TMagicDialog
|
||||
v-model="previewVisible"
|
||||
destroy-on-close
|
||||
class="pre-viewer"
|
||||
@ -33,7 +33,7 @@
|
||||
:height="stageRect && stageRect.height"
|
||||
:src="previewUrl"
|
||||
></iframe>
|
||||
</el-dialog>
|
||||
</TMagicDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -41,9 +41,9 @@
|
||||
import { computed, nextTick, ref, toRaw } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { Coin, Connection, Document } from '@element-plus/icons-vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import serialize from 'serialize-javascript';
|
||||
|
||||
import { TMagicDialog, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
|
||||
import { editorService, MenuBarData, MoveableOptions, TMagicEditor } from '@tmagic/editor';
|
||||
import type { MContainer, MNode } from '@tmagic/schema';
|
||||
import { NodeType } from '@tmagic/schema';
|
||||
@ -104,13 +104,13 @@ const menu: MenuBarData = {
|
||||
handler: async (services) => {
|
||||
if (services?.editorService.get('modifiedNodeIds').size > 0) {
|
||||
try {
|
||||
await ElMessageBox.confirm('有修改未保存,是否先保存再预览', '提示', {
|
||||
await tMagicMessageBox.confirm('有修改未保存,是否先保存再预览', '提示', {
|
||||
confirmButtonText: '保存并预览',
|
||||
cancelButtonText: '预览',
|
||||
type: 'warning',
|
||||
});
|
||||
save();
|
||||
ElMessage.success('保存成功');
|
||||
tMagicMessage.success('保存成功');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
@ -132,7 +132,7 @@ const menu: MenuBarData = {
|
||||
icon: Coin,
|
||||
handler: () => {
|
||||
save();
|
||||
ElMessage.success('保存成功');
|
||||
tMagicMessage.success('保存成功');
|
||||
},
|
||||
},
|
||||
'/',
|
||||
|
@ -20,17 +20,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-dialog v-model="resultVisible" title="result" append-to-body>
|
||||
<TMagicDialog v-model="resultVisible" title="result" append-to-body>
|
||||
<pre><code class="language-javascript hljs" v-html="result"></code></pre>
|
||||
</el-dialog>
|
||||
</TMagicDialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { markRaw, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { Coin } from '@element-plus/icons-vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
import { TMagicDialog, tMagicMessage } from '@tmagic/design';
|
||||
import { MenuButton } from '@tmagic/editor';
|
||||
import { MForm } from '@tmagic/form';
|
||||
|
||||
@ -401,12 +401,7 @@ async function submit() {
|
||||
result.value = JSON.stringify(values, null, 2);
|
||||
} catch (e: any) {
|
||||
console.error(e);
|
||||
ElMessage.error({
|
||||
duration: 10000,
|
||||
showClose: true,
|
||||
message: e.message,
|
||||
dangerouslyUseHTMLString: true,
|
||||
});
|
||||
tMagicMessage.error(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,9 +409,9 @@ function change(value: string) {
|
||||
try {
|
||||
// eslint-disable-next-line no-eval
|
||||
config.value = eval(value);
|
||||
ElMessage.success('更新成功');
|
||||
tMagicMessage.success('更新成功');
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e.message);
|
||||
tMagicMessage.error(e.message);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -18,8 +18,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
import { tMagicMessage } from '@tmagic/design';
|
||||
import { MenuButton } from '@tmagic/editor';
|
||||
|
||||
import NavMenu from '../components/NavMenu.vue';
|
||||
@ -71,9 +71,9 @@ function change(value: string) {
|
||||
try {
|
||||
// eslint-disable-next-line no-eval
|
||||
columns.value = eval(value);
|
||||
ElMessage.success('更新成功');
|
||||
tMagicMessage.success('更新成功');
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e.message);
|
||||
tMagicMessage.error(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,9 +81,9 @@ function changeData(value: string) {
|
||||
try {
|
||||
// eslint-disable-next-line no-eval
|
||||
data.value = eval(value);
|
||||
ElMessage.success('更新成功');
|
||||
tMagicMessage.success('更新成功');
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e.message);
|
||||
tMagicMessage.error(e.message);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@ -523,8 +523,8 @@ importers:
|
||||
specifier: ^2.2.32
|
||||
version: 2.2.32(vue@3.2.37)
|
||||
tdesign-vue-next:
|
||||
specifier: ^0.26.0
|
||||
version: 0.26.0(vue@3.2.37)
|
||||
specifier: ^1.3.1
|
||||
version: 1.3.1(vue@3.2.37)
|
||||
vue:
|
||||
specifier: ^3.2.37
|
||||
version: 3.2.37
|
||||
@ -8653,8 +8653,8 @@ packages:
|
||||
vue: 3.2.37
|
||||
dev: false
|
||||
|
||||
/tdesign-vue-next@0.26.0(vue@3.2.37):
|
||||
resolution: {integrity: sha512-s5/vSn5JGgR+FofBoauCbNli8hXZ+RnwcwHIHNH1CgpI8tnHKpYBU3qteSy7DsKs3nsti58lAbVbNAJT5Izf6w==}
|
||||
/tdesign-vue-next@1.3.1(vue@3.2.37):
|
||||
resolution: {integrity: sha512-KHnDu9DX20mEIXIXM6jrYTbeD5mIxyDIsUUjXBY2cdyXn1oAneQJwg6Ceph8Ih7a3sm4/Q8dQVFpqo1/12aWGw==}
|
||||
peerDependencies:
|
||||
vue: '>=3.1.0'
|
||||
dependencies:
|
||||
|
Loading…
x
Reference in New Issue
Block a user