2022-08-23 20:35:34 +08:00

186 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Tencent is pleased to support the open source community by making TMagicEditor available.
*
* Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { reactive } from 'vue';
import { cloneDeep, mergeWith } from 'lodash-es';
import type { FormConfig } from '@tmagic/form';
import type { MComponent, MNode } from '@tmagic/schema';
import { toLine } from '@tmagic/utils';
import type { PropsState } from '../type';
import { DEFAULT_CONFIG, fillConfig } from '../utils/props';
import BaseService from './BaseService';
class Props extends BaseService {
private state = reactive<PropsState>({
propsConfigMap: {},
propsValueMap: {},
});
constructor() {
super([
'setPropsConfig',
'getPropsConfig',
'setPropsValue',
'getPropsValue',
'createId',
'setNewItemId',
'getDefaultPropsValue',
]);
}
public setPropsConfigs(configs: Record<string, FormConfig>) {
Object.keys(configs).forEach((type: string) => {
this.setPropsConfig(toLine(type), configs[type]);
});
this.emit('props-configs-change');
}
/**
* 为指定类型组件设置组件属性表单配置
* @param type 组件类型
* @param config 组件属性表单配置
*/
public setPropsConfig(type: string, config: FormConfig) {
this.state.propsConfigMap[type] = fillConfig(Array.isArray(config) ? config : [config]);
}
/**
* 获取指点类型的组件属性表单配置
* @param type 组件类型
* @returns 组件属性表单配置
*/
public async getPropsConfig(type: string): Promise<FormConfig> {
if (type === 'area') {
return await this.getPropsConfig('button');
}
return cloneDeep(this.state.propsConfigMap[type] || DEFAULT_CONFIG);
}
public setPropsValues(values: Record<string, MNode>) {
Object.keys(values).forEach((type: string) => {
this.setPropsValue(toLine(type), values[type]);
});
}
/**
* 为指点类型组件设置组件初始值
* @param type 组件类型
* @param value 组件初始值
*/
public setPropsValue(type: string, value: MNode) {
this.state.propsValueMap[type] = value;
}
/**
* 获取指定类型的组件初始值
* @param type 组件类型
* @returns 组件初始值
*/
public async getPropsValue(type: string, { inputEvent, ...defaultValue }: Record<string, any> = {}) {
if (type === 'area') {
const value = (await this.getPropsValue('button')) as MComponent;
value.className = 'action-area';
value.text = '';
if (value.style) {
value.style.backgroundColor = 'rgba(255, 255, 255, 0)';
}
return value;
}
const [id, defaultPropsValue, data] = await Promise.all([
this.createId(type),
this.getDefaultPropsValue(type),
this.setNewItemId(
cloneDeep({
type,
...defaultValue,
} as any),
),
]);
return {
id,
...defaultPropsValue,
...mergeWith({}, cloneDeep(this.state.propsValueMap[type] || {}), data),
};
}
public async createId(type: string | number): Promise<string> {
return `${type}_${this.guid()}`;
}
/**
* 将组件与组件的子元素配置中的id都设置成一个新的ID
* @param {Object} config 组件配置
*/
/* eslint no-param-reassign: ["error", { "props": false }] */
public async setNewItemId(config: MNode) {
config.id = await this.createId(config.type || 'component');
if (config.items && Array.isArray(config.items)) {
for (const item of config.items) {
await this.setNewItemId(item);
}
}
return config;
}
/**
* 获取默认属性配置
* @param type 组件类型
* @returns Object
*/
public async getDefaultPropsValue(type: string) {
return ['page', 'container'].includes(type)
? {
type,
layout: 'absolute',
style: {},
name: type,
items: [],
}
: {
type,
style: {},
name: type,
};
}
/**
* 生成指定位数的GUID无【-】格式
* @param digit 位数默认值8
* @returns
*/
private guid(digit = 8): string {
return 'x'.repeat(digit).replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0;
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
}
export type PropsService = Props;
export default new Props();