fix(amis-editor): 显示类型配置交互优化,改用icon切换模式

This commit is contained in:
wibetter 2023-04-03 15:37:16 +08:00
parent 636944da6d
commit 5366841a45
51 changed files with 651 additions and 443 deletions

View File

@ -31,7 +31,8 @@
"clean-dist": "rimraf lib/* esm/*",
"i18n:update": "npx i18n update --config=./i18nConfig.js",
"i18n:translate": "npx i18n translate --config=./i18nConfig.js --l=en-US",
"i18n:merge": "npx i18n merge --config=./i18nConfig.js --l=en-US"
"i18n:merge": "npx i18n merge --config=./i18nConfig.js --l=en-US",
"format": "prettier --write \"{src,scss}/**/**/*.{js,jsx,ts,tsx,vue,scss,json}\""
},
"keywords": [
"amis",

View File

@ -0,0 +1,22 @@
.icon-ButtonList {
button {
display: inline-flex;
align-items: center;
justify-content: center;
width: 42px;
background-color: #fff !important;
box-sizing: border-box;
svg {
margin: 0 !important;
padding: 0 !important;
width: 20px;
}
&.is-active {
svg {
fill: $Editor-theme-color;
}
}
}
}

View File

@ -69,4 +69,4 @@
}
}
}
}
}

View File

@ -37,6 +37,7 @@
@import './control/_inpupt-file';
@import './control/_nav-control';
@import './control/_status';
@import './control/_icon-button-group-control';
/* 样式控件 */
@import './style-control/box-model';

View File

@ -223,7 +223,10 @@ export default class HighlightBox extends React.Component<HighlightBoxProps> {
const isActive = store.isActive(id);
const curFreeContainerId = store.parentIsFreeContainer();
const isHover =
store.isHoved(id) || store.dropId === id || store.insertOrigId === id || curFreeContainerId === id;
store.isHoved(id) ||
store.dropId === id ||
store.insertOrigId === id ||
curFreeContainerId === id;
const isDraggableContainer = store.draggableContainer(id);
// 获取当前高亮画布宽度

View File

@ -33,48 +33,49 @@ export class AvailableRenderersPanel extends React.Component<
<div className="ae-RendererPanel">
<div className="panel-header"></div>
<div className="ae-RendererPanel-content">
{store.showCustomRenderersPanel && customRenderersByOrder.length > 0 && (
<Tabs
theme={curTheme}
tabsMode={'line'} // tiled
className="ae-RendererList-tabs"
linksClassName="ae-RendererList-tabs-header"
contentClassName="ae-RendererList-tabs-content"
activeKey={renderersTabsKey}
onSelect={this.handleSelect}
>
<Tab
key={'base-renderers'}
eventKey={'base-renderers'}
title={'系统组件'}
className={`ae-RendererList-tabs-panel base-renderers`}
mountOnEnter={true}
unmountOnExit={false}
{store.showCustomRenderersPanel &&
customRenderersByOrder.length > 0 && (
<Tabs
theme={curTheme}
tabsMode={'line'} // tiled
className="ae-RendererList-tabs"
linksClassName="ae-RendererList-tabs-header"
contentClassName="ae-RendererList-tabs-content"
activeKey={renderersTabsKey}
onSelect={this.handleSelect}
>
<RenderersPanel
groupedRenderers={groupedSubRenderers}
store={store}
manager={manager}
searchRendererType={'renderer'}
/>
</Tab>
<Tab
key={'custom-renderers'}
eventKey={'custom-renderers'}
title={'自定义组件'}
className={`ae-RendererList-tabs-panel custom-renderers`}
mountOnEnter={true}
unmountOnExit={false}
>
<RenderersPanel
groupedRenderers={groupedCustomRenderers}
store={store}
manager={manager}
searchRendererType={'custom-renderer'}
/>
</Tab>
</Tabs>
)}
<Tab
key={'base-renderers'}
eventKey={'base-renderers'}
title={'系统组件'}
className={`ae-RendererList-tabs-panel base-renderers`}
mountOnEnter={true}
unmountOnExit={false}
>
<RenderersPanel
groupedRenderers={groupedSubRenderers}
store={store}
manager={manager}
searchRendererType={'renderer'}
/>
</Tab>
<Tab
key={'custom-renderers'}
eventKey={'custom-renderers'}
title={'自定义组件'}
className={`ae-RendererList-tabs-panel custom-renderers`}
mountOnEnter={true}
unmountOnExit={false}
>
<RenderersPanel
groupedRenderers={groupedCustomRenderers}
store={store}
manager={manager}
searchRendererType={'custom-renderer'}
/>
</Tab>
</Tabs>
)}
{(!store.showCustomRenderersPanel ||
Object.keys(groupedCustomRenderers).length < 1) && (
<RenderersPanel

View File

@ -185,7 +185,9 @@ export default class RenderersPanel extends React.Component<
data-dnd-data={JSON.stringify(
item.scaffold || {type: item.type}
)}
onDragStart={(e: React.DragEvent) => this.handleDragStart(e, item.name)}
onDragStart={(e: React.DragEvent) =>
this.handleDragStart(e, item.name)
}
>
<div
className="icon-box"

View File

@ -116,9 +116,7 @@ export class RegionWrapper extends React.Component<RegionWrapperProps> {
<span
className={`ae-Region-placeholder ${
isLayoutItem ? 'layout-content' : ''
} ${
isNeedFillPlaceholder ? 'fill-placeholder' : ''
}`}
} ${isNeedFillPlaceholder ? 'fill-placeholder' : ''}`}
>
{this.props.placeholder || this.props.label}
</span>

View File

@ -193,7 +193,9 @@ export default class SearchPanel extends React.Component<
const grouped: {
[propName: string]: any[];
} = {};
const regular = curKeyword ? new RegExp(stringRegExp(curKeyword), 'i') : null;
const regular = curKeyword
? new RegExp(stringRegExp(curKeyword), 'i')
: null;
allResult.forEach(item => {
if (isString(item) && regular && regular.test(item)) {

View File

@ -280,7 +280,7 @@ export class EditorDNDManager {
};
store.setDragId(id, 'copy', type, schema);
const containerId = store.activeContainerId;
// 如果当前选中了某个组件,则默认让其第一个区域处于拖入状态。
if (containerId) {
const node = store.getNodeById(containerId);
@ -292,7 +292,11 @@ export class EditorDNDManager {
slotIndex = index;
}
});
this.switchToRegion(e, node.id, node.childRegions[slotIndex].region);
this.switchToRegion(
e,
node.id,
node.childRegions[slotIndex].region
);
}
}
break;
@ -306,7 +310,9 @@ export class EditorDNDManager {
// 判断父级容器是否自由容器
const curNode = store.getNodeById(activeId);
if (curNode) {
const parentNode = curNode.parentId ? store.getNodeById(curNode.parentId) : undefined;
const parentNode = curNode.parentId
? store.getNodeById(curNode.parentId)
: undefined;
if (parentNode?.schema?.isFreeContainer) {
store.setDropId(curNode.parentId, 'body');
}
@ -333,7 +339,7 @@ export class EditorDNDManager {
const curElem = target.closest(`[data-region][data-region-host]`);
const hostId = curElem?.getAttribute('data-region-host');
const region = curElem?.getAttribute('data-region');
if (
d > 0 &&
this.curDragId &&
@ -347,7 +353,7 @@ export class EditorDNDManager {
let dragHlBoxItem = doc.querySelector(
`[data-hlbox-id='${this.curDragId}']`
) as HTMLElement;
if (store.isMobile && !dragHlBoxItem && parentDoc) {
dragHlBoxItem = parentDoc.querySelector(
`[data-hlbox-id='${this.curDragId}']`
@ -376,10 +382,14 @@ export class EditorDNDManager {
} ${
hlBInset.right !== 'auto' ? unitFormula(hlBInset.right, -dx) : 'auto'
} ${
hlBInset.bottom !== 'auto' ? unitFormula(hlBInset.bottom, -dy) : 'auto'
} ${hlBInset.left !== 'auto' ? unitFormula(hlBInset.left, dx) : 'auto'}`;
hlBInset.bottom !== 'auto'
? unitFormula(hlBInset.bottom, -dy)
: 'auto'
} ${
hlBInset.left !== 'auto' ? unitFormula(hlBInset.left, dx) : 'auto'
}`;
}
// 实时调整被拖拽元素的坐标值
const dragContainerItem = doc.querySelector(
`[data-editor-id='${this.curDragId}']`

View File

@ -47,7 +47,6 @@ import DeleteBold from './delete-bold.svg';
import DragIcon from './drag-icon.svg';
import EventSetting from './event-setting.svg';
registerIcon('edit-full-btn', Edit);
registerIcon('event-setting', EventSetting);
registerIcon('add-btn', Plus);

View File

@ -842,7 +842,7 @@ export class EditorManager {
// 当渲染器信息和 schemaData 都为空时,则不作任何处理
return;
}
if (!node) {
toast.warning('请先选择一个元素作为插入的位置。');
return;

View File

@ -25,7 +25,8 @@
"clean-dist": "rimraf lib/* esm/*",
"i18n:update": "npx i18n update --config=./i18nConfig.js",
"i18n:translate": "npx i18n translate --config=./i18nConfig.js --l=en-US",
"i18n:merge": "npx i18n merge --config=./i18nConfig.js --l=en-US"
"i18n:merge": "npx i18n merge --config=./i18nConfig.js --l=en-US",
"format": "prettier --write \"src/**/**/*.{js,jsx,ts,tsx,vue,scss,json}\""
},
"keywords": [
"amis",

View File

@ -538,7 +538,11 @@ export class TableViewEditor extends React.Component<
));
return (
<div className="ae-TableViewEditor" ref={this.tableViewWrapperRef} style={schema?.style}>
<div
className="ae-TableViewEditor"
ref={this.tableViewWrapperRef}
style={schema?.style}
>
{children}
{this.renderMergeIcon()}
{rowLines}

View File

@ -0,0 +1 @@
<svg preserveAspectRatio="xMidYMid meet" width="16" height="16" viewBox="0 0 22 14"><path opacity=".15" d="M19 3v8H3V3h16m1-1H2v10h18V2z"></path><path d="M19.8 1H2.2A1.2 1.2 0 0 0 1 2.2v9.6A1.2 1.2 0 0 0 2.2 13h17.6a1.2 1.2 0 0 0 1.2-1.2V2.2A1.2 1.2 0 0 0 19.8 1zm.2 11H2V2h18v10z"></path><path opacity=".35" d="M3 3h16v8H3z"></path></svg>

After

Width:  |  Height:  |  Size: 339 B

View File

@ -0,0 +1 @@
<svg preserveAspectRatio="xMidYMid meet" width="16" height="16" viewBox="0 0 23 14"><g fillRule="evenodd"><path d="M21 2v10H2V2h19zm1-1H1v12h21V1z" opacity=".15"></path><path d="M1.2 0A1.2 1.2 0 0 0 0 1.2v11.6A1.2 1.2 0 0 0 1.2 14h20.6a1.2 1.2 0 0 0 1.2-1.2V1.2A1.2 1.2 0 0 0 21.8 0H1.2zM22 13H1V1h21v12z"></path><path opacity=".4" d="M3 3h5v8H3z"></path><path d="M4 4v6h3V4H4zm4-1v8H3V3h5z"></path><path opacity=".4" d="M9 3h5v8H9z"></path><path d="M10 4v6h3V4h-3zm4-1v8H9V3h5z"></path><path opacity=".4" d="M15 3h5v8h-5z"></path><path d="M16 4v6h3V4h-3zm4-1v8h-5V3h5z"></path></g></svg>

After

Width:  |  Height:  |  Size: 588 B

View File

@ -0,0 +1 @@
<svg preserveAspectRatio="xMidYMid meet" width="16" height="16" viewBox="0 0 28 14"><path d="M25 3v8H3V3h22m1-1H2v10h24V2z" opacity=".15"></path><path opacity=".35" d="M8.418 9.8H7.66L7.25 11h1.58l-.232-.676-.18-.525zM3 11h.567l2.916-7.94h3.15L11 6.78V3H3v8zm15.12-1.002a3.302 3.302 0 0 1-.48-.586c-.173.343-.42.653-.73.888.002 0 .004-.002.005-.003l-.008.006.003-.003a3.145 3.145 0 0 1-1.092.55c-.4.11-.825.15-1.303.15h6.017a4.416 4.416 0 0 1-1.12-.215 3.51 3.51 0 0 1-1.292-.787zM14.237 3c.49 0 .853.014 1.167.06.335.05.656.16.953.314h.003l.004.003c.365.19.694.492.898.866.13.234.197.49.24.747.16-.298.343-.58.578-.82v-.002c.358-.366.8-.643 1.287-.826a4.373 4.373 0 0 1 1.557-.272 5.67 5.67 0 0 1 1.442.18l.01.002.01.003c.205.06.4.126.59.208.15.064.283.125.407.185l.562.274v3.016h-1.54l-.28-.24a7.018 7.018 0 0 0-.233-.188 2.703 2.703 0 0 0-.26-.175 1.594 1.594 0 0 0-.277-.125h-.006l-.2-.03a.772.772 0 0 0-.26.042l-.16.102a.63.63 0 0 0-.13.22 1.486 1.486 0 0 0-.075.516c0 .266.04.436.074.513a.59.59 0 0 0 .13.212l.15.09h.003a.868.868 0 0 0 .265.045l.236-.037h.008a1.04 1.04 0 0 0 .25-.113l.007-.004.01-.005.24-.16a6.41 6.41 0 0 0 .216-.17l.285-.254h1.536v3.017l-.59.266c-.15.066-.292.13-.422.184a4.19 4.19 0 0 1-.53.19 5.918 5.918 0 0 1-.636.15c-.076.012-.16.02-.24.026H25V3H14.237z"></path><path d="M25.8 1H2.2A1.2 1.2 0 0 0 1 2.2v9.6A1.2 1.2 0 0 0 2.2 13h23.6a1.2 1.2 0 0 0 1.2-1.2V2.2A1.2 1.2 0 0 0 25.8 1zm.2 11H2V2h24v10zm-7.186-2.72c.258.248.567.435.927.56s.76.19 1.18.19c.29 0 .51-.014.68-.042.167-.028.34-.07.53-.123.143-.04.28-.09.41-.146l.412-.19V8.16h-.154c-.07.06-.157.134-.265.22a3.337 3.337 0 0 1-.35.237 2.11 2.11 0 0 1-.485.22 1.798 1.798 0 0 1-1.1-.01 1.403 1.403 0 0 1-.523-.3c-.15-.14-.28-.33-.38-.57a2.36 2.36 0 0 1-.152-.9c0-.347.047-.64.14-.88s.216-.433.367-.58c.157-.15.33-.26.517-.325a1.786 1.786 0 0 1 1.116-.014c.164.056.316.125.457.206a4.868 4.868 0 0 1 .644.466h.17V4.54a13.03 13.03 0 0 0-.367-.168 3.667 3.667 0 0 0-1.005-.27 4.736 4.736 0 0 0-.65-.04c-.436 0-.837.07-1.205.207s-.675.333-.924.59c-.26.262-.457.58-.59.95S18 6.6 18 7.055c0 .488.07.918.213 1.29s.343.683.6.933zm-3.264.607c.272-.076.52-.2.75-.38.195-.15.35-.338.46-.567.113-.23.17-.488.17-.778 0-.4-.11-.722-.332-.967-.22-.245-.52-.406-.896-.484v-.03a1.46 1.46 0 0 0 .623-.51 1.36 1.36 0 0 0 .22-.77c0-.25-.052-.47-.16-.665a1.15 1.15 0 0 0-.49-.465 2.065 2.065 0 0 0-.64-.215A7.67 7.67 0 0 0 14.237 4H12v6h2.515c.418 0 .763-.037 1.035-.113zM13.478 5.1h.14c.29 0 .517.002.678.006s.296.027.404.07c.12.05.206.123.253.223a.69.69 0 0 1 .072.29.86.86 0 0 1-.062.34c-.042.1-.13.18-.263.24a1.05 1.05 0 0 1-.39.08c-.166.007-.366.01-.6.01h-.233V5.1zm.108 3.8h-.108V7.405h.324c.222 0 .434 0 .638.004.203 0 .363.02.48.05.17.05.29.13.36.23s.106.25.106.44c0 .144-.03.272-.087.384s-.17.2-.32.27a1.257 1.257 0 0 1-.5.104c-.18.003-.48.004-.9.004zm-6.64-.1h2.187l.41 1.2h1.574L8.935 4.06H7.182L5 10h1.535l.412-1.2zM8.04 5.58l.727 2.13H7.313l.727-2.13z"></path></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1 @@
<svg preserveAspectRatio="xMidYMid meet" width="16" height="16" viewBox="0 0 20 8"><path d="M14.814 6.25c.258.248.567.435.927.56s.76.19 1.18.19c.29 0 .51-.014.68-.042.167-.028.34-.07.53-.123.143-.04.28-.09.41-.146l.41-.19V5.13h-.153c-.07.06-.157.134-.265.22a3.337 3.337 0 0 1-.35.237 2.11 2.11 0 0 1-.484.22 1.798 1.798 0 0 1-1.1-.01 1.403 1.403 0 0 1-.523-.3 1.566 1.566 0 0 1-.38-.57c-.1-.24-.152-.54-.152-.9 0-.346.048-.638.14-.878s.217-.437.368-.58c.16-.155.33-.26.52-.33a1.786 1.786 0 0 1 1.117-.013c.165.055.317.124.458.205a4.385 4.385 0 0 1 .643.47h.17V1.52c-.107-.05-.23-.107-.37-.168a3.613 3.613 0 0 0-1.003-.27 4.736 4.736 0 0 0-.65-.04c-.436 0-.837.07-1.205.207s-.674.33-.923.59c-.26.26-.458.58-.59.95S14 3.57 14 4.02c0 .488.07.918.213 1.29s.343.683.6.933zm-3.264.608c.272-.075.52-.2.75-.377a1.5 1.5 0 0 0 .46-.56 1.72 1.72 0 0 0 .17-.77c0-.4-.11-.72-.332-.96-.22-.244-.52-.404-.896-.48v-.04a1.46 1.46 0 0 0 .623-.516c.147-.22.22-.474.22-.763 0-.25-.052-.47-.16-.66a1.152 1.152 0 0 0-.49-.46 2.06 2.06 0 0 0-.64-.212A7.67 7.67 0 0 0 10.237 1H8v5.97h2.515c.418 0 .763-.037 1.035-.112zM9.478 2.095h.14c.29 0 .517.002.678.006.162.01.296.03.404.07a.46.46 0 0 1 .253.23.69.69 0 0 1 .072.298.85.85 0 0 1-.062.34.492.492 0 0 1-.263.24 1.052 1.052 0 0 1-.39.08c-.166.006-.366.01-.6.01h-.232v-1.27zm.108 3.78h-.108V4.388h.324c.222 0 .434 0 .638.004a1.8 1.8 0 0 1 .48.056c.17.05.29.127.36.23.07.104.106.25.106.44 0 .144-.03.272-.087.383s-.17.2-.32.27-.32.1-.5.11c-.18.004-.48.004-.9.004zm-6.64-.106h2.187l.41 1.2h1.574L4.935 1.03H3.182L1 6.97h1.535l.412-1.2zM4.04 2.55l.727 2.13H3.313l.727-2.13z"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -153,6 +153,12 @@ import layout_3_2 from './layout/layout3-2.svg';
import layout_free_container from './layout/layout-free-container.svg';
import layout_fixed_top from './layout/layout-fixed-top.svg';
// 属性配置面板/显示类型
import block from './config/block.svg';
import inline from './config/inline.svg';
import inline_block from './config/inline-block.svg';
import flex from './config/flex.svg';
// 功能类组件 icon x 11
registerIcon('audio-plugin', audio);
registerIcon('custom-plugin', custom);
@ -292,4 +298,10 @@ registerIcon('layout-3-2-plugin', layout_3_2);
registerIcon('layout-free-container', layout_free_container);
registerIcon('layout-fixed-top', layout_fixed_top);
// 属性配置面板/显示类型
registerIcon('inline-display', inline);
registerIcon('inline-block-display', inline_block);
registerIcon('block-display', block);
registerIcon('flex-display', flex);
export {Icon};

View File

@ -179,6 +179,7 @@ import './renderer/event-control/index';
import './renderer/TreeOptionControl';
import './renderer/TransferTableControl';
import './renderer/style-control/ThemeClassName';
import './renderer/ButtonGroupControl';
import 'amis-theme-editor/lib/renderers/Border';
import 'amis-theme-editor/lib/renderers/ColorPicker';
import 'amis-theme-editor/lib/renderers/Font';

View File

@ -236,9 +236,7 @@ export class AnchorNavPlugin extends BasePlugin {
getSchemaTpl('collapseGroup', [
{
title: '基本',
body: [
getSchemaTpl('anchorNavTitle')
]
body: [getSchemaTpl('anchorNavTitle')]
}
])
]

View File

@ -55,7 +55,7 @@ export class CodeViewPlugin extends BasePlugin {
title: '显隐',
body: [getSchemaTpl('ref'), getSchemaTpl('visible')]
}
])
]);
};
}

View File

@ -323,7 +323,8 @@ export class ContainerPlugin extends LayoutBasePlugin {
: null,
getSchemaTpl('layout:z-index'),
getSchemaTpl('layout:sticky', {
visibleOn: 'data.style && (data.style.position !== "fixed" && data.style.position !== "absolute")'
visibleOn:
'data.style && (data.style.position !== "fixed" && data.style.position !== "absolute")'
}),
getSchemaTpl('layout:stickyPosition')
]

View File

@ -30,7 +30,8 @@ export class DividerPlugin extends BasePlugin {
body: [
getSchemaTpl('layout:originPosition', {value: 'left-top'}),
getSchemaTpl('layout:width:v2', {
visibleOn: 'data.style && data.style.position && (data.style.position === "fixed" || data.style.position === "absolute")',
visibleOn:
'data.style && data.style.position && (data.style.position === "fixed" || data.style.position === "absolute")'
}),
getSchemaTpl('className')
]

View File

@ -77,7 +77,7 @@ export class DropDownButtonPlugin extends BasePlugin {
)
},
getSchemaTpl('label', {
label: '按钮文案',
label: '按钮文案'
}),
{
type: 'button-group-select',

View File

@ -35,7 +35,11 @@ export class HiddenControlPlugin extends BasePlugin {
];
renderRenderer(props: any) {
return this.renderPlaceholder('功能组件(隐藏字段)', props.key, props.style);
return this.renderPlaceholder(
'功能组件(隐藏字段)',
props.key,
props.style
);
}
}

View File

@ -1,4 +1,8 @@
import {getI18nEnabled, RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
import {
getI18nEnabled,
RendererPluginAction,
RendererPluginEvent
} from 'amis-editor-core';
import flatten from 'lodash/flatten';
import {ContainerWrapper} from 'amis-editor-core';
import {registerEditorPlugin} from 'amis-editor-core';

View File

@ -124,7 +124,7 @@ export class RangeControlPlugin extends BasePlugin {
}),
getSchemaTpl('label', {
label: 'Label',
label: 'Label'
}),
{

View File

@ -11,7 +11,7 @@ import {ValidatorTag} from '../../validator';
const tinymceToolbarsDelimiter = ' ';
const tinymceOptions = [
const tinymceOptions = [
'advlist',
'autolink',
'link',
@ -214,7 +214,12 @@ export class RichTextControlPlugin extends BasePlugin {
label: '类型',
value: hasRichTextToken ? 'froala' : 'tinymce',
options: ['tinymce', 'froala'],
onChange: (value: any, oldValue: any, model: any, form: any) => {
onChange: (
value: any,
oldValue: any,
model: any,
form: any
) => {
if (value === 'tinymce') {
form.changeValue('options', {
height: 400,
@ -226,8 +231,7 @@ export class RichTextControlPlugin extends BasePlugin {
toolbarButtonsMD: undefined,
toolbarButtonsSM: undefined
});
}
else if (value === 'froala') {
} else if (value === 'froala') {
form.changeValue('options', {
height: undefined,
width: undefined,
@ -246,7 +250,8 @@ export class RichTextControlPlugin extends BasePlugin {
multiple: true,
label: tipedLabel(
'插件',
'查看 https://www.tiny.cloud/docs/general-configuration-guide/basic-setup/ 文档'),
'查看 https://www.tiny.cloud/docs/general-configuration-guide/basic-setup/ 文档'
),
name: 'options.plugins',
visibleOn: 'data.vendor === "tinymce"',
value: [...tinymceOptions].join(','),
@ -271,10 +276,13 @@ export class RichTextControlPlugin extends BasePlugin {
},
visibleOn: 'data.vendor === "tinymce"',
delimiter: tinymceToolbarsDelimiter,
value: 'undo redo formatselect bold italic backcolor alignleft aligncenter alignright alignjustify bullist numlist outdent indent removeformat help',
value:
'undo redo formatselect bold italic backcolor alignleft aligncenter alignright alignjustify bullist numlist outdent indent removeformat help',
pipeOut: (value: string) => {
const arr = value?.split(tinymceToolbarsDelimiter) ?? [];
return tinymceToolbars.filter(item => arr.find(a => a === item)).join(' ');
return tinymceToolbars
.filter(item => arr.find(a => a === item))
.join(' ');
},
options: tinymceToolbars
},
@ -282,7 +290,7 @@ export class RichTextControlPlugin extends BasePlugin {
label: '显示菜单栏',
value: true,
name: 'options.menubar',
visibleOn: 'data.vendor === "tinymce"',
visibleOn: 'data.vendor === "tinymce"'
}),
// froala
@ -304,7 +312,7 @@ export class RichTextControlPlugin extends BasePlugin {
joinValues: false,
extractValue: true,
options: [...froalaOptions],
pipeOut: froalaOptionsPipeOut,
pipeOut: froalaOptionsPipeOut
},
{
type: 'select',
@ -348,13 +356,13 @@ export class RichTextControlPlugin extends BasePlugin {
label: '快速插入',
value: true,
name: 'options.quickInsertEnabled',
visibleOn: 'data.vendor === "froala"',
visibleOn: 'data.vendor === "froala"'
}),
getSchemaTpl('switch', {
label: '字数统计',
value: true,
name: 'options.charCounterCount',
visibleOn: 'data.vendor === "froala"',
visibleOn: 'data.vendor === "froala"'
}),
// 公用部分
@ -363,7 +371,8 @@ export class RichTextControlPlugin extends BasePlugin {
labelClassName: 'none',
name: 'receiver',
label: '图片接收接口',
visibleOn: '${vendor === "tinymce" && CONTAINS(options.plugins, "image")}',
visibleOn:
'${vendor === "tinymce" && CONTAINS(options.plugins, "image")}'
}),
getSchemaTpl('apiControl', {
@ -371,7 +380,7 @@ export class RichTextControlPlugin extends BasePlugin {
labelClassName: 'none',
name: 'receiver',
label: '图片接收接口',
visibleOn: 'data.vendor === "froala"',
visibleOn: 'data.vendor === "froala"'
}),
getSchemaTpl('apiControl', {
@ -379,14 +388,14 @@ export class RichTextControlPlugin extends BasePlugin {
labelClassName: 'none',
name: 'videoReceiver',
label: '视频接收接口',
visibleOn: 'data.vendor === "froala"',
visibleOn: 'data.vendor === "froala"'
}),
getSchemaTpl('labelRemark'),
getSchemaTpl('remark'),
getSchemaTpl('placeholder', {
visibleOn: 'data.vendor !== "tinymce"'
}),
getSchemaTpl('description'),
getSchemaTpl('description')
]
},
getSchemaTpl('status', {isFormItem: true}),
@ -405,7 +414,7 @@ export class RichTextControlPlugin extends BasePlugin {
label: '高度',
min: 0,
name: 'options.height',
visibleOn: 'data.vendor === "tinymce"',
visibleOn: 'data.vendor === "tinymce"'
},
{
type: 'input-number',
@ -413,7 +422,7 @@ export class RichTextControlPlugin extends BasePlugin {
min: 150,
max: 400,
name: 'options.height',
visibleOn: 'data.vendor === "froala"',
visibleOn: 'data.vendor === "froala"'
}
]
},

View File

@ -19,7 +19,10 @@ import {
} from 'amis-editor-core';
import {setVariable} from 'amis-core';
import {ValidatorTag} from '../../validator';
import {getEventControlConfig, getArgsWrapper} from '../../renderer/event-control/helper';
import {
getEventControlConfig,
getArgsWrapper
} from '../../renderer/event-control/helper';
import cloneDeep from 'lodash/cloneDeep';
export class TableControlPlugin extends BasePlugin {
@ -170,12 +173,12 @@ export class TableControlPlugin extends BasePlugin {
label: '日期'
},
{
value: 'datetime',
label: '日期时间'
value: 'datetime',
label: '日期时间'
},
{
value: 'time',
label: '时间'
value: 'time',
label: '时间'
},
{
value: 'status',
@ -260,10 +263,12 @@ export class TableControlPlugin extends BasePlugin {
const rawColumn = {
...column,
type: column.type,
quickEdit: column.quickEdit?.type ? {
type: column.quickEdit.type,
name: column.name
} : false
quickEdit: column.quickEdit?.type
? {
type: column.quickEdit.type,
name: column.name
}
: false
};
rawColumns.push(rawColumn);
});
@ -596,7 +601,7 @@ export class TableControlPlugin extends BasePlugin {
type: i18nEnabled ? 'input-text-i18n' : 'input-text',
name: 'cancelBtnLabel',
label: '取消按钮名称',
placeholder: '取消按钮名称',
placeholder: '取消按钮名称'
},
getSchemaTpl('icon', {
name: 'cancelBtnIcon',
@ -659,7 +664,7 @@ export class TableControlPlugin extends BasePlugin {
name: 'copyBtnIcon',
label: '按钮图标',
pipeIn: defaultValue('copy')
}),
})
]
}
},
@ -775,7 +780,7 @@ export class TableControlPlugin extends BasePlugin {
schema: [
getSchemaTpl('className', {
name: 'rowClassName',
label: '行样式',
label: '行样式'
})
]
})

View File

@ -1,5 +1,9 @@
import React from 'react';
import {getI18nEnabled, RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
import {
getI18nEnabled,
RendererPluginAction,
RendererPluginEvent
} from 'amis-editor-core';
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
import {registerEditorPlugin} from 'amis-editor-core';
import {BaseEventContext, BasePlugin} from 'amis-editor-core';

View File

@ -1,4 +1,8 @@
import {getI18nEnabled, RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
import {
getI18nEnabled,
RendererPluginAction,
RendererPluginEvent
} from 'amis-editor-core';
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
import {registerEditorPlugin} from 'amis-editor-core';
import {BaseEventContext, BasePlugin} from 'amis-editor-core';

View File

@ -87,7 +87,11 @@ export class IFramePlugin extends BasePlugin {
};
renderRenderer(props: any) {
return this.renderPlaceholder(`IFrame 页面(${props.src}`, props.key, props.style);
return this.renderPlaceholder(
`IFrame 页面(${props.src}`,
props.key,
props.style
);
}
}

View File

@ -40,9 +40,9 @@ const defaultFlexContainerSchema = {
defaultFlexColumnSchema('第三列')
],
style: {
position: 'relative',
position: 'relative'
},
direction: "row",
direction: 'row',
justify: 'flex-start',
alignItems: 'stretch'
};
@ -88,7 +88,7 @@ export class FlexPluginBase extends LayoutBasePlugin {
getSchemaTpl('layout:originPosition'),
getSchemaTpl('layout:inset', {
mode: 'vertical'
}),
})
];
return [
@ -226,33 +226,33 @@ export class FlexPluginBase extends LayoutBasePlugin {
getSchemaTpl('layout:flex-wrap'),
isFlexItem
? getSchemaTpl('layout:flex', {
isFlexColumnItem,
label: isFlexColumnItem ? '高度设置' : '宽度设置',
visibleOn:
'data.style && (data.style.position === "static" || data.style.position === "relative")'
})
: null,
? getSchemaTpl('layout:flex', {
isFlexColumnItem,
label: isFlexColumnItem ? '高度设置' : '宽度设置',
visibleOn:
'data.style && (data.style.position === "static" || data.style.position === "relative")'
})
: null,
isFlexItem
? getSchemaTpl('layout:flex-grow', {
visibleOn:
'data.style && data.style.flex === "1 1 auto" && (data.style.position === "static" || data.style.position === "relative")'
})
: null,
? getSchemaTpl('layout:flex-grow', {
visibleOn:
'data.style && data.style.flex === "1 1 auto" && (data.style.position === "static" || data.style.position === "relative")'
})
: null,
isFlexItem
? getSchemaTpl('layout:flex-basis', {
label: isFlexColumnItem ? '弹性高度' : '弹性宽度',
visibleOn:
'data.style && (data.style.position === "static" || data.style.position === "relative") && data.style.flex === "1 1 auto"'
})
: null,
? getSchemaTpl('layout:flex-basis', {
label: isFlexColumnItem ? '弹性高度' : '弹性宽度',
visibleOn:
'data.style && (data.style.position === "static" || data.style.position === "relative") && data.style.flex === "1 1 auto"'
})
: null,
isFlexItem
? getSchemaTpl('layout:flex-basis', {
label: isFlexColumnItem ? '固定高度' : '固定宽度',
visibleOn:
'data.style && (data.style.position === "static" || data.style.position === "relative") && data.style.flex === "0 0 150px"'
})
: null,
? getSchemaTpl('layout:flex-basis', {
label: isFlexColumnItem ? '固定高度' : '固定宽度',
visibleOn:
'data.style && (data.style.position === "static" || data.style.position === "relative") && data.style.flex === "0 0 150px"'
})
: null,
getSchemaTpl('layout:overflow-x', {
visibleOn: `${
@ -299,7 +299,7 @@ export class FlexPluginBase extends LayoutBasePlugin {
getSchemaTpl('layout:min-width', {
visibleOn: `${!isFlexItem || isFlexColumnItem}`
}),
getSchemaTpl('layout:overflow-x', {
visibleOn: `${
!isFlexItem || isFlexColumnItem
@ -308,9 +308,11 @@ export class FlexPluginBase extends LayoutBasePlugin {
!isFlexItem ? getSchemaTpl('layout:margin-center') : null,
getSchemaTpl('layout:z-index'),
!isSorptionContainer && getSchemaTpl('layout:sticky', {
visibleOn: 'data.style && (data.style.position !== "fixed" && data.style.position !== "absolute")'
}),
!isSorptionContainer &&
getSchemaTpl('layout:sticky', {
visibleOn:
'data.style && (data.style.position !== "fixed" && data.style.position !== "absolute")'
}),
getSchemaTpl('layout:stickyPosition')
]
},
@ -351,7 +353,7 @@ export class FlexPluginBase extends LayoutBasePlugin {
const isFlexColumnItem = this.manager?.isFlexColumnItem(id);
const newColumnSchema = defaultFlexColumnSchema('新的一列');
const toolbarsTooltips:any = {};
const toolbarsTooltips: any = {};
toolbars.forEach(toolbar => {
if (toolbar.tooltip) {
toolbarsTooltips[toolbar.tooltip] = 1;
@ -413,7 +415,9 @@ export class FlexPluginBase extends LayoutBasePlugin {
}
if (isFlexItem && !draggableContainer) {
if (!toolbarsTooltips[`${isFlexColumnItem ? '上方' : '左侧'}插入列级容器`]) {
if (
!toolbarsTooltips[`${isFlexColumnItem ? '上方' : '左侧'}插入列级容器`]
) {
// 布局容器的列级元素 增加左右插入icon
toolbars.push(
{

View File

@ -100,7 +100,7 @@ export class ListPlugin extends BasePlugin {
{
name: 'placeholder',
pipeIn: defaultValue('没有数据'),
type: i18nEnabled ? 'input-text-i18n' : 'input-text',
type: i18nEnabled ? 'input-text-i18n' : 'input-text',
label: '无数据提示'
},
{

View File

@ -53,7 +53,7 @@ export class ListItemPlugin extends BasePlugin {
},
{
name: 'subTitle',
type: i18nEnabled ? 'input-text-i18n' : 'input-text',
type: i18nEnabled ? 'input-text-i18n' : 'input-text',
label: '副标题',
descrition: '支持模板语法如: ${xxx}'
},
@ -85,7 +85,7 @@ export class ListItemPlugin extends BasePlugin {
})
]
}
])
]);
};
getRendererInfo({

View File

@ -22,7 +22,8 @@ export class PagePlugin extends BasePlugin {
isBaseComponent = true;
// 只有顶级才会用到这个page组件
disabledRendererPlugin = true;
description = '页面渲染器,页面的顶级入口。包含多个区域,您可以选择在不同的区域里面放置不同的渲染器。';
description =
'页面渲染器,页面的顶级入口。包含多个区域,您可以选择在不同的区域里面放置不同的渲染器。';
docLink = '/amis/zh-CN/components/page';
tags = '容器';
icon = 'fa fa-desktop';

View File

@ -99,59 +99,59 @@ export class StatusPlugin extends BasePlugin {
{
children: (
<TooltipWrapper
tooltipClassName="ae-Status-default-icon-tooltip"
trigger="hover"
rootClose={true}
placement="bottom"
tooltip={{
children: () =>
render({
type: 'container',
body: [
{
type: 'tpl',
tpl: '默认支持如下几种状态,无需配置即可使用。自定义状态会和默认状态合并。',
wrapperComponent: 'p',
className: 'ae-Status-default-icon-tip'
tooltipClassName="ae-Status-default-icon-tooltip"
trigger="hover"
rootClose={true}
placement="bottom"
tooltip={{
children: () =>
render({
type: 'container',
body: [
{
type: 'tpl',
tpl: '默认支持如下几种状态,无需配置即可使用。自定义状态会和默认状态合并。',
wrapperComponent: 'p',
className: 'ae-Status-default-icon-tip'
},
{
type: 'table',
data: {
items: this.defaultSource
},
{
type: 'table',
data: {
items: this.defaultSource
columns: [
{
name: 'icon',
label: '默认icon值'
},
columns: [
{
name: 'icon',
label: '默认icon值'
},
{
name: 'label',
label: '默认label'
},
{
name: 'value',
label: '默认value值'
},
{
name: 'status',
label: '状态',
type: 'mapping',
map: {
'*': {
type: 'status'
}
{
name: 'label',
label: '默认label'
},
{
name: 'value',
label: '默认value值'
},
{
name: 'status',
label: '状态',
type: 'mapping',
map: {
'*': {
type: 'status'
}
}
]
}
]
})
}}
>
<div className="ae-Status-label-tip-icon">
<Icon icon="editor-help" className="icon" />
</div>
</TooltipWrapper>
}
]
}
]
})
}}
>
<div className="ae-Status-label-tip-icon">
<Icon icon="editor-help" className="icon" />
</div>
</TooltipWrapper>
)
}
],
@ -161,7 +161,12 @@ export class StatusPlugin extends BasePlugin {
getSchemaTpl('icon', {
label: '',
placeholder: '图标',
onChange(value: any, oldValue: boolean, model: any, form: any) {
onChange(
value: any,
oldValue: boolean,
model: any,
form: any
) {
// 选择图标时自动填充label
if (value && value.name) {
form.setValues({
@ -173,7 +178,7 @@ export class StatusPlugin extends BasePlugin {
{
type: i18nEnabled ? 'input-text-i18n' : 'input-text',
name: 'label',
placeholder: 'label',
placeholder: 'label'
},
{
type: 'input-text',
@ -188,57 +193,71 @@ export class StatusPlugin extends BasePlugin {
getSchemaTpl('theme:colorPicker', {
label: '',
name: 'color'
}),
})
],
pipeIn: (value: any, {data} : any) => {
pipeIn: (value: any, {data}: any) => {
// 首次进入将schema 转换为 combo的数据
if (value === undefined) {
let {map, labelMap, source} = data;
let res = cloneDeep(source) || {};
// 兼容旧版
map && Object.entries(map).forEach(([value, icon]) => {
if (value === '' || value == null || value === '$$id') {
return;
}
if (!res[value]) {
res[value] = {icon};
} else {
res[value] = {...res[value], icon};
}
});
labelMap && Object.entries(labelMap).forEach(([value, label]) => {
if (value === '' || value == null) {
return;
}
if (!res[value]) {
res[value] = {label};
} else {
res[value] = {...res[value], label};
}
});
map &&
Object.entries(map).forEach(([value, icon]) => {
if (
value === '' ||
value == null ||
value === '$$id'
) {
return;
}
if (!res[value]) {
res[value] = {icon};
} else {
res[value] = {...res[value], icon};
}
});
labelMap &&
Object.entries(labelMap).forEach(([value, label]) => {
if (value === '' || value == null) {
return;
}
if (!res[value]) {
res[value] = {label};
} else {
res[value] = {...res[value], label};
}
});
Object.keys(res).forEach((key, index) => {
const item = res[key];
if(!('key' in item)) {
if (!('key' in item)) {
item.key = key;
}
if(!('value' in item)) {
if (!('value' in item)) {
item.value = key;
}
});
return Object.values(res);
}
else {
} else {
// 后续可以直接使用value
return value;
}
},
onChange(value: any, oldValue: boolean, model: any, form: any) {
onChange(
value: any,
oldValue: boolean,
model: any,
form: any
) {
const res: any = {};
value.forEach((item: any) => {
if (item.value !== '' && item.value != null) {
res[item.value] = pick(item, ['label', 'color', 'icon']);
res[item.value] = pick(item, [
'label',
'color',
'icon'
]);
}
});
form.setValues({

View File

@ -1,6 +1,10 @@
import React from 'react';
import {Button, resolveVariable} from 'amis';
import {getI18nEnabled, RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
import {
getI18nEnabled,
RendererPluginAction,
RendererPluginEvent
} from 'amis-editor-core';
import {findTree, setVariable, someTree} from 'amis-core';
import {registerEditorPlugin, repeatArray, diff} from 'amis-editor-core';

View File

@ -15,8 +15,8 @@ const presetColors = [
'#f33e3e',
'#ff9326',
'#fff',
'#000',
]
'#000'
];
export class TagPlugin extends BasePlugin {
// 关联渲染器名字
@ -101,7 +101,6 @@ export class TagPlugin extends BasePlugin {
actions: RendererPluginAction[] = [];
panelBodyCreator = (context: BaseEventContext) => {
return getSchemaTpl('tabs', [
{
title: '属性',
@ -119,15 +118,15 @@ export class TagPlugin extends BasePlugin {
options: [
{
label: '普通',
value:'normal'
value: 'normal'
},
{
label: '圆角',
value:'rounded'
value: 'rounded'
},
{
label: '状态',
value:'status'
value: 'status'
}
]
},
@ -147,28 +146,28 @@ export class TagPlugin extends BasePlugin {
title: '颜色',
body: [
{
type:'input-color',
type: 'input-color',
label: '主题',
name: 'color',
presetColors,
pipeOut: undefinedPipeOut
},
{
type:'input-color',
type: 'input-color',
label: '背景色',
name: 'style.backgroundColor',
presetColors,
pipeOut: undefinedPipeOut
},
{
type:'input-color',
type: 'input-color',
label: '边框',
name: 'style.borderColor',
presetColors,
pipeOut: undefinedPipeOut
},
{
type:'input-color',
type: 'input-color',
label: '文字',
name: 'style.color',
presetColors,

View File

@ -8,7 +8,13 @@ import camelCase from 'lodash/camelCase';
import mapKeys from 'lodash/mapKeys';
import {FormItem, Switch} from 'amis';
import {autobind, isObject, isEmpty, anyChanged, getI18nEnabled} from 'amis-editor-core';
import {
autobind,
isObject,
isEmpty,
anyChanged,
getI18nEnabled
} from 'amis-editor-core';
import {defaultValue, tipedLabel} from 'amis-editor-core';
import type {FormControlProps} from 'amis-core';

View File

@ -0,0 +1,50 @@
/**
* @file icon按钮组
*/
import React from 'react';
import {FormControlProps, FormItem, Button, Icon} from 'amis';
export interface ButtonGroupControlProps extends FormControlProps {
options?: Array<{
label: string;
icon: string;
value: string;
}>;
onChange: (value: string | number) => void;
value?: string | number;
}
export default class ButtonGroupControl extends React.Component<ButtonGroupControlProps> {
constructor(props: any) {
super(props);
}
render() {
const {options, value, onChange, classnames: cx, className} = this.props;
return (
<div className={cx('ButtonGroup', 'icon-ButtonList', className)}>
{options &&
options.map(item => (
<Button
key={item.value}
onClick={() => onChange(item.value)}
level={value === item.value ? 'primary' : 'default'}
tooltip={item.label}
active={value === item.value}
>
{item.icon ? (
<Icon icon={item.icon} className="icon" />
) : (
item.label
)}
</Button>
))}
</div>
);
}
}
@FormItem({
type: 'button-icon-group'
})
export class ButtonGroupControlRenderer extends ButtonGroupControl {}

View File

@ -50,7 +50,11 @@ export default class MapSourceControl extends React.Component<
};
}
componentDidUpdate(prevProps: Readonly<MapSourceControlProps>, prevState: Readonly<MapSourceControlState>, snapshot?: any): void {
componentDidUpdate(
prevProps: Readonly<MapSourceControlProps>,
prevState: Readonly<MapSourceControlState>,
snapshot?: any
): void {
const isArrayOld = Array.isArray(prevProps.data?.map);
const isArrayNew = Array.isArray(this.props.data?.map);
// map 类型改变了
@ -62,8 +66,8 @@ export default class MapSourceControl extends React.Component<
}
/**
* map字段的统一出口
*/
* map字段的统一出口
*/
onChange() {
let {mapType, source, map, labelField, valueField} = this.state;
const {onBulkChange} = this.props;
@ -72,47 +76,46 @@ export default class MapSourceControl extends React.Component<
valueField = valueField === '' ? undefined : valueField;
if (mapType === MapType.CUSTOM) {
onBulkChange && onBulkChange({
map,
source: undefined,
labelField,
valueField
});
onBulkChange &&
onBulkChange({
map,
source: undefined,
labelField,
valueField
});
return;
}
if (mapType === MapType.API) {
onBulkChange && onBulkChange({
source,
map: undefined,
labelField,
valueField
});
onBulkChange &&
onBulkChange({
source,
map: undefined,
labelField,
valueField
});
return;
}
}
/**
*
*/
*
*/
@autobind
handleMapTypeChange(mapType: MapType) {
this.setState({
mapType,
labelField: undefined,
valueField: undefined
}, this.onChange);
this.setState(
{
mapType,
labelField: undefined,
valueField: undefined
},
this.onChange
);
}
renderHeader() {
const {
render,
label,
labelRemark,
useMobileUI,
env,
popOverContainer,
} = this.props;
const {render, label, labelRemark, useMobileUI, env, popOverContainer} =
this.props;
const classPrefix = env?.theme?.classPrefix;
const {mapType} = this.state;
const optionSourceList = (
@ -124,7 +127,7 @@ export default class MapSourceControl extends React.Component<
{
label: '外部接口',
value: MapType.API
},
}
] as Array<{
label: string;
value: MapType;
@ -136,7 +139,10 @@ export default class MapSourceControl extends React.Component<
return (
<header className="ae-OptionControl-header">
<label className={cx(`${classPrefix}Form-label`)} style={{marginBottom:0}}>
<label
className={cx(`${classPrefix}Form-label`)}
style={{marginBottom: 0}}
>
{label || ''}
{labelRemark
? render('label-remark', {
@ -200,27 +206,29 @@ export default class MapSourceControl extends React.Component<
}
renderOtherFields() {
return [{
label: tipedLabel(
'值匹配字段',
'映射表是数组对象且对象有多个key时用来匹配值的字段, 默认为value'
),
type: 'input-text',
name: 'valueField',
placeholder: '匹配字段默认为value',
onChange: this.handleValueFieldChange,
},
{
label: tipedLabel(
'显示字段',
'映射表是数组对象时用作显示的字段显示多字段请使用自定义显示模板默认为label'
),
type: 'input-text',
name: 'labelField',
placeholder: '显示字段默认为label',
onChange: this.handleLabelFieldChange,
visibleOn: '${!itemSchema}'
}]
return [
{
label: tipedLabel(
'值匹配字段',
'映射表是数组对象且对象有多个key时用来匹配值的字段, 默认为value'
),
type: 'input-text',
name: 'valueField',
placeholder: '匹配字段默认为value',
onChange: this.handleValueFieldChange
},
{
label: tipedLabel(
'显示字段',
'映射表是数组对象时用作显示的字段显示多字段请使用自定义显示模板默认为label'
),
type: 'input-text',
name: 'labelField',
placeholder: '显示字段默认为label',
onChange: this.handleLabelFieldChange,
visibleOn: '${!itemSchema}'
}
];
}
renderApiPanel() {
@ -248,85 +256,88 @@ export default class MapSourceControl extends React.Component<
renderObjectMap() {
const {render} = this.props;
return render('objectMap', getSchemaTpl('combo-container', {
label: '',
type: 'combo',
mode: 'normal',
scaffold: {
key: 'key-{index}',
value: 'value-{index}'
},
required: true,
name: 'map',
descriptionClassName: 'help-block text-xs m-b-none',
description:
'<p>当值命中左侧 Key 时,展示右侧内容<br />当没有命中时,默认展示 Key 为 <code>*</code>的内容</div><br />(请确保key值唯一)',
multiple: true,
pipeIn: (value: any) => {
if (!isObject(value)) {
return [
{
key: 'key0',
value: 'value1'
}
];
}
let arr: Array<any> = [];
Object.keys(value).forEach(key => {
arr.push({
key: key || '',
value:
typeof value[key] === 'string'
? value[key]
: JSON.stringify(value[key])
});
});
return arr;
},
pipeOut: (value: any) => {
if (!Array.isArray(value)) {
return value;
}
let obj: any = {};
value.forEach((item: any, idx: number) => {
let key: string = item.key || '';
let value: any = item.value;
if (key === 'key-{index}' && value === 'value-{index}') {
key = key.replace('-{index}', `${idx}`);
value = value.replace('-{index}', `${idx}`);
}
try {
value = JSON.parse(value);
} catch (e) {}
obj[key] = value;
});
return obj;
},
onChange: (value: any) => {
this.handleMapChange(value || {'*': '通配值'});
},
items: [
{
placeholder: 'Key',
type: 'input-text',
unique: true,
name: 'key',
required: true,
columnClassName: 'w-xs'
return render(
'objectMap',
getSchemaTpl('combo-container', {
label: '',
type: 'combo',
mode: 'normal',
scaffold: {
key: 'key-{index}',
value: 'value-{index}'
},
required: true,
name: 'map',
descriptionClassName: 'help-block text-xs m-b-none',
description:
'<p>当值命中左侧 Key 时,展示右侧内容<br />当没有命中时,默认展示 Key 为 <code>*</code>的内容</div><br />(请确保key值唯一)',
multiple: true,
pipeIn: (value: any) => {
if (!isObject(value)) {
return [
{
key: 'key0',
value: 'value1'
}
];
}
{
placeholder: '内容',
type: 'input-text',
name: 'value'
}
]
}));
let arr: Array<any> = [];
Object.keys(value).forEach(key => {
arr.push({
key: key || '',
value:
typeof value[key] === 'string'
? value[key]
: JSON.stringify(value[key])
});
});
return arr;
},
pipeOut: (value: any) => {
if (!Array.isArray(value)) {
return value;
}
let obj: any = {};
value.forEach((item: any, idx: number) => {
let key: string = item.key || '';
let value: any = item.value;
if (key === 'key-{index}' && value === 'value-{index}') {
key = key.replace('-{index}', `${idx}`);
value = value.replace('-{index}', `${idx}`);
}
try {
value = JSON.parse(value);
} catch (e) {}
obj[key] = value;
});
return obj;
},
onChange: (value: any) => {
this.handleMapChange(value || {'*': '通配值'});
},
items: [
{
placeholder: 'Key',
type: 'input-text',
unique: true,
name: 'key',
required: true,
columnClassName: 'w-xs'
},
{
placeholder: '内容',
type: 'input-text',
name: 'value'
}
]
})
);
}
handleMapItemChange(index: number, item: any) {
@ -341,26 +352,27 @@ export default class MapSourceControl extends React.Component<
renderArrayMap() {
const {render} = this.props;
return <div className='ae-ExtendMore'>
{render('arrayMap', [
{
type: 'json-editor',
name: 'map',
label: false,
placeholder: '请保持数组成员结构相同',
onChange: (value: any, ...args: any[]) => {
try {
const map = JSON.parse(value);
this.debounceMapChange(map)
return (
<div className="ae-ExtendMore">
{render('arrayMap', [
{
type: 'json-editor',
name: 'map',
label: false,
placeholder: '请保持数组成员结构相同',
onChange: (value: any, ...args: any[]) => {
try {
const map = JSON.parse(value);
this.debounceMapChange(map);
} catch (e) {
console.error();
}
}
catch (e) {
console.error();
}
}
},
...this.renderOtherFields()
])}
</div>;
},
...this.renderOtherFields()
])}
</div>
);
}
debounceMapChange = debounce(this.handleMapChange, 250);

View File

@ -8,7 +8,14 @@ import cx from 'classnames';
import uniqBy from 'lodash/uniqBy';
import omit from 'lodash/omit';
import Sortable from 'sortablejs';
import {FormItem, Button, Checkbox, Icon, InputBox, render as amisRender} from 'amis';
import {
FormItem,
Button,
Checkbox,
Icon,
InputBox,
render as amisRender
} from 'amis';
import {value2array} from 'amis-ui/lib/components/Select';
import {autobind, getI18nEnabled} from 'amis-editor-core';
@ -625,18 +632,16 @@ export default class OptionControl extends React.Component<
clearable={false}
onChange={(value: string) => this.handleEditLabel(index, value)}
/> */}
{
amisRender({
type: i18nEnabled ? 'input-text-i18n' : 'input-text',
className: 'ae-OptionControlItem-input',
value: label,
placeholder: '请输入文本/值',
clearable: false,
onChange: (value: string) => {
this.handleEditLabel(index, value);
}
})
}
{amisRender({
type: i18nEnabled ? 'input-text-i18n' : 'input-text',
className: 'ae-OptionControlItem-input',
value: label,
placeholder: '请输入文本/值',
clearable: false,
onChange: (value: string) => {
this.handleEditLabel(index, value);
}
})}
{render(
'dropdown',
{

View File

@ -336,8 +336,8 @@ export default class TreeOptionControl extends React.Component<
<a className="ae-TreeOptionControlItem-dragBar">
<Icon icon="drag-bar" className="icon" />
</a>
{
i18nEnabled ? amisRender({
{i18nEnabled ? (
amisRender({
type: 'input-text-i18n',
className: 'ae-TreeOptionControlItem-input-label',
value: option.label,
@ -349,18 +349,18 @@ export default class TreeOptionControl extends React.Component<
onI18nChange: (value: string) => {
this.handleEditLabelOrValue(value, path, 'label');
}
}) : (
<InputBox
className="ae-TreeOptionControlItem-input-label"
value={option.label}
placeholder="选项名称"
clearable={false}
onBlur={(event: any) => {
this.handleEditLabelOrValue(event.target.value, path, 'label');
}}
/>
)
}
})
) : (
<InputBox
className="ae-TreeOptionControlItem-input-label"
value={option.label}
placeholder="选项名称"
clearable={false}
onBlur={(event: any) => {
this.handleEditLabelOrValue(event.target.value, path, 'label');
}}
/>
)}
<InputBox
className="ae-TreeOptionControlItem-input-value"
value={option.value}

View File

@ -114,7 +114,10 @@ export default class ActionDialog extends React.Component<ActionDialogProp> {
) {
groupType = 'closeDialog';
}
if (value === 'visibility' && !['show', 'hidden', 'visibility'].includes(groupType)) {
if (
value === 'visibility' &&
!['show', 'hidden', 'visibility'].includes(groupType)
) {
groupType = 'show';
}

View File

@ -173,7 +173,7 @@ const Font: React.FC<FontProps> = props => {
// TODO: 添加'justify-all', 'start', 'end', 'match-parent'类型
getSchemaTpl('layout:textAlign', {
label: '文字位置',
mode: 'row',
mode: 'row'
}),
{
type: 'group',

View File

@ -5,7 +5,7 @@ import {
isObject,
tipedLabel,
DSField,
EditorManager,
EditorManager
} from 'amis-editor-core';
import {SchemaObject} from 'amis/lib/Schema';
import flatten from 'lodash/flatten';

View File

@ -235,28 +235,28 @@ setSchemaTpl(
}) => {
const configOptions = [
{
label: '块级(默认)',
label: '块级(block)',
icon: 'block-display',
value: 'block'
},
{
label: '弹性布局',
value: 'flex'
},
{
label: '行内弹性布局',
value: 'inline-flex'
},
{
label: '行内块级',
label: '行内区块(inline-block)',
icon: 'inline-block-display',
value: 'inline-block'
},
{
label: '行内元素',
label: '行内元素(inline)',
icon: 'inline-display',
value: 'inline'
},
{
label: '弹性布局(flex)',
icon: 'flex-display',
value: 'flex'
}
]
];
const configSchema = {
type: 'select',
type: 'button-icon-group',
label:
config?.label ||
tipedLabel(
@ -276,7 +276,7 @@ setSchemaTpl(
form.setValueByName('style.alignItems', undefined);
form.setValueByName('style.flexWrap', undefined);
}
},
}
};
if (config?.mode === 'vertical') {
@ -311,7 +311,6 @@ setSchemaTpl(
pipeIn?: (value: any, data: any) => void;
pipeOut?: (value: any, data: any) => void;
}) => {
const defaultOptions = [
{
label: '起始端对齐',
@ -1142,7 +1141,10 @@ setSchemaTpl(
size: 'xs',
label:
config?.label ||
tipedLabel('对齐方式', '通过 margin 数值来设置对齐方式,其中 margin: 0 auto 用于设置居中对齐'),
tipedLabel(
'对齐方式',
'通过 margin 数值来设置对齐方式,其中 margin: 0 auto 用于设置居中对齐'
),
name: config?.name || 'style.margin',
value: config?.value || '0',
inputClassName: 'inline-flex justify-between',
@ -1161,10 +1163,13 @@ setSchemaTpl(
{
label: '靠右',
value: 'auto 0px auto auto'
},
}
],
onChange: (value: string, oldValue: string, model: any, form: any) => {
if (form?.data?.style?.position === 'fixed' || form?.data?.style?.position === 'absolute') {
if (
form?.data?.style?.position === 'fixed' ||
form?.data?.style?.position === 'absolute'
) {
// 吸附容器
if (value === '0px auto') {
// 居中
@ -1342,10 +1347,7 @@ setSchemaTpl('layout:sticky', {
setSchemaTpl('layout:stickyPosition', {
type: 'button-group-select',
size: 'xs',
label: tipedLabel(
'吸附位置',
'用于设置滚动吸附时的位置'
),
label: tipedLabel('吸附位置', '用于设置滚动吸附时的位置'),
name: 'stickyPosition',
visibleOn: 'data.stickyStatus',
options: [
@ -1360,7 +1362,7 @@ setSchemaTpl('layout:stickyPosition', {
{
label: '自动',
value: 'auto'
},
}
],
onChange: (value: string, oldValue: string, model: any, form: any) => {
if (value === 'top') {
@ -1418,7 +1420,7 @@ setSchemaTpl(
label: '无',
value: 'none'
}
],
]
};
}
);
@ -1467,4 +1469,4 @@ setSchemaTpl(
]
};
}
);
);

View File

@ -1,4 +1,9 @@
import {setSchemaTpl, getSchemaTpl, defaultValue, getI18nEnabled} from 'amis-editor-core';
import {
setSchemaTpl,
getSchemaTpl,
defaultValue,
getI18nEnabled
} from 'amis-editor-core';
import {tipedLabel} from 'amis-editor-core';
import {SchemaObject} from 'amis/lib/Schema';
import assign from 'lodash/assign';
@ -86,7 +91,7 @@ setSchemaTpl('options', () => {
unique: true
}
]
}
};
});
setSchemaTpl('tree', {
@ -375,7 +380,10 @@ setSchemaTpl('dataMap', {
visibleOn: 'this.dataMapSwitch',
body: [
getSchemaTpl('switch', {
label: tipedLabel('原始数据打平', '开启后,会将所有原始数据打平设置到 data 中,并在此基础上定制'),
label: tipedLabel(
'原始数据打平',
'开启后,会将所有原始数据打平设置到 data 中,并在此基础上定制'
),
name: 'withDefaultData',
className: 'mb-0',
pipeIn: defaultValue(false),
@ -400,7 +408,9 @@ setSchemaTpl('dataMap', {
return data && data['&'] === '$$' ? omit(data, '&') : data;
},
onChange: (value: any, oldValue: any, model: any, form: any) => {
const newData = form.data.withDefaultData ? assign({'&': '$$'}, value) : cloneDeep(value);
const newData = form.data.withDefaultData
? assign({'&': '$$'}, value)
: cloneDeep(value);
form.setValues({
data: newData
});

View File

@ -1,6 +1,4 @@
import {
setSchemaTpl,
} from 'amis-editor-core';
import {setSchemaTpl} from 'amis-editor-core';
import {remarkTpl} from '../component/BaseControl';
setSchemaTpl(
@ -20,4 +18,4 @@ setSchemaTpl(
label: '标题提示',
labelRemark: '在标题旁展示提示'
})
);
);