mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-05 05:28:37 +08:00
amis-saas-10220 外观源码编辑器
Change-Id: I36dcfaa22c811dda6d970f0c508abdb792daf1fa
This commit is contained in:
parent
b47c56eee2
commit
acd3dd078f
@ -367,7 +367,14 @@ export class ButtonPlugin extends BasePlugin {
|
||||
...buttonStateFunc("${editorState == 'active'}", 'active')
|
||||
]
|
||||
},
|
||||
getSchemaTpl('theme:cssCode')
|
||||
getSchemaTpl('theme:cssCode', {
|
||||
themeClass: [
|
||||
{
|
||||
value: '',
|
||||
state: ['default', 'hover', 'active']
|
||||
}
|
||||
]
|
||||
})
|
||||
])
|
||||
},
|
||||
{
|
||||
|
@ -282,7 +282,17 @@ export class NumberControlPlugin extends BasePlugin {
|
||||
)
|
||||
]
|
||||
},
|
||||
getSchemaTpl('theme:cssCode', {isFormItem: true})
|
||||
getSchemaTpl('theme:cssCode', {
|
||||
themeClass: [
|
||||
{
|
||||
name: '数字输入框',
|
||||
value: '',
|
||||
className: 'inputControlClassName',
|
||||
state: ['default', 'hover', 'active']
|
||||
}
|
||||
],
|
||||
isFormItem: true
|
||||
})
|
||||
],
|
||||
{...context?.schema, configTitle: 'style'}
|
||||
)
|
||||
|
@ -383,7 +383,19 @@ export class TextControlPlugin extends BasePlugin {
|
||||
]
|
||||
},
|
||||
getSchemaTpl('theme:cssCode', {
|
||||
themeClass: ['addOn'],
|
||||
themeClass: [
|
||||
{
|
||||
name: '输入框',
|
||||
value: '',
|
||||
className: 'inputControlClassName',
|
||||
state: ['default', 'hover', 'active']
|
||||
},
|
||||
{
|
||||
name: 'addOn',
|
||||
value: 'addOn',
|
||||
className: 'addOnClassName'
|
||||
}
|
||||
],
|
||||
isFormItem: true
|
||||
})
|
||||
],
|
||||
|
@ -274,30 +274,7 @@ export class PagePlugin extends BasePlugin {
|
||||
className: 'p-none',
|
||||
body: [
|
||||
getSchemaTpl('collapseGroup', [
|
||||
...getSchemaTpl('theme:common', ['layout']),
|
||||
getSchemaTpl('style:classNames', {
|
||||
isFormItem: false,
|
||||
schema: [
|
||||
getSchemaTpl('className', {
|
||||
name: 'headerClassName',
|
||||
label: '顶部'
|
||||
}),
|
||||
getSchemaTpl('className', {
|
||||
name: 'bodyClassName',
|
||||
label: '内容区'
|
||||
}),
|
||||
|
||||
getSchemaTpl('className', {
|
||||
name: 'asideClassName',
|
||||
label: '边栏'
|
||||
}),
|
||||
|
||||
getSchemaTpl('className', {
|
||||
name: 'toolbarClassName',
|
||||
label: '工具栏'
|
||||
})
|
||||
]
|
||||
})
|
||||
...getSchemaTpl('theme:common', ['layout'])
|
||||
])
|
||||
]
|
||||
},
|
||||
|
@ -3,12 +3,13 @@
|
||||
*/
|
||||
import React, {useEffect, useRef, useState} from 'react';
|
||||
import {Button, Editor, Overlay, PopOver} from 'amis-ui';
|
||||
import {FormControlProps, FormItem} from 'amis-core';
|
||||
import {FormControlProps, FormItem, uuid} from 'amis-core';
|
||||
import {parse as cssParse} from 'amis-postcss';
|
||||
import {PlainObject} from './types';
|
||||
import {cloneDeep, debounce} from 'lodash';
|
||||
import {cloneDeep, debounce, isEmpty} from 'lodash';
|
||||
import {Icon} from '../../icons/index';
|
||||
import editorFactory from './themeLanguage';
|
||||
import cx from 'classnames';
|
||||
|
||||
const valueMap: PlainObject = {
|
||||
'margin-top': 'marginTop',
|
||||
@ -53,39 +54,62 @@ interface CssNode {
|
||||
selector: string;
|
||||
}
|
||||
|
||||
function AmisStyleCodeEditor(props: FormControlProps) {
|
||||
interface CssNodeTab {
|
||||
name: string;
|
||||
children: CssNode[];
|
||||
}
|
||||
|
||||
function AmisThemeCssCodeEditor(props: FormControlProps) {
|
||||
const {themeClass, data} = props;
|
||||
const id = data.id.replace('u:', '');
|
||||
const [cssNodes, setCssNodes] = useState<CssNode[]>([]);
|
||||
const [value, setValue] = useState('');
|
||||
const [select, setSelect] = useState(0);
|
||||
function getCssAndSetValue(themeClass: string[]) {
|
||||
const [cssNodes, setCssNodes] = useState<CssNodeTab[]>([]);
|
||||
const [tabId, setTabId] = useState(0);
|
||||
function getCssAndSetValue(themeClass: any[]) {
|
||||
try {
|
||||
const nodes: any[] = [];
|
||||
const ids = themeClass.map(n => (n ? id + '-' + n : id));
|
||||
ids?.forEach(id => {
|
||||
const dom = document.getElementById(id || '') || null;
|
||||
const newCssNodes: CssNodeTab[] = [];
|
||||
themeClass?.forEach(n => {
|
||||
const classId = n.value ? id + '-' + n.value : id;
|
||||
const state = n.state || ['default'];
|
||||
const className = n.className || 'className';
|
||||
const dom = document.getElementById(classId || '') || null;
|
||||
const content = dom?.innerHTML || '';
|
||||
const ast = cssParse(content);
|
||||
|
||||
const nodes: any[] = [];
|
||||
ast.nodes.forEach((node: any) => {
|
||||
const selector = node.selector;
|
||||
if (!selector.endsWith('.hover') && !selector.endsWith('.active')) {
|
||||
nodes.push(node);
|
||||
}
|
||||
});
|
||||
ast.nodes = nodes;
|
||||
});
|
||||
|
||||
const css = nodes.map(node => {
|
||||
const style = node.nodes.map((n: any) => `${n.prop}: ${n.value};`);
|
||||
return {
|
||||
selector: node.selector,
|
||||
value: style.join('\n')
|
||||
};
|
||||
const css: {selector: string; value: string; state: string}[] = [];
|
||||
state.forEach((s: string) => {
|
||||
css.push({
|
||||
selector: `.${className}-${id}${s === 'default' ? '' : ':' + s}`,
|
||||
state: s,
|
||||
value: ''
|
||||
});
|
||||
});
|
||||
nodes.forEach(node => {
|
||||
const style = node.nodes.map((n: any) => `${n.prop}: ${n.value};`);
|
||||
const item = css.find(c => {
|
||||
if (
|
||||
c.selector === node.selector ||
|
||||
node.selector.endsWith(`:${c.state}`)
|
||||
) {
|
||||
return c;
|
||||
}
|
||||
return false;
|
||||
})!;
|
||||
item.value = style.join('\n');
|
||||
});
|
||||
|
||||
newCssNodes.push({
|
||||
name: n.name || '自定义样式',
|
||||
children: css
|
||||
});
|
||||
});
|
||||
setValue(css[select].value);
|
||||
setCssNodes(css);
|
||||
setCssNodes(newCssNodes);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
@ -95,61 +119,70 @@ function AmisStyleCodeEditor(props: FormControlProps) {
|
||||
getCssAndSetValue(themeClass);
|
||||
}, []);
|
||||
|
||||
const editorChange = debounce((nodes: CssNode[]) => {
|
||||
const editorChange = debounce((nodeTabs: CssNodeTab[]) => {
|
||||
try {
|
||||
const {data, onBulkChange} = props;
|
||||
const sourceCss = data.themeCss || data.css || {};
|
||||
const newCss: any = {};
|
||||
nodes.forEach(node => {
|
||||
const nodes = node.value
|
||||
.replace(/\s/g, '')
|
||||
.split(';')
|
||||
.map(kv => {
|
||||
const [prop, value] = kv.split(':');
|
||||
return {
|
||||
prop,
|
||||
value
|
||||
};
|
||||
})
|
||||
.filter(n => n.value);
|
||||
const selector = node.selector;
|
||||
const nameEtr = /\.(.*)\-/.exec(selector);
|
||||
const cssCode: PlainObject = {};
|
||||
let name = nameEtr ? nameEtr[1] : '';
|
||||
let state = 'default';
|
||||
if (!!~selector.indexOf(':hover:active')) {
|
||||
state = 'active';
|
||||
} else if (!!~selector.indexOf(':hover')) {
|
||||
state = 'hover';
|
||||
}
|
||||
nodes.forEach(item => {
|
||||
const prop = item.prop;
|
||||
const cssValue = item.value;
|
||||
if (!!~prop.indexOf('radius')) {
|
||||
const type = 'radius:' + state;
|
||||
!cssCode[type] && (cssCode[type] = {});
|
||||
const radius = cssValue.split(' ');
|
||||
nodeTabs.forEach(tab => {
|
||||
tab.children.forEach(node => {
|
||||
const nodes = node.value
|
||||
.replace(/\s/g, '')
|
||||
.split(';')
|
||||
.map(kv => {
|
||||
const [prop, value] = kv.split(':');
|
||||
return {
|
||||
prop,
|
||||
value
|
||||
};
|
||||
})
|
||||
.filter(n => n.value);
|
||||
const selector = node.selector;
|
||||
const nameEtr = /\.(.*)\-/.exec(selector);
|
||||
const cssCode: PlainObject = {};
|
||||
let name = nameEtr ? nameEtr[1] : '';
|
||||
let state = 'default';
|
||||
if (!!~selector.indexOf(':active')) {
|
||||
state = 'active';
|
||||
} else if (!!~selector.indexOf(':hover')) {
|
||||
state = 'hover';
|
||||
}
|
||||
nodes.forEach(item => {
|
||||
const prop = item.prop;
|
||||
const cssValue = item.value;
|
||||
if (!!~prop.indexOf('radius')) {
|
||||
const type = 'radius:' + state;
|
||||
!cssCode[type] && (cssCode[type] = {});
|
||||
const radius = cssValue.split(' ');
|
||||
|
||||
cssCode[type]['top-left-border-radius'] = radius[0];
|
||||
cssCode[type]['top-right-border-radius'] = radius[1];
|
||||
cssCode[type]['bottom-right-border-radius'] = radius[2];
|
||||
cssCode[type]['bottom-left-border-radius'] = radius[3];
|
||||
} else if (!!~prop.indexOf('border')) {
|
||||
!cssCode['border:' + state] && (cssCode['border:' + state] = {});
|
||||
cssCode['border:' + state][valueMap[prop] || prop] = cssValue;
|
||||
} else if (!!~prop.indexOf('padding') || !!~prop.indexOf('margin')) {
|
||||
!cssCode['padding-and-margin:' + state] &&
|
||||
(cssCode['padding-and-margin:' + state] = {});
|
||||
cssCode['padding-and-margin:' + state][valueMap[prop] || prop] =
|
||||
cssValue;
|
||||
} else if (fontStyle.includes(prop)) {
|
||||
!cssCode['font:' + state] && (cssCode['font:' + state] = {});
|
||||
cssCode['font:' + state][valueMap[prop] || prop] = cssValue;
|
||||
cssCode[type]['top-left-border-radius'] = radius[0];
|
||||
cssCode[type]['top-right-border-radius'] = radius[1];
|
||||
cssCode[type]['bottom-right-border-radius'] = radius[2];
|
||||
cssCode[type]['bottom-left-border-radius'] = radius[3];
|
||||
} else if (!!~prop.indexOf('border')) {
|
||||
!cssCode['border:' + state] && (cssCode['border:' + state] = {});
|
||||
cssCode['border:' + state][valueMap[prop] || prop] = cssValue;
|
||||
} else if (
|
||||
!!~prop.indexOf('padding') ||
|
||||
!!~prop.indexOf('margin')
|
||||
) {
|
||||
!cssCode['padding-and-margin:' + state] &&
|
||||
(cssCode['padding-and-margin:' + state] = {});
|
||||
cssCode['padding-and-margin:' + state][valueMap[prop] || prop] =
|
||||
cssValue;
|
||||
} else if (fontStyle.includes(prop)) {
|
||||
!cssCode['font:' + state] && (cssCode['font:' + state] = {});
|
||||
cssCode['font:' + state][valueMap[prop] || prop] = cssValue;
|
||||
} else {
|
||||
cssCode[(valueMap[prop] || prop) + ':' + state] = cssValue;
|
||||
}
|
||||
});
|
||||
if (newCss[name]) {
|
||||
newCss[name] = Object.assign(newCss[name], cssCode);
|
||||
} else {
|
||||
cssCode[(valueMap[prop] || prop) + ':' + state] = cssValue;
|
||||
newCss[name] = cssCode;
|
||||
}
|
||||
});
|
||||
newCss[name] = cssCode;
|
||||
});
|
||||
onBulkChange &&
|
||||
onBulkChange({
|
||||
@ -163,13 +196,22 @@ function AmisStyleCodeEditor(props: FormControlProps) {
|
||||
}
|
||||
});
|
||||
|
||||
function handleChange(value: string) {
|
||||
const newCssNodes = cloneDeep(cssNodes);
|
||||
newCssNodes[select].value = value;
|
||||
setCssNodes(newCssNodes);
|
||||
setValue(value);
|
||||
function handleChange(value: string, i: number, j: number) {
|
||||
const newCssNodes = cssNodes;
|
||||
newCssNodes[i].children[j].value = value;
|
||||
setCssNodes(newCssNodes); // 好像不需要这个?
|
||||
editorChange(newCssNodes);
|
||||
}
|
||||
function formateTitle(title: string) {
|
||||
if (title.endsWith('hover')) {
|
||||
return '悬浮态样式';
|
||||
} else if (title.endsWith('active')) {
|
||||
return '点击态样式';
|
||||
} else if (title.endsWith('disabled')) {
|
||||
return '禁用态样式';
|
||||
}
|
||||
return '常规态样式';
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ThemeCssCode-editor">
|
||||
@ -179,12 +221,125 @@ function AmisStyleCodeEditor(props: FormControlProps) {
|
||||
<Icon icon="close" className="icon" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="ThemeCssCode-editor-content">
|
||||
<div className="ThemeCssCode-editor-content-header">
|
||||
{cssNodes.map((node, index) => {
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
onClick={() => setTabId(index)}
|
||||
className={cx(
|
||||
'ThemeCssCode-editor-content-header-title',
|
||||
index === tabId &&
|
||||
'ThemeCssCode-editor-content-header-title--active'
|
||||
)}
|
||||
>
|
||||
{node.name}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="ThemeCssCode-editor-content-main">
|
||||
{cssNodes.map((node, i) => {
|
||||
const children = node.children;
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
className={cx(
|
||||
i !== tabId && 'ThemeCssCode-editor-content-body--hidden'
|
||||
)}
|
||||
>
|
||||
{children.map((css, j) => {
|
||||
return (
|
||||
<div
|
||||
className="ThemeCssCode-editor-content-body"
|
||||
key={`${i}-${j}-${css.selector}`}
|
||||
id={`${i}-${j}-${css.selector}`}
|
||||
>
|
||||
{children.length > 1 ? (
|
||||
<div className="ThemeCssCode-editor-content-body-title">
|
||||
{formateTitle(css.selector)}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="ThemeCssCode-editor-content-body-editor">
|
||||
<Editor
|
||||
value={css.value}
|
||||
editorFactory={editorFactory}
|
||||
options={{
|
||||
onChange: (value: string) =>
|
||||
handleChange(value, i, j)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AmisStyleCodeEditor(props: FormControlProps) {
|
||||
const {data, onBulkChange} = props;
|
||||
const {style} = data;
|
||||
const [value, setValue] = useState('');
|
||||
|
||||
function getCssAndSetValue(data: any) {
|
||||
if (isEmpty(data)) {
|
||||
return '';
|
||||
}
|
||||
let str = '';
|
||||
for (let key in data) {
|
||||
str += `${key}: ${data[key]};\n`;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const res = getCssAndSetValue(style);
|
||||
setValue(res);
|
||||
}, []);
|
||||
|
||||
const editorChange = debounce((value: string) => {
|
||||
const newStyle: PlainObject = {};
|
||||
value
|
||||
.replace(/\s/g, '')
|
||||
.split(';')
|
||||
.forEach(kv => {
|
||||
const [prop, value] = kv.split(':');
|
||||
if (value) {
|
||||
newStyle[prop] = value;
|
||||
}
|
||||
});
|
||||
onBulkChange &&
|
||||
onBulkChange({
|
||||
style: newStyle
|
||||
});
|
||||
});
|
||||
|
||||
function handleChange(value: string) {
|
||||
editorChange(value);
|
||||
setValue(value);
|
||||
}
|
||||
return (
|
||||
<div className="ThemeCssCode-editor">
|
||||
<div className="ThemeCssCode-editor-title">编辑样式源码</div>
|
||||
<div className="ThemeCssCode-editor-close">
|
||||
<Button onClick={props.onHide} level="link">
|
||||
<Icon icon="close" className="icon" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="ThemeCssCode-editor-content">
|
||||
<Editor
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
editorFactory={editorFactory}
|
||||
options={{
|
||||
onChange: handleChange
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -193,7 +348,6 @@ function AmisStyleCodeEditor(props: FormControlProps) {
|
||||
|
||||
function ThemeCssCode(props: FormControlProps) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const {value} = props;
|
||||
const [showEditor, setShowEditor] = useState(false);
|
||||
function handleShowEditor() {
|
||||
setShowEditor(true);
|
||||
@ -213,7 +367,17 @@ function ThemeCssCode(props: FormControlProps) {
|
||||
rootClose={false}
|
||||
>
|
||||
<PopOver overlay onHide={() => setShowEditor(false)}>
|
||||
<AmisStyleCodeEditor {...props} onHide={() => setShowEditor(false)} />
|
||||
{props.isLayout ? (
|
||||
<AmisStyleCodeEditor
|
||||
{...props}
|
||||
onHide={() => setShowEditor(false)}
|
||||
/>
|
||||
) : (
|
||||
<AmisThemeCssCodeEditor
|
||||
{...props}
|
||||
onHide={() => setShowEditor(false)}
|
||||
/>
|
||||
)}
|
||||
</PopOver>
|
||||
</Overlay>
|
||||
</>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {PlainObject} from 'amis-core';
|
||||
import {parse as cssParse} from 'amis-postcss';
|
||||
import {isEmpty} from 'lodash';
|
||||
|
||||
const conf = {
|
||||
const conf: any = {
|
||||
ws: '[ \t\n\r\f]*',
|
||||
identifier:
|
||||
'-?-?([a-zA-Z]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))([\\w\\-]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))*',
|
||||
@ -3005,7 +3005,8 @@ const keywords: PlainObject = {
|
||||
}
|
||||
};
|
||||
|
||||
function validate(model: any, monaco: any) {
|
||||
function validate(editor: any, monaco: any) {
|
||||
const model = editor.getModel();
|
||||
const markers = [];
|
||||
const lineLen = model.getLineCount();
|
||||
for (let i = 1; i < lineLen + 1; i++) {
|
||||
@ -3060,81 +3061,90 @@ export default function editorFactory(
|
||||
monaco: any,
|
||||
options: any
|
||||
) {
|
||||
// 注册语言
|
||||
monaco.languages.register({id: 'amisTheme'});
|
||||
// 设置主题
|
||||
monaco.editor.defineTheme('amisTheme', {base: 'vs'});
|
||||
// 设置高亮
|
||||
monaco.languages.setMonarchTokensProvider('amisTheme', conf);
|
||||
// 设置提示
|
||||
monaco.languages.registerCompletionItemProvider('amisTheme', {
|
||||
provideCompletionItems: (model: any, position: any) => {
|
||||
const {lineNumber, column} = position;
|
||||
// 获取输入前的字符
|
||||
const textBeforePointer = model.getValueInRange({
|
||||
startLineNumber: lineNumber,
|
||||
startColumn: 0,
|
||||
endLineNumber: lineNumber,
|
||||
endColumn: column
|
||||
});
|
||||
// 如果已经配置了key和value就不给建议了
|
||||
if (/(.*):(.*);/.test(textBeforePointer)) {
|
||||
return {suggestions: []};
|
||||
}
|
||||
const token = /(.*):/.exec(textBeforePointer) || [];
|
||||
const valueTip = keywords[token[1]];
|
||||
let suggestions;
|
||||
if (!monaco.languages.getEncodedLanguageId('amisTheme')) {
|
||||
// 注册语言
|
||||
monaco.languages.register({id: 'amisTheme'});
|
||||
// 设置高亮
|
||||
monaco.languages.setMonarchTokensProvider('amisTheme', conf);
|
||||
// 设置提示
|
||||
monaco.languages.registerCompletionItemProvider('amisTheme', {
|
||||
provideCompletionItems: (model: any, position: any) => {
|
||||
const {lineNumber, column} = position;
|
||||
// 获取输入前的字符
|
||||
const textBeforePointer = model.getValueInRange({
|
||||
startLineNumber: lineNumber,
|
||||
startColumn: 0,
|
||||
endLineNumber: lineNumber,
|
||||
endColumn: column
|
||||
});
|
||||
// 如果已经配置了key和value就不给建议了
|
||||
if (/(.*):(.*);/.test(textBeforePointer)) {
|
||||
return {suggestions: []};
|
||||
}
|
||||
const token = /(.*):/.exec(textBeforePointer) || [];
|
||||
const valueTip = keywords[token[1]];
|
||||
let suggestions;
|
||||
|
||||
// 判断是需要提示key还是value
|
||||
if (valueTip) {
|
||||
suggestions = [
|
||||
...valueTip.values.map((k: string) => ({
|
||||
label: k,
|
||||
kind: monaco.languages.CompletionItemKind.Enum,
|
||||
insertText: k + ';'
|
||||
}))
|
||||
];
|
||||
} else {
|
||||
suggestions = [
|
||||
...Object.keys(keywords).map(k => ({
|
||||
label: k,
|
||||
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||
insertText: k + ': '
|
||||
}))
|
||||
];
|
||||
}
|
||||
// 判断是需要提示key还是value
|
||||
if (!isEmpty(valueTip)) {
|
||||
suggestions = [
|
||||
...valueTip.values.map((k: string) => ({
|
||||
label: k,
|
||||
kind: monaco.languages.CompletionItemKind.Enum,
|
||||
insertText: k + ';'
|
||||
}))
|
||||
];
|
||||
} else {
|
||||
suggestions = [
|
||||
...Object.keys(keywords).map(k => ({
|
||||
label: k,
|
||||
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||
insertText: k + ': '
|
||||
}))
|
||||
];
|
||||
}
|
||||
|
||||
return {
|
||||
suggestions: suggestions
|
||||
};
|
||||
},
|
||||
triggerCharacters: [' ']
|
||||
});
|
||||
|
||||
const model = monaco.editor.createModel('', 'amisTheme');
|
||||
|
||||
model.onDidChangeContent(() => {
|
||||
validate(model, monaco);
|
||||
});
|
||||
|
||||
return monaco.editor.create(containerElement, {
|
||||
model,
|
||||
language: 'amisTheme',
|
||||
options: {
|
||||
automaticLayout: true,
|
||||
lineNumbers: 'off',
|
||||
glyphMargin: false,
|
||||
tabSize: 2,
|
||||
wordWrap: 'on',
|
||||
lineDecorationsWidth: 0,
|
||||
lineNumbersMinChars: 0,
|
||||
selectOnLineNumbers: true,
|
||||
scrollBeyondLastLine: false,
|
||||
folding: true,
|
||||
minimap: {
|
||||
enabled: false
|
||||
return {
|
||||
suggestions: suggestions
|
||||
};
|
||||
},
|
||||
...options
|
||||
}
|
||||
triggerCharacters: [' ']
|
||||
});
|
||||
}
|
||||
// const uri = monaco.Uri.parse(options.uri.replace(/:/g, '-'));
|
||||
// let model: any = null;
|
||||
// try {
|
||||
// model = monaco.editor.createModel(options.value, 'amisTheme', uri);
|
||||
// } catch (error) {
|
||||
// model = monaco.editor.getModel(uri);
|
||||
// }
|
||||
|
||||
const editor = monaco.editor.create(containerElement, {
|
||||
...options,
|
||||
'language': 'amisTheme',
|
||||
'autoIndent': true,
|
||||
'formatOnType': true,
|
||||
'formatOnPaste': true,
|
||||
'selectOnLineNumbers': true,
|
||||
'scrollBeyondLastLine': false,
|
||||
'folding': true,
|
||||
'minimap': {
|
||||
enabled: false
|
||||
},
|
||||
'scrollbar': {
|
||||
alwaysConsumeMouseWheel: false
|
||||
},
|
||||
'bracketPairColorization.enabled': true,
|
||||
'automaticLayout': true,
|
||||
'lineNumbers': 'off',
|
||||
'glyphMargin': false,
|
||||
'wordWrap': 'on',
|
||||
'lineDecorationsWidth': 0,
|
||||
'lineNumbersMinChars': 0
|
||||
});
|
||||
editor.onDidChangeModelContent(() => {
|
||||
validate(editor, monaco);
|
||||
options.onChange && options.onChange(editor.getValue());
|
||||
});
|
||||
return editor;
|
||||
}
|
||||
|
@ -430,15 +430,23 @@ setSchemaTpl(
|
||||
'theme:cssCode',
|
||||
({
|
||||
themeClass = [],
|
||||
isFormItem
|
||||
isFormItem,
|
||||
isLayout
|
||||
}: {
|
||||
themeClass?: string[];
|
||||
themeClass?: any[];
|
||||
isFormItem?: boolean;
|
||||
} = {}) => {
|
||||
console.log(themeClass);
|
||||
themeClass.push('');
|
||||
if (isFormItem) {
|
||||
themeClass.push(...['description', 'label']);
|
||||
themeClass.push(
|
||||
...[
|
||||
{
|
||||
name: 'description',
|
||||
value: 'description',
|
||||
className: 'descriptionClassName'
|
||||
},
|
||||
{name: 'label', value: 'label', className: 'labelClassName'}
|
||||
]
|
||||
);
|
||||
}
|
||||
return {
|
||||
title: '样式源码',
|
||||
@ -581,8 +589,7 @@ setSchemaTpl(
|
||||
].filter(comp => !~exclude.indexOf(comp.type.replace(/^style-/i, '')))
|
||||
},
|
||||
{
|
||||
header: '样式',
|
||||
key: 'style',
|
||||
title: '自定义样式',
|
||||
body: [
|
||||
getSchemaTpl('theme:border', {
|
||||
name: 'style'
|
||||
@ -606,24 +613,14 @@ setSchemaTpl(
|
||||
]
|
||||
},
|
||||
{
|
||||
header: '圆角',
|
||||
key: 'radius',
|
||||
body: []
|
||||
},
|
||||
{
|
||||
header: '间距',
|
||||
key: 'box-model',
|
||||
body: []
|
||||
},
|
||||
{
|
||||
header: '背景',
|
||||
key: 'background',
|
||||
body: []
|
||||
},
|
||||
{
|
||||
header: '阴影',
|
||||
key: 'box-shadow',
|
||||
body: []
|
||||
title: '样式源码',
|
||||
body: [
|
||||
{
|
||||
type: 'theme-cssCode',
|
||||
label: false,
|
||||
isLayout: true
|
||||
}
|
||||
]
|
||||
}
|
||||
].filter(item =>
|
||||
include.length ? ~include.indexOf(item.key) : !~exclude.indexOf(item.key)
|
||||
|
Loading…
Reference in New Issue
Block a user