Merge branch 'master' into feat-context

This commit is contained in:
lvxiaojiao 2023-05-08 10:18:22 +08:00
commit 2241c50c0e
29 changed files with 436 additions and 44 deletions

View File

@ -1,18 +1,16 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<link rel="stylesheet" href="@fortawesome/fontawesome-free/css/all.css" />
<link
rel="stylesheet"
href="@fortawesome/fontawesome-free/css/v4-shims.css"
/>
<link rel="stylesheet" title="ang" href="amis-ui/scss/helper.scss" />
<link rel="stylesheet" href="@fortawesome/fontawesome-free/css/v4-shims.css" />
<!--DEPENDENCIES_INJECT_PLACEHOLDER-->
<!--STYLE_PLACEHOLDER-->
<link rel="stylesheet" title="ang" href="amis-ui/scss/themes/ang.scss" />
<link rel="stylesheet" title="cxd" href="amis-ui/scss/themes/cxd.scss" />
<link rel="stylesheet" title="dark" href="amis-ui/scss/themes/dark.scss" />
<link rel="stylesheet" title="antd" href="amis-ui/scss/themes/antd.scss" />
<link rel="stylesheet" title="helper" href="amis-ui/scss/helper.scss" />
</head>
<body>

View File

@ -5,5 +5,5 @@
"packages/amis-ui",
"packages/amis"
],
"version": "2.9.0"
"version": "3.0.0"
}

View File

@ -56,7 +56,7 @@ function mockResponse(event, context, callback) {
function createHeaders(headers) {
let referer = '';
if (/^(https?\:\/\/[^:\/]+(?:\:\d+)?\/)/i.test(headers['referer'])) {
if (/^(https?\:\/\/[^:\/]+(?:\:\d+)?\/)/i.test(headers['Referer'])) {
referer = RegExp.$1.replace(/\/$/, '');
}
@ -64,6 +64,7 @@ function createHeaders(headers) {
'Content-Type': 'Application/json',
'Access-Control-Allow-Headers': 'x-requested-with,content-type',
'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE,OPTIONS,HEAD',
'Access-Control-Allow-Origin': referer ? `${referer}` : '*'
'Access-Control-Allow-Origin': referer ? `${referer}` : '*',
'Access-Control-Allow-Credentials': 'true'
};
}

View File

@ -1,6 +1,6 @@
{
"name": "amis-core",
"version": "2.9.0",
"version": "3.0.0",
"description": "amis-core",
"main": "lib/index.js",
"module": "esm/index.js",
@ -45,7 +45,7 @@
"esm"
],
"dependencies": {
"amis-formula": "^2.9.0",
"amis-formula": "^3.0.0",
"classnames": "2.3.1",
"file-saver": "^2.0.2",
"hoist-non-react-statics": "^3.3.2",

View File

@ -1,4 +1,4 @@
import {Evaluator, parse} from 'amis-formula';
import {Evaluator, parse, evaluateForAsync} from 'amis-formula';
export const tokenize = (
str: string,
@ -24,3 +24,27 @@ export const tokenize = (
return str;
}
};
export const asyncTokenize = async (
str: string,
data: object,
defaultFilter: string = '| html'
) => {
if (!str || typeof str !== 'string') {
return str;
}
try {
const ast = parse(str, {
evalMode: false,
allowFilter: true
});
const result = await evaluateForAsync(ast, data, {defaultFilter});
return `${result == null ? '' : result}`;
} catch (e) {
console.warn(e);
return str;
}
};

View File

@ -13,7 +13,7 @@ import {filterDate, parseDuration, relativeValueRe} from './date';
import {pickValues} from './object';
import {isPureVariable} from './isPureVariable';
import {stripNumber} from './stripNumber';
import {tokenize} from './tokenize';
import {tokenize, asyncTokenize} from './tokenize';
import {resolveVariable} from './resolveVariable';
import {resolveVariableAndFilter} from './resolveVariableAndFilter';
import {resolveVariableAndFilterForAsync} from './resolveVariableAndFilterForAsync';
@ -83,6 +83,17 @@ export function register(): Enginer & {name: string} {
} catch (e) {
return `error: ${e.message}`;
}
},
asyncCompile: async (
str: string,
data: object,
defaultFilter = '| html'
) => {
try {
return asyncTokenize(str, data, defaultFilter);
} catch (e) {
return `error: ${e.message}`;
}
}
};
}

View File

@ -60,6 +60,7 @@ export function register(): Enginer & {name: string} {
return {
name: 'lodash',
test: (str: string) => !!~str.indexOf('<%'),
compile: (str: string, data: object) => lodashCompile(str, data)
compile: (str: string, data: object) => lodashCompile(str, data),
asyncCompile: (str: string, data: object) => lodashCompile(str, data)
};
}

View File

