Merge pull request #9949 from zhangtao07/master

chore: flex布局设置优化
This commit is contained in:
张涛 2024-04-01 20:52:48 +08:00 committed by GitHub
commit d1dd59cc8a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 86 additions and 56 deletions

View File

@ -24,6 +24,6 @@
&-itemColumn { &-itemColumn {
height: 100%; height: 100%;
background-color: #999; background-color: #ccc;
} }
} }

View File

@ -141,24 +141,21 @@ export class ContainerPlugin extends LayoutBasePlugin {
const node = context.node!; const node = context.node!;
const isFlexItem = this.manager?.isFlexItem(node.id); const isFlexItem = this.manager?.isFlexItem(node.id);
if (isFlexItem && context.node.parent?.children?.length > 1) { if (isFlexItem) {
let isColumnFlex = String(node.schema?.style?.flexDirection).includes( let isColumnFlex = this.manager.isFlexColumnItem(node.id);
'column' context?.node.setHeightMutable(
node?.schema?.isFixedHeight && !isColumnFlex
); );
console.log( context?.node.setWidthMutable(
'isColumnFlex', (!isColumnFlex && context.node.parent?.children?.length > 1) ||
isColumnFlex, node.schema?.style?.flex === '0 0 150px'
node.schema?.style?.flexDirection
); );
// context?.node.setHeightMutable(isColumnFlex); } else {
context?.node.setWidthMutable(!isColumnFlex); context?.node.setHeightMutable(node.schema?.isFixedHeight);
context?.node.setWidthMutable(node.schema?.isFixedWidth);
} }
} }
afterUpdate(event: PluginEvent<ActiveEventContext>) {
const node = event.context?.node;
}
onWidthChangeStart( onWidthChangeStart(
event: PluginEvent< event: PluginEvent<
ResizeMoveEventContext, ResizeMoveEventContext,
@ -177,11 +174,11 @@ export class ContainerPlugin extends LayoutBasePlugin {
if (!parent) { if (!parent) {
return; return;
} }
console.log('on width change start');
const resizer = context.resizer; const resizer = context.resizer;
const frameRect = parent.getBoundingClientRect(); const frameRect = parent.getBoundingClientRect();
const rect = dom.getBoundingClientRect(); const rect = dom.getBoundingClientRect();
const isFlexItem = this.manager?.isFlexItem(node.id); const isFlexItem = this.manager?.isFlexItem(node.id);
const isColumnFlex = this.manager?.isFlexColumnItem(node.id);
const schema = node.schema; const schema = node.schema;
const index = node.index; const index = node.index;
const isFlexSize = const isFlexSize =
@ -234,7 +231,7 @@ export class ContainerPlugin extends LayoutBasePlugin {
} }
} }
} else { } else {
if (isFlexItem) { if (isFlexItem && !isColumnFlex) {
node.updateState({ node.updateState({
style: { style: {
...node.schema.style, ...node.schema.style,
@ -270,7 +267,7 @@ export class ContainerPlugin extends LayoutBasePlugin {
item.updateState({}, true); item.updateState({}, true);
}); });
} else { } else {
if (isFlexItem) { if (isFlexItem && !isColumnFlex) {
node.updateSchema({ node.updateSchema({
style: { style: {
...node.schema.style, ...node.schema.style,
@ -296,18 +293,18 @@ export class ContainerPlugin extends LayoutBasePlugin {
}); });
} }
onHeightChangeStart( // onHeightChangeStart(
event: PluginEvent< // event: PluginEvent<
ResizeMoveEventContext, // ResizeMoveEventContext,
{ // {
onMove(e: MouseEvent): void; // onMove(e: MouseEvent): void;
onEnd(e: MouseEvent): void; // onEnd(e: MouseEvent): void;
} // }
> // >
) { // ) {
console.log('on height change start'); // // console.log('on height change start');
// return this.onSizeChangeStart(event, 'vertical'); // // return this.onSizeChangeStart(event, 'vertical');
} // }
panelBodyCreator = (context: BaseEventContext) => { panelBodyCreator = (context: BaseEventContext) => {
const curRendererSchema = context?.schema; const curRendererSchema = context?.schema;

View File

@ -6,7 +6,8 @@ import {
JSONPipeOut, JSONPipeOut,
LayoutBasePlugin, LayoutBasePlugin,
PluginEvent, PluginEvent,
reGenerateID reGenerateID,
tipedLabel
} from 'amis-editor-core'; } from 'amis-editor-core';
import {getSchemaTpl} from 'amis-editor-core'; import {getSchemaTpl} from 'amis-editor-core';
import {Button, PlainObject} from 'amis'; import {Button, PlainObject} from 'amis';
@ -108,13 +109,7 @@ export class FlexPluginBase extends LayoutBasePlugin {
if (/^[\d:]+$/.test(value) && isAlive(node)) { if (/^[\d:]+$/.test(value) && isAlive(node)) {
let list = value.trim().split(':'); let list = value.trim().split(':');
let children = node.children || []; let children = node.children || [];
const isColumn = this.manager?.isFlexColumnItem(node.id);
if (String(node.schema?.style?.flexDirection).includes('column')) {
list = list.reverse();
node.updateSchemaStyle({
flexDirection: 'row'
});
}
// 更新flex布局 // 更新flex布局
for (let i = 0; i < children.length; i++) { for (let i = 0; i < children.length; i++) {
@ -122,7 +117,7 @@ export class FlexPluginBase extends LayoutBasePlugin {
child.updateSchemaStyle({ child.updateSchemaStyle({
flexGrow: +list[i], flexGrow: +list[i],
width: undefined, width: undefined,
flexBasis: 0, flexBasis: isColumn ? 'auto' : 0,
flex: '1 1 auto' flex: '1 1 auto'
}); });
} }
@ -130,7 +125,7 @@ export class FlexPluginBase extends LayoutBasePlugin {
// 增加或删除列 // 增加或删除列
if (children.length < list.length) { if (children.length < list.length) {
for (let i = 0; i < list.length - children.length; i++) { for (let i = 0; i < list.length - children.length; i++) {
let newColumnSchema = defaultFlexColumnSchema(); let newColumnSchema = defaultFlexColumnSchema('', !isColumn);
newColumnSchema.style.flexGrow = +list[i]; newColumnSchema.style.flexGrow = +list[i];
this.manager.addElem(newColumnSchema, true, false); this.manager.addElem(newColumnSchema, true, false);
} }
@ -214,6 +209,7 @@ export class FlexPluginBase extends LayoutBasePlugin {
const isFlexColumnItem = this.manager?.isFlexColumnItem(context?.id); const isFlexColumnItem = this.manager?.isFlexColumnItem(context?.id);
// 判断是否为吸附容器 // 判断是否为吸附容器
const isSorptionContainer = curRendererSchema?.isSorptionContainer || false; const isSorptionContainer = curRendererSchema?.isSorptionContainer || false;
const flexDirection = context.node?.schema?.style?.flexDirection || 'row';
const positionTpl = [ const positionTpl = [
getSchemaTpl('layout:position', { getSchemaTpl('layout:position', {
@ -239,6 +235,7 @@ export class FlexPluginBase extends LayoutBasePlugin {
getSchemaTpl('layout:flex-layout', { getSchemaTpl('layout:flex-layout', {
name: 'layout', name: 'layout',
label: '快捷版式设置', label: '快捷版式设置',
flexDirection,
pipeIn: () => { pipeIn: () => {
if (isAlive(context.node)) { if (isAlive(context.node)) {
let children = context.node?.children || []; let children = context.node?.children || [];
@ -323,10 +320,12 @@ export class FlexPluginBase extends LayoutBasePlugin {
getSchemaTpl('layout:flex-basis', { getSchemaTpl('layout:flex-basis', {
label: '行间隔', label: '行间隔',
tooltip: '垂直排布时,内部容器之间的间隔',
name: 'style.rowGap' name: 'style.rowGap'
}), }),
getSchemaTpl('layout:flex-basis', { getSchemaTpl('layout:flex-basis', {
label: '列间隔', label: '列间隔',
tooltip: '水平排布时,内部容器之间的间隔',
name: 'style.columnGap' name: 'style.columnGap'
}), }),

View File

@ -2,7 +2,7 @@
* @file flex * @file flex
*/ */
import React from 'react'; import React, {useEffect, useState} from 'react';
import {InputBox, TooltipWrapper} from 'amis-ui'; import {InputBox, TooltipWrapper} from 'amis-ui';
import {FormControlProps, FormItem} from 'amis-core'; import {FormControlProps, FormItem} from 'amis-core';
import cx from 'classnames'; import cx from 'classnames';
@ -11,12 +11,14 @@ function LayoutItem({
value, value,
onSelect, onSelect,
active, active,
tip tip,
flexDirection
}: { }: {
value: string; value: string;
onSelect: () => void; onSelect: () => void;
active?: boolean; active?: boolean;
tip?: string; tip?: string;
flexDirection?: React.CSSProperties['flexDirection'];
}) { }) {
const items = String(value).split(':'); const items = String(value).split(':');
return ( return (
@ -25,7 +27,10 @@ function LayoutItem({
className={cx('ae-FlexLayout-item', { className={cx('ae-FlexLayout-item', {
active active
})} })}
style={{flex: value}} style={{
flex: value,
flexDirection: flexDirection || 'row'
}}
onClick={onSelect} onClick={onSelect}
> >
{items.map(val => ( {items.map(val => (
@ -38,10 +43,12 @@ function LayoutItem({
function FlexLayouts({ function FlexLayouts({
onChange, onChange,
value value,
flexDirection
}: { }: {
onChange: (value: string) => void; onChange: (value: string) => void;
value?: string; value?: string;
flexDirection?: React.CSSProperties['flexDirection'];
}) { }) {
const presetLayouts = [ const presetLayouts = [
'1', '1',
@ -53,14 +60,27 @@ function FlexLayouts({
'1:2:1', '1:2:1',
'1:1:1:1' '1:1:1:1'
]; ];
let currentLayout = value; const [currentLayout, setCurrentLayout] = useState<string>('');
useEffect(() => {
if (value) { if (value) {
// 转换成1:x格式 // 转换成1:x格式
let items = String(value).split(':'); let items = String(value).split(':');
const min = Math.min.apply(null, items); const min = Math.min.apply(null, items);
if (items.every(item => +item % min === 0)) { if (items.every(item => +item % min === 0)) {
items = items.map(item => String(+item / min)); items = items.map(item => String(+item / min));
currentLayout = items.join(':'); let layout = items.join(':');
if (layout !== currentLayout) {
setCurrentLayout(items.join(':'));
}
} else if (value !== currentLayout) {
setCurrentLayout(value);
}
}
}, []);
function onChangeLayout() {
if (/\d[\d:]+\d$/.test(currentLayout)) {
onChange(currentLayout);
} }
} }
@ -72,7 +92,11 @@ function FlexLayouts({
key={item} key={item}
value={item} value={item}
tip={`排列${item}`} tip={`排列${item}`}
onSelect={() => onChange(item)} flexDirection={flexDirection}
onSelect={() => {
setCurrentLayout(item);
onChange(item);
}}
active={item === currentLayout} active={item === currentLayout}
/> />
))} ))}
@ -83,10 +107,16 @@ function FlexLayouts({
<InputBox <InputBox
className="ae-FlexLayout-input" className="ae-FlexLayout-input"
clearable={false} clearable={false}
value={value} value={currentLayout}
placeholder="例如 1:3:2" placeholder="例如 1:3:2"
onChange={val => (currentLayout = val)} onChange={val => setCurrentLayout(val)}
onBlur={() => currentLayout && onChange(currentLayout)} onBlur={() => currentLayout && onChangeLayout()}
onKeyDown={e => {
if (e.key === 'Enter') {
e.preventDefault();
onChangeLayout();
}
}}
/> />
</div> </div>
</div> </div>

View File

@ -623,6 +623,7 @@ setSchemaTpl(
'layout:flex-basis', 'layout:flex-basis',
(config?: { (config?: {
label?: string; label?: string;
tooltip?: string;
name?: string; name?: string;
value?: string; value?: string;
visibleOn?: string; visibleOn?: string;
@ -634,6 +635,7 @@ setSchemaTpl(
type: 'input-number', type: 'input-number',
label: tipedLabel( label: tipedLabel(
config?.label || '默认宽度', config?.label || '默认宽度',
config?.tooltip ||
'在分配多余空间之前其默认占据的主轴空间main size' '在分配多余空间之前其默认占据的主轴空间main size'
), ),
name: config?.name || 'style.flexBasis', name: config?.name || 'style.flexBasis',
@ -1498,6 +1500,7 @@ setSchemaTpl(
name?: string; name?: string;
label?: string; label?: string;
visibleOn?: string; visibleOn?: string;
flexDirection?: string;
pipeIn?: (value: any, data: any) => void; pipeIn?: (value: any, data: any) => void;
pipeOut?: (value: any, data: any) => void; pipeOut?: (value: any, data: any) => void;
}) => { }) => {
@ -1507,6 +1510,7 @@ setSchemaTpl(
name: config?.name || 'layout', name: config?.name || 'layout',
label: config?.label ?? false, label: config?.label ?? false,
visibleOn: config?.visibleOn, visibleOn: config?.visibleOn,
flexDirection: config?.flexDirection,
pipeIn: config?.pipeIn, pipeIn: config?.pipeIn,
pipeOut: config?.pipeOut pipeOut: config?.pipeOut
}; };