@ -7,6 +7,11 @@ export interface Enginer {
test: (tpl: string) => boolean;
removeEscapeToken?: (tpl: string) => string;
compile: (tpl: string, data: object, ...rest: Array<any>) => string;
asyncCompile: (
tpl: string,
data: object,
...rest: Array<any>
) => Promise<string>;
}
const enginers: {
@ -39,6 +44,28 @@ export function filter(
return tpl;
}
export function asyncFilter(
tpl?: any,
data: object = {},
...rest: Array<any>
): Promise<string> {
if (!tpl || typeof tpl !== 'string') {
return Promise.resolve('');
}
let keys = Object.keys(enginers);
for (let i = 0, len = keys.length; i < len; i++) {
let enginer = enginers[keys[i]];
if (enginer.test(tpl)) {
return enginer.asyncCompile(tpl, data, ...rest);
} else if (enginer.removeEscapeToken) {
tpl = enginer.removeEscapeToken(tpl);
}
}
return tpl;
}
// 缓存一下提升性能
const EVAL_CACHE: {[key: string]: Function} = {};
@ -175,6 +202,7 @@ export function evalJS(js: string, data: object): any {
registerTplEnginer(info.name, {
test: info.test,
compile: info.compile,
asyncCompile: info.asyncCompile,
removeEscapeToken: info.removeEscapeToken
});
});

View File

@ -30,8 +30,8 @@ module.exports = {
path: './'
},
translate: {
appId: '20220902001329332',
key: 'pVS96QbIzVROBSOarU4R',
appId: '20230324001613652', // 私人翻译账户,如有国际化需求,请申请自己的百度翻译服务
key: 'Sprp7Mz8_yydeyhYrgE0',
host: 'http://api.fanyi.baidu.com'
}
};

View File

@ -1,6 +1,6 @@
{
"name": "amis-editor-core",
"version": "5.2.5-alpha.16",
"version": "5.3.0",
"description": "amis 可视化编辑器",
"main": "lib/index.js",
"module": "esm/index.js",
@ -83,6 +83,7 @@
"concurrently": "^6.2.0",
"css-loader": "^6.2.0",
"faker": "^5.5.3",
"i18n-command": "^0.0.23-beta.15",
"mini-css-extract-plugin": "^2.3.0",
"postcss-import": "^14.1.0",
"postcss-minify": "^1.1.0",
@ -111,8 +112,8 @@
"amis": "*",
"amis-core": "*",
"amis-formula": "*",
"amis-ui": "*",
"amis-theme-editor-helper": "*",
"amis-ui": "*",
"i18n-runtime": "*",
"react": ">=16.8.6",
"react-dom": ">=16.8.6"

View File

@ -264,5 +264,8 @@ extendLocale('en-US', {
'5b804b05e14aaacc75033a4f77fc2844': 'Source code',
'69a53230577258b6d97ee932befcc168': '<Column>:',
'cc6aeb073ebc3cb29734a49164f8964c': 'Page variables',
'b71e8739cb9bcba8057a8fa8b59512da': '<Column>'
'b71e8739cb9bcba8057a8fa8b59512da': '<Column>',
'34d240d1ded259c32f7fee21e99c5671': 'Preview/Edit',
'6722089d251c1e4aabe9d58c26a2208a': 'Turn preview mode on/off',
'107542a61cdccbb2981ad0c8bafc3440': 'Replace component'
});

View File

@ -236,5 +236,8 @@ extendLocale('zh-CN', {
'5b804b05e14aaacc75033a4f77fc2844': '源码',
'69a53230577258b6d97ee932befcc168': '<列>:',
'cc6aeb073ebc3cb29734a49164f8964c': '页面变量',
'b71e8739cb9bcba8057a8fa8b59512da': '<列>'
'b71e8739cb9bcba8057a8fa8b59512da': '<列>',
'34d240d1ded259c32f7fee21e99c5671': '预览/编辑',
'6722089d251c1e4aabe9d58c26a2208a': '开启/关闭预览模式',
'107542a61cdccbb2981ad0c8bafc3440': '替换组件'
});

View File

@ -335,10 +335,15 @@ export class EditorManager {
| PluginClass
| [PluginClass, Record<string, any> | (() => Record<string, any>)]
>
) {
): (
| PluginClass
| [PluginClass, Record<string, any> | (() => Record<string, any>)]
)[] {
return (
plugins?.map(klass => {
let options;
if (Array.isArray(klass)) {
options = klass[1];
klass = klass[0];
}
@ -347,7 +352,7 @@ export class EditorManager {
new Set(['global'].concat(klass.scene || 'global'))
);
klass.scene = scene;
return klass;
return options ? [klass, options] : klass;
}) || []
);
}

View File

@ -30,8 +30,8 @@ module.exports = {
path: './'
},
translate: {
appId: '20220902001329332',
key: 'pVS96QbIzVROBSOarU4R',
appId: '20230324001613652', // 私人翻译账户,如有国际化需求,请申请自己的百度翻译服务
key: 'Sprp7Mz8_yydeyhYrgE0',
host: 'http://api.fanyi.baidu.com'
}
};

View File

@ -1,6 +1,6 @@
{
"name": "amis-editor",
"version": "5.2.5-alpha.16",
"version": "5.3.0",
"description": "amis 可视化编辑器",
"main": "lib/index.js",
"module": "esm/index.js",
@ -74,6 +74,7 @@
"concurrently": "^6.2.0",
"css-loader": "^6.2.0",
"faker": "^5.5.3",
"i18n-command": "^0.0.23-beta.15",
"mini-css-extract-plugin": "^2.3.0",
"prettier": "^2.2.1",
"react": "^18.2.0",

View File

@ -3850,5 +3850,123 @@ extendLocale('en-US', {
'6922790f45faf064e063069816e4d2ec':
'After opening, all the original data will be flattened and set in the data, and customized on this basis',
'9791b05a4df9d72f1a01b81fa695fbc6':
'When the grouping names of multiple columns are consistent, the table will display the super header on the upper layer of the display header.<a href=“ https://baidu.github.io/amis/zh-CN/components/table#%E8%B6%85%E7%BA%A7%E8%A1%A8%E5%A4%B4 " target="_ Blank ">Example</a>'
'When the grouping names of multiple columns are consistent, the table will display the super header on the upper layer of the display header.<a href=“ https://baidu.github.io/amis/zh-CN/components/table#%E8%B6%85%E7%BA%A7%E8%A1%A8%E5%A4%B4 " target="_ Blank ">Example</a>',
'7441768e25f67a80f0f2173c2a618c35': 'Date value',
'8036cf5e8dbf62ee4f4e896f7354ce5c': 'Date Time Value',
'598f69a9b640508d8e124fd7d33131f0': 'Select icon',
'ef79da787ad206e5d5f8cf62e195c836': 'Icon size',
'ff58428ef8221c4c1bbf532dd3c77113': 'Icon Bottom Margin',
'88f109195ad926bcd436f0c56198240d': 'Image upload button',
'd825ba2b8ea0c1b0737b0dd5ca9bc128': 'Upload icon',
'bade9c4e0b8a75a251c1a2760571d3c3': 'Number Input Box Style',
'53069052573de671c6e5108de745b036': 'Number input box',
'5c48fa6f337d2b5dd168a0887c6baa2b': 'Table Form Data',
'fb7b49ff7f85f6e3f995b5eaae42d084': 'Label selection',
'0aefac04b467ce313ca6b05e33c6145a': 'Maximum Word Count',
'188676cb26835b8e4d8ea568467c55cd': 'Limit the maximum number of text input',
'f1ee660e12ef0b76c10cccc3d923e605':
'AK cannot be empty, please visit http://lbsyun.baidu.com/ Obtain Key (AK)',
'4d01bb9f50eb1480e0e9995a2a003181':
'Please select<a href=“ http://lbsyun.baidu.com/ " target="_ Blank "class=" text sm ">Baidu Maps open platform</a>Get',
'f1f7a5f821ca0ee4caaa9324eda48d91': 'Static Form Item',
'4602761ee85e2e6e5360cd13fe642a08':
'<p>The current component has stopped maintenance. It is recommended that you use the new feature of<a="/amis/zh CN/components/form/formitem #% E9% 85% 8D% E7% BD% AE% E9% 9D% 99% E6% 80% 81% E5% B1% 95% E7% A4% BA" target="_blank">static display</a>to achieve static display of form items</ p>',
'6ca92e3386f9e392584367df5054c27c':
'Used to display an icon, you can configure different icon styles.',
'47fd366b711a0567646854f541449f8b':
'For example: ${listVar}, used to associate existing data in the scope',
'98204720c30a843a9234bdf22dc05d51': 'Elastic Layout Settings',
'3212f1de74130815d12d982437fc6919': 'Document Preview',
'a7199769ae58f8a5c35ac0e5f8804abf': 'Office Document Preview',
'e414473c886072e393710563f201d7f3': 'Printing',
'6a62d33c838524f0609a624aa59ee9e7': 'print a document',
'f26ef914245883c80f181c4aade2ed04': 'download',
'fc856cd721f5b5955f8c4be2767a1cee': 'Download Documents',
'270c7dfc38ec1f8eb7b211481d26659a': 'Document Address',
'2bd4fa4fe6637a09add46354f52ea9dc': 'Whether to render',
'010787d733c97c5f7a8f9bda438af9e2': 'Word rendering configuration',
'9a50cbc2f0c7115043a19c3b1db5776b': 'Ignore width',
'927ed823f52a6d3bbceed4436636a7dd': 'Page Inner Margin',
'755ea661684e7bffe9f97fb07b8d4921': 'List using font',
'9b87dc5a019f749722a1d3a9c854a2b9': 'Variable Replacement',
'c6adeba660df8e19ac6cd3b8c57416ad': 'Forced row height',
'b93ea0046d63e2df7cf24a7a63bf5c99': 'Font Mapping',
'f6e9b56f97af64235bf81f4ddc2288ab': 'Whether to enable pagination rendering',
'4c71a09da7ce050d45514b68bb15b4ab': 'Page Top and Bottom Margins',
'3651c159e19c05a3bdaa7036dac91e4e': 'Page background color',
'91bc444339545a7785f3aa3055d9ba05': 'Show page shadows',
'c856051e8c80913ff6607dc880341a20': 'Whether to display page packages',
'6a6772a0eae27591ed8763b6e616e988': 'Page Wrap Width',
'22bca073daae505d7fc9e7d7c8ee047c': 'Page Wrap Background Color',
'2839785a190e062058635add192f961d': 'Zoom ratio',
'9723e66141840db4dc6bd1db9b165302': 'Adaptive width',
'b7dd79307fb7bcc921aa1b94ef904fe9': 'Behavior button',
'c3e817974de836e80c95cc6ce5718eff': 'Search box',
'83fe6a5db780fcfa68f3336c7d86f25b':
'Used to display a simple search box, usually used in conjunction with other components. For example, after configuring initApi on the page, it can be used to achieve simple data filtering and lookup, and name keywords will be passed as parameters to initApi on the page.',
'bb50b53491c2c43845c58b16e48c27f3': 'Search box content',
'68a896ef9627fea8cd84f3fa4f7269aa': 'Click Search',
'a7be3c702997f49cf9429240fbbc5e36':
'Triggered when clicking on the search icon',
'1c113a8c88ba15fc1ff04ea410e63f33': 'Search Content',
'0796ba76b4b553687e5ffaeb78512ccb': 'Basics',
'218bcea849478df7335ac31072860e8e': 'Search immediately after clearing',
'a48b511d5da79faf6f7f58c5470738f0': 'Search Now',
'71c198baa12405e56705a3c68f66e3ef': 'Mini version',
'b814fb5782f733a22ee561397ad376fc': 'Strengthen Style',
'87d88a457161f2a09f95f6aa29b38051': 'Step Bar',
'2a9a1329b191c2787b1a70c289e3bbe0': 'vertical',
'd517acb68fbed2331b57d1a11ca21dcc': 'simple',
'341fe804cc8b65dc17a31c7a25a90444': 'Label Name',
'd04f139ee0fb6fac19ccaec0f7b323df': 'Click to close',
'fe7967a547915be9ae4083ed50c3b94a': 'Triggered when clicked to close',
'b624985146c759cfeb1be80325eccd65': 'Text prompt',
'6d8e3115be41a8a5690d6fefa637dac7':
'The data returned by the interface needs to conform to the following format, with status, msg, and data as necessary fields',
'09212e946a4d9b0f775700c46ef0dcd5':
'Returning 0 indicates that the current interface is returning correctly, otherwise it will be processed as an error request',
'7391774e57425e5d8e83de64100b5f2e':
'Returns interface processing information, mainly used for displaying the toast when a form submission or request fails',
'fa385c23820ee9999c82035086baa772':
'Must return an object with a key value structure',
'6494bc042d99f2f5de34a858b8a699c6':
'Verification interface return format field description:',
'e6246c03148f553e5d6a66adbdabb9f8':
'Returning 0 indicates successful verification, 422 indicates failed verification',
'b8079b9d1e6d3e8a457787910a75cce4':
'When the return status is 422, the displayed verification failure message',
'a59c65bea7d5065f19eb9c918a716c33':
'The modified API object must be returned.',
'05fb5edb84e41c19b0f5429fff20b834': 'Return adapter',
'98498eb59e87ec9a0eaf98ac55628da9':
"The current request's response payload, which is response.data",
'ed33c46d1d69336bb011813e8352fa01': 'horizontal direction',
'963e9ff4252cdef288063c41eb6d4998': 'vertical direction',
'4117e80d2c2e52f795ec64160f399364': 'Vertically centered',
'd365d58d281508b9982f6a0370649ae2': 'horizontally',
'21af94c1abc5891b2703c9321417a1a9': 'Interval distribution',
'849b9b944a65eb0685f3e6af60a0c523': 'Horizontal spreading',
'50334fc77fc5a2c2636f14f158d3c417': 'Context variables',
'7f05bea37729325a6cc84eb26bb9f8c8': 'Please enter the subscript text',
'bc3f5a690d8c3a47d27ef8a1b127bafc':
'Hidden options cannot be set as default values',
'240a19929878c26f5e4c41c08f63cd1c': 'Interface verification',
'c6f30c2f084ddeacb7944235348bdaa4': 'Memory variables',
'fa6b01f51cc2b8e16bfbb914b6c08ace': 'Confirmation dialog box',
'4cb9c4bc5cb960fcd03fceb2d2e62f3a': 'Drawer Title',
'fd2bed5e9a84273b22f79950a0a1807f': 'Suspended Style',
'1daee167a43c72dbe9e31e955b670b4f': 'Click on Style',
'd117954f3769008ef22b864060913c65': 'Disabled Style',
'd37c4140bd531fc117e91e727d7e576c': 'Normal state style',
'0371c0e05806c01e5ce2f26e9e2e39c8': 'Edit Style Source Code',
'bb7654f7c2768614e95a0da7e94f4045': 'Expected colon',
'af26fdb215bad5b2296529802b129c12': 'Expected attribute',
'3955b2e2e06144010a1142d3624b17b1': 'Missing semicolon',
'052f7eec7ca35a6b4d72d169ee1de494': 'Please enter an expression',
'10710f1c01d960a3ffde384115296026': 'Block level',
'26b10072a4e0c8c9a3a1142db3d7b3b4': 'Inline block',
'2c7fe494c99c94ba5965f963fd7d3a4c': 'Inline element',
'39353c2b258e4bc73d8dd6a46f0a7955': 'Flexible layout (flex)',
'553333a72dec41b54e8ed18d49453a76': 'Select the first item by default',
'86bf16f0cb7fd8b1fef2e1439e06b632': 'Style source code'
});

View File

@ -3431,5 +3431,135 @@ extendLocale('zh-CN', {
'6922790f45faf064e063069816e4d2ec':
'开启后,会将所有原始数据打平设置到 data 中,并在此基础上定制',
'9791b05a4df9d72f1a01b81fa695fbc6':
'当多列的分组名称设置一致时,表格会在显示表头的上层显示超级表头,<a href="https://baidu.github.io/amis/zh-CN/components/table#%E8%B6%85%E7%BA%A7%E8%A1%A8%E5%A4%B4" target="_blank">示例</a>'
'当多列的分组名称设置一致时,表格会在显示表头的上层显示超级表头,<a href="https://baidu.github.io/amis/zh-CN/components/table#%E8%B6%85%E7%BA%A7%E8%A1%A8%E5%A4%B4" target="_blank">示例</a>',
'7441768e25f67a80f0f2173c2a618c35': '日期值',
'8036cf5e8dbf62ee4f4e896f7354ce5c': '日期时间值',
'598f69a9b640508d8e124fd7d33131f0': '选择图标',
'ef79da787ad206e5d5f8cf62e195c836': '图标大小',
'ff58428ef8221c4c1bbf532dd3c77113': '图标底边距',
'88f109195ad926bcd436f0c56198240d': '图片上传按钮',
'd825ba2b8ea0c1b0737b0dd5ca9bc128': '上传图标',
'bade9c4e0b8a75a251c1a2760571d3c3': '数字输入框样式',
'53069052573de671c6e5108de745b036': '数字输入框',
'5c48fa6f337d2b5dd168a0887c6baa2b': '表格表单数据',
'fb7b49ff7f85f6e3f995b5eaae42d084': '标签选择',
'0aefac04b467ce313ca6b05e33c6145a': '最大字数',
'188676cb26835b8e4d8ea568467c55cd': '限制输入最多文字数量',
'f1ee660e12ef0b76c10cccc3d923e605':
'AK不能为空请访问http://lbsyun.baidu.com/获取密钥(AK)',
'4d01bb9f50eb1480e0e9995a2a003181':
'请从<a href="http://lbsyun.baidu.com/" target="_blank" class="text-sm">百度地图开放平台</a>获取',
'f1f7a5f821ca0ee4caaa9324eda48d91': '静态表单项',
'4602761ee85e2e6e5360cd13fe642a08':
'<p>当前组件已停止维护,建议您使用<a href="/amis/zh-CN/components/form/formitem#%E9%85%8D%E7%BD%AE%E9%9D%99%E6%80%81%E5%B1%95%E7%A4%BA" target="_blank">静态展示</a>新特性实现表单项的静态展示。</p>',
'6ca92e3386f9e392584367df5054c27c':
'用来展示一个图标,你可以配置不同的图标样式。',
'47fd366b711a0567646854f541449f8b':
'比如:\\${listVar},用来关联作用域中的已有数据',
'98204720c30a843a9234bdf22dc05d51': '弹性布局设置',
'3212f1de74130815d12d982437fc6919': '文档预览',
'a7199769ae58f8a5c35ac0e5f8804abf': 'Office 文档预览',
'e414473c886072e393710563f201d7f3': '打印',
'6a62d33c838524f0609a624aa59ee9e7': '打印文档',
'f26ef914245883c80f181c4aade2ed04': '下载',
'fc856cd721f5b5955f8c4be2767a1cee': '下载文档',
'270c7dfc38ec1f8eb7b211481d26659a': '文档地址',
'2bd4fa4fe6637a09add46354f52ea9dc': '是否渲染',
'010787d733c97c5f7a8f9bda438af9e2': 'Word 渲染配置',
'9a50cbc2f0c7115043a19c3b1db5776b': '忽略宽度',
'927ed823f52a6d3bbceed4436636a7dd': '页面内边距',
'755ea661684e7bffe9f97fb07b8d4921': '列表使用字体',
'9b87dc5a019f749722a1d3a9c854a2b9': '变量替换',
'c6adeba660df8e19ac6cd3b8c57416ad': '强制行高',
'b93ea0046d63e2df7cf24a7a63bf5c99': '字体映射',
'f6e9b56f97af64235bf81f4ddc2288ab': '是否开启分页渲染',
'4c71a09da7ce050d45514b68bb15b4ab': '页上下边距',
'3651c159e19c05a3bdaa7036dac91e4e': '页背景色',
'91bc444339545a7785f3aa3055d9ba05': '是否显示页面阴影',
'c856051e8c80913ff6607dc880341a20': '是否显示页面包裹',
'6a6772a0eae27591ed8763b6e616e988': '页面包裹宽度',
'22bca073daae505d7fc9e7d7c8ee047c': '页面包裹背景色',
'2839785a190e062058635add192f961d': '缩放比例',
'9723e66141840db4dc6bd1db9b165302': '自适应宽度',
'b7dd79307fb7bcc921aa1b94ef904fe9': '行为按钮',
'c3e817974de836e80c95cc6ce5718eff': '搜索框',
'83fe6a5db780fcfa68f3336c7d86f25b':
'用于展示一个简单搜索框,通常需要搭配其他组件使用。比如 page 配置 initApi 后可以用来实现简单数据过滤查找name keywords 会作为参数传递给 page 的 initApi。',
'bb50b53491c2c43845c58b16e48c27f3': '搜索框内容',
'68a896ef9627fea8cd84f3fa4f7269aa': '点击搜索',
'a7be3c702997f49cf9429240fbbc5e36': '点击搜索图标时触发',
'1c113a8c88ba15fc1ff04ea410e63f33': '搜索内容',
'0796ba76b4b553687e5ffaeb78512ccb': '基础',
'218bcea849478df7335ac31072860e8e': '清除后立即搜索',
'a48b511d5da79faf6f7f58c5470738f0': '立即搜索',
'71c198baa12405e56705a3c68f66e3ef': 'mini版本',
'b814fb5782f733a22ee561397ad376fc': '加强样式',
'87d88a457161f2a09f95f6aa29b38051': '步骤条',
'2a9a1329b191c2787b1a70c289e3bbe0': '竖直',
'd517acb68fbed2331b57d1a11ca21dcc': '简单',
'341fe804cc8b65dc17a31c7a25a90444': '标签名称',
'd04f139ee0fb6fac19ccaec0f7b323df': '点击关闭',
'fe7967a547915be9ae4083ed50c3b94a': '点击关闭时触发',
'b624985146c759cfeb1be80325eccd65': '文字提示',
'717b9f738e2da460071b1b5ae7cc0e06':
"{\n url: string; // 当前接口地址\n method: 'get' | 'post' | 'put' | 'delete';\n data?: Object; // 请求体\n headers?: Object; // 请求头\n ...\n}",
'd1bfe86cb1776358c5ed50bc137a2b7a':
'{\n data: Object; // 接口返回数据,\n request: XMLHttpRequest;\n headers?: Object; // 请求头\n status: number; // 状态码 200, 404, 500..\n statusText: string; // 状态信息\n ...\n}',
'd3b13672e0e24d1490b2564ae7f6da4e':
"// API响应或自定义处理后需要符合以下格式\nreturn {\n status: 0, // 0 表示请求成功,否则按错误处理\n msg: '请求成功',\n data: {\n text: 'world',\n items: [\n {label: '张三', value: 1}\n ]\n }\n}",
'36d7adab7769ff6741b2860f041e56d2':
"// 校验成功\nreturn {\n status: 0\n};\n\n// 校验失败\nreturn {\n status: 422,\n errors: '当前用户已存在'\n}",
'0228c8f19830732b523a58a2ee0bbcfd':
'{\n "status": 0,\n "msg": "",\n "data": {\n // ...其他字段\n }\n}',
'6d8e3115be41a8a5690d6fefa637dac7':
'接口返回数据需要符合以下格式, status、msg、data 为必要字段',
'09212e946a4d9b0f775700c46ef0dcd5':
'返回 0 表示当前接口正确返回,否则按错误请求处理',
'7391774e57425e5d8e83de64100b5f2e':
'返回接口处理信息,主要用于表单提交或请求失败时的 toast 显示',
'fa385c23820ee9999c82035086baa772': '必须返回一个具有 key-value 结构的对象',
'6494bc042d99f2f5de34a858b8a699c6': '校验接口返回格式字段说明:',
'e6246c03148f553e5d6a66adbdabb9f8': '返回 0 表示校验成功422 表示校验失败',
'b8079b9d1e6d3e8a457787910a75cce4':
'返回 status 为 422 时,显示的校验失败信息',
'9d49f04a3affb34a31bb157e4887cbe7':
'可基于 JavaScript 语言直接录入发送适配器的函数体,在该函数体内,您可以对 <span style="color: #108CEE">api</span> 进行处理或者返回新的内容,最后需要 <span style="color: #108CEE">return</span> <span style="color: #108CEE">api</span>。<br><br/>\n 函数体内可访问的变量如下:<br/>\n &nbsp;1. <span style="color: #108CEE">api</span>接口的schema配置对象<br/>\n &nbsp;2. <span style="color: #108CEE">api.data</span>:请求数据<br/>\n &nbsp;3. <span style="color: #108CEE">api.query</span>:请求查询参数<br/>\n &nbsp;4. <span style="color: #108CEE">api.body</span>请求体针对POST/PUT/PATCH<br/>\n &nbsp;5. <span style="color: #108CEE">api.headers</span>:请求头<br/>\n &nbsp;6. <span style="color: #108CEE">api.url</span>:请求地址<br/>',
'a59c65bea7d5065f19eb9c918a716c33': '必须将修改好的 api 对象 return 出去。',
'05fb5edb84e41c19b0f5429fff20b834': '返回适配器',
'44af993b124817085dc2579a9f842d55':
'可基于 JavaScript 语言直接录入返回适配器的函数体,在函数体内,您可以对 <span style="color: #108CEE">payload</span> 进行处理或者返回新的内容,最后需要 <span style="color: #108CEE">return</span> 接口最终的返回结果。<br><br/>\n 函数体内可访问的变量如下:<br/>\n &nbsp;1. <span style="color: #108CEE">payload</span>:接口的返回结果<br/>\n &nbsp;2. <span style="color: #108CEE">response</span>接口的response对象<br/>\n &nbsp;3. <span style="color: #108CEE">api</span>接口的schema配置对象<br/>',
'98498eb59e87ec9a0eaf98ac55628da9':
'当前请求的响应 payload即 response.data',
'ed33c46d1d69336bb011813e8352fa01': '水平方向',
'963e9ff4252cdef288063c41eb6d4998': '垂直方向',
'4117e80d2c2e52f795ec64160f399364': '垂直居中',
'd365d58d281508b9982f6a0370649ae2': '水平居中',
'21af94c1abc5891b2703c9321417a1a9': '间隔分布',
'849b9b944a65eb0685f3e6af60a0c523': '水平铺开',
'50334fc77fc5a2c2636f14f158d3c417': '上下文变量',
'7f05bea37729325a6cc84eb26bb9f8c8': '请输入角标文本',
'bc3f5a690d8c3a47d27ef8a1b127bafc': '隐藏选项不能设为默认值',
'240a19929878c26f5e4c41c08f63cd1c': '接口校验',
'ae7ca6f3dec57a73ddc145a7094adc97':
'配置校验接口,对表单项进行远程校验,配置方式与普通接口一致<br />\n 1. 接口返回 <span class="ae-ValidationControl-label-code">{status: 0}</span> 表示校验通过<br />\n 2. 接口返回 <span class="ae-ValidationControl-label-code">{status: 422}</span> 表示校验不通过<br />\n 3. 若校验失败时需要显示错误提示信息,还需返回 errors 字段,示例<br />\n <span class="ae-ValidationControl-label-code">{status: 422, errors: \'错误提示消息\'}</span>\n ',
'c6f30c2f084ddeacb7944235348bdaa4': '内存变量',
'fa6b01f51cc2b8e16bfbb914b6c08ace': '确认对话框',
'4cb9c4bc5cb960fcd03fceb2d2e62f3a': '抽屉标题',
'fbaa94ca6b6e6e76a07124e80733f109':
"/* 自定义JS使用说明\n * 1.动作执行函数doAction可以执行所有类型的动作\n * 2.通过上下文对象context可以获取当前组件实例例如context.props可以获取该组件相关属性\n * 3.事件对象event在doAction之后执行event.stopPropagation();可以阻止后续动作执行\n*/\nconst myMsg = '我是自定义JS';\ndoAction({\n actionType: 'toast',\n args: {\n msg: myMsg\n }\n});\n",
'fd2bed5e9a84273b22f79950a0a1807f': '悬浮态样式',
'1daee167a43c72dbe9e31e955b670b4f': '点击态样式',
'd117954f3769008ef22b864060913c65': '禁用态样式',
'd37c4140bd531fc117e91e727d7e576c': '常规态样式',
'0371c0e05806c01e5ce2f26e9e2e39c8': '编辑样式源码',
'bb7654f7c2768614e95a0da7e94f4045': '应为冒号',
'af26fdb215bad5b2296529802b129c12': '应为属性',
'3955b2e2e06144010a1142d3624b17b1': '缺少分号',
'052f7eec7ca35a6b4d72d169ee1de494': '请输入表达式',
'10710f1c01d960a3ffde384115296026': '块级(block)',
'26b10072a4e0c8c9a3a1142db3d7b3b4': '行内区块(inline-block)',
'2c7fe494c99c94ba5965f963fd7d3a4c': '行内元素(inline)',
'39353c2b258e4bc73d8dd6a46f0a7955': '弹性布局(flex)',
'553333a72dec41b54e8ed18d49453a76': '默认选择第一项',
'86bf16f0cb7fd8b1fef2e1439e06b632': '样式源码'
});

View File

@ -1,6 +1,6 @@
{
"name": "amis-formula",
"version": "2.9.0",
"version": "3.0.0",
"description": "负责 amis 里面的表达式实现,内置公式,编辑器等",
"main": "lib/index.js",
"module": "esm/index.js",

View File

@ -3,7 +3,7 @@
"main": "lib/index.js",
"module": "esm/index.js",
"types": "lib/index.d.ts",
"version": "2.9.0",
"version": "3.0.0",
"description": "",
"scripts": {
"build": "npm run clean-dist && NODE_ENV=production rollup -c ",
@ -35,8 +35,8 @@
},
"dependencies": {
"@rc-component/mini-decimal": "^1.0.1",
"amis-core": "^2.9.0",
"amis-formula": "^2.9.0",
"amis-core": "^3.0.0",
"amis-formula": "^3.0.0",
"classnames": "2.3.1",
"codemirror": "^5.63.0",
"downshift": "6.1.12",

View File

@ -44,6 +44,11 @@
box-shadow: var(--Form-input-boxShadow);
}
.is-error > & {
border-color: var(--Form-input-onError-borderColor);
background: var(--Form-input-onError-bg);
}
&.is-disabled {
background: var(--ColorPicker-onDisabled-bg);
color: var(--ColorPicker-onDisabled-color);

View File

@ -64,6 +64,11 @@
}
}
.is-error > & {
border-color: var(--Form-input-onError-borderColor);
background: var(--Form-input-onError-bg);
}
.#{$ns}DateRangePicker-input {
border: none;
border-bottom: var(--DateRangePicker-activeCursor-height) solid transparent;

View File

@ -88,6 +88,11 @@
}
}
.is-error > & {
border-color: var(--Form-input-onError-borderColor);
background: var(--Form-input-onError-bg);
}
&.is-disabled {
background: var(--inputDate-disabled-bg-color);
border-width: var(--inputDate-disabled-top-border-width)

View File

@ -246,6 +246,11 @@
color: var(--Number-handler-onDisabled-color);
}
.is-error > & {
border-color: var(--Form-input-onError-borderColor);
background: var(--Form-input-onError-bg);
}
&-disabled {
border-color: var(--Form-input-onDisabled-borderColor);
.#{$ns}Number-input {

View File

@ -104,6 +104,10 @@
}
}
}
&.is-error > .#{$ns}ResultBox {
border-color: var(--Form-input-onError-borderColor);
background: var(--Form-input-onError-bg);
}
}
.#{$ns}TagControl-popover {

View File

@ -236,6 +236,8 @@ test('Renderer:InputSubForm with draggable & addable & removable', async () => {
fireEvent.click(values[0].querySelector('.cxd-SubForm-valueDel')!);
await wait(200);
values = container.querySelectorAll('.cxd-SubForm-values .cxd-SubForm-value');
expect(values!.length).toBe(3);

View File

@ -551,7 +551,7 @@ test('Renderer:Page initApi sendOn -> false', async () => {
expect(fetcher).not.toHaveBeenCalled();
});
test('Renderer:Page location query', () => {
test('Renderer:Page location query', async () => {
const history = createMemoryHistory({
initialEntries: ['/xxx?a=5']
});
@ -584,6 +584,7 @@ test('Renderer:Page location query', () => {
)
);
await wait(300);
expect(component.toJSON()).toMatchSnapshot();
});
@ -1002,6 +1003,7 @@ test('Renderer:Page handleAction actionType=ajax & feedback', async () => {
await waitFor(() => {
expect(getByText('确认')).toBeInTheDocument();
});
await wait(300);
expect(container).toMatchSnapshot();
fireEvent.click(getByText(/确认/));

View File

@ -79,6 +79,7 @@ test('Renderer:Progress with map', async () => {
})
);
await wait(200);
expect(container).toMatchSnapshot();
expect(container.querySelector('.cxd-Progress-line-bar')!).toHaveStyle({
'background-color': 'rgb(249, 109, 62)'
@ -203,6 +204,7 @@ test('Renderer:Progress with mode', async () => {
})
);
await wait(200);
// gapDegree 与 gapPosition 无法验证,因为是 svg
expect(container).toMatchSnapshot();
});

View File

@ -1,6 +1,6 @@
{
"name": "amis",
"version": "2.9.0",
"version": "3.0.0",
"description": "一种MIS页面生成工具",
"main": "lib/index.js",
"module": "esm/index.js",
@ -36,8 +36,8 @@
}
],
"dependencies": {
"amis-core": "^2.9.0",
"amis-ui": "^2.9.0",
"amis-core": "^3.0.0",
"amis-ui": "^3.0.0",
"attr-accept": "2.2.2",
"blueimp-canvastoblob": "2.1.0",
"classnames": "2.3.1",

View File

@ -1,6 +1,6 @@
import React from 'react';
import {autobind, createObject, Renderer, RendererProps} from 'amis-core';
import {filter} from 'amis-core';
import {filter, asyncFilter} from 'amis-core';
import cx from 'classnames';
import {anyChanged, getPropValue} from 'amis-core';
import {escapeHtml} from 'amis-core';
@ -52,7 +52,11 @@ export interface TplProps extends RendererProps, TplSchema {
value?: string;
}
export class Tpl extends React.Component<TplProps, object> {
interface TplState {
content: string;
}
export class Tpl extends React.Component<TplProps, TplState> {
static defaultProps: Partial<TplProps> = {
inline: true,
placeholder: ''
@ -62,8 +66,33 @@ export class Tpl extends React.Component<TplProps, object> {
constructor(props: TplProps) {
super(props);
this.state = {
content: this.getContent()
};
}
componentDidUpdate(prevProps: Readonly<TplProps>): void {
const checkProps = ['tpl', 'html', 'text', 'raw', 'data', 'placeholder'];
if (
checkProps.some(key => prevProps[key] !== this.props[key]) ||
getPropValue(prevProps) !== getPropValue(this.props)
) {
this.updateContent();
}
}
@autobind
updateContent() {
const {tpl, html, text} = this.props;
if (html || tpl || text) {
this.getAsyncContent().then(content => {
this.setState({content});
});
}
}
@autobind
getContent() {
const {tpl, html, text, raw, data, placeholder} = this.props;
const value = getPropValue(this.props);
@ -85,10 +114,22 @@ export class Tpl extends React.Component<TplProps, object> {
}
}
@autobind
async getAsyncContent() {
const {tpl, html, text, data} = this.props;
if (html || tpl) {
return asyncFilter(html || tpl, data);
} else {
return escapeHtml(await asyncFilter(text, data));
}
}
/**
* HTML标签, , HTML标签的title属性
*/
getTitle(content: string): string {
@autobind
getTitle(content: string) {
const {showNativeTitle} = this.props;
if (!showNativeTitle) {
@ -96,10 +137,7 @@ export class Tpl extends React.Component<TplProps, object> {
}
let title = typeof content === 'string' ? content : '';
const tempDom = new DOMParser().parseFromString(
this.getContent(),
'text/html'
);
const tempDom = new DOMParser().parseFromString(content, 'text/html');
if (tempDom?.body?.textContent) {
title = tempDom.body.textContent;
@ -153,7 +191,7 @@ export class Tpl extends React.Component<TplProps, object> {
env
} = this.props;
const Component = wrapperComponent || (inline ? 'span' : 'div');
const content = this.getContent();
const {content} = this.state;
return (
<Component