feat: improve draggable api
This commit is contained in:
parent
5b4dd1800e
commit
de25f56a79
@ -1,12 +1,13 @@
|
||||
import React from 'react';
|
||||
import { useDesignable } from '../..';
|
||||
import { SortableItem } from '../sortable-item';
|
||||
|
||||
export const BlockItem: React.FC<any> = (props) => {
|
||||
const { DesignableBar } = useDesignable();
|
||||
return (
|
||||
<div className="nb-block-item">
|
||||
<SortableItem>
|
||||
{props.children}
|
||||
<DesignableBar />
|
||||
</div>
|
||||
</SortableItem>
|
||||
);
|
||||
};
|
||||
|
@ -1,55 +1,15 @@
|
||||
import React from 'react';
|
||||
import { observer, useFieldSchema } from '@formily/react';
|
||||
import { uid } from '@formily/shared';
|
||||
import { observer, useField, useFieldSchema } from '@formily/react';
|
||||
import { useDraggable, useDroppable } from '@dnd-kit/core';
|
||||
import { SchemaComponent, SchemaComponentProvider, BlockItem, DndContext } from '@nocobase/client';
|
||||
|
||||
function Draggable(props) {
|
||||
const { attributes, listeners, setNodeRef, transform } = useDraggable({
|
||||
id: props.id,
|
||||
data: props.data,
|
||||
});
|
||||
const style = transform
|
||||
? {
|
||||
transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<button ref={setNodeRef} style={style} {...listeners} {...attributes}>
|
||||
{props.children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function Droppable(props) {
|
||||
const { isOver, setNodeRef } = useDroppable({
|
||||
id: props.id,
|
||||
data: props.data,
|
||||
});
|
||||
const style = {
|
||||
color: isOver ? 'green' : undefined,
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={setNodeRef} style={style}>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
import { BlockItem, DndContext, DragHandler, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
|
||||
import React from 'react';
|
||||
|
||||
const Block = observer((props) => {
|
||||
const fieldSchema = useFieldSchema();
|
||||
const field = useField();
|
||||
return (
|
||||
<Droppable id={field.address.toString()} data={{ schema: fieldSchema }}>
|
||||
<div style={{ marginBottom: 20, padding: '0 20px', height: 50, lineHeight: '50px', background: '#f1f1f1' }}>
|
||||
Block {fieldSchema.name}
|
||||
<Draggable id={field.address.toString()} data={{ schema: fieldSchema }}>
|
||||
Drag
|
||||
</Draggable>
|
||||
<DragHandler />
|
||||
</div>
|
||||
</Droppable>
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -1 +1,2 @@
|
||||
export * from './BlockItem';
|
||||
|
||||
|
@ -10,6 +10,9 @@ const useDragEnd = () => {
|
||||
console.log({ active, over });
|
||||
const activeSchema = active?.data?.current?.schema;
|
||||
const overSchema = over?.data?.current?.schema;
|
||||
const insertAdjacent = over?.data?.current?.insertAdjacent;
|
||||
const wrapSchema = over?.data?.current?.wrapSchema;
|
||||
const onInsertAdjacent = over?.data?.current?.onInsertAdjacent;
|
||||
|
||||
if (!activeSchema || !overSchema) {
|
||||
return;
|
||||
@ -20,7 +23,25 @@ const useDragEnd = () => {
|
||||
});
|
||||
|
||||
dn.on('afterInsertAdjacent', refresh);
|
||||
dn.insertBeforeBeginOrAfterEnd(activeSchema);
|
||||
dn.on('afterRemove', refresh);
|
||||
|
||||
if (activeSchema.parent === overSchema.parent) {
|
||||
return dn.insertBeforeBeginOrAfterEnd(activeSchema);
|
||||
}
|
||||
|
||||
if (insertAdjacent) {
|
||||
console.log('removeIfChildrenEmpty', activeSchema)
|
||||
dn.insertAdjacent(insertAdjacent, activeSchema, {
|
||||
wrap: wrapSchema,
|
||||
removeEmptyParents: true,
|
||||
});
|
||||
// onInsertAdjacent && onInsertAdjacent({
|
||||
// dn,
|
||||
// orginDraggedParentSchema,
|
||||
// draggedSchema: activeSchema,
|
||||
// });
|
||||
return;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { FormLayout } from '@formily/antd';
|
||||
import { createForm, FormPath } from '@formily/core';
|
||||
import {
|
||||
FieldContext,
|
||||
@ -72,7 +73,7 @@ const useDefaultValues = (props: any = {}, opts: any = {}) => {
|
||||
};
|
||||
|
||||
export const Form: ComposedForm = observer((props) => {
|
||||
const { useValues = useDefaultValues } = props;
|
||||
const { request, initialValue, useValues = useDefaultValues, ...others } = props;
|
||||
const decorator = useFormDecorator();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const form = useMemo(() => createForm(), []);
|
||||
@ -83,7 +84,13 @@ export const Form: ComposedForm = observer((props) => {
|
||||
form.setValues(data?.data);
|
||||
},
|
||||
});
|
||||
return <Spin spinning={loading}>{decorator ? <FormDecorator form={form} /> : <FormComponent form={form} />}</Spin>;
|
||||
return (
|
||||
<Spin spinning={loading}>
|
||||
<FormLayout layout={'vertical'} {...others}>
|
||||
{decorator ? <FormDecorator form={form} /> : <FormComponent form={form} />}
|
||||
</FormLayout>
|
||||
</Spin>
|
||||
);
|
||||
});
|
||||
|
||||
Form.__NOCOBASE_FORM = true;
|
||||
|
@ -1,115 +1,90 @@
|
||||
import React from 'react';
|
||||
import { uid } from '@formily/shared';
|
||||
import { observer, useFieldSchema } from '@formily/react';
|
||||
import { useDraggable, useDroppable } from '@dnd-kit/core';
|
||||
import { SchemaComponent, SchemaComponentProvider, Grid } from '@nocobase/client';
|
||||
|
||||
function Draggable(props) {
|
||||
const { attributes, listeners, setNodeRef, transform } = useDraggable({
|
||||
id: props.id,
|
||||
data: props.data,
|
||||
});
|
||||
const style = transform
|
||||
? {
|
||||
transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<button ref={setNodeRef} style={style} {...listeners} {...attributes}>
|
||||
{props.children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function Droppable(props) {
|
||||
const { isOver, setNodeRef } = useDroppable({
|
||||
id: props.id,
|
||||
data: props.data,
|
||||
});
|
||||
const style = {
|
||||
color: isOver ? 'green' : undefined,
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={setNodeRef} style={style}>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
import { uid } from '@formily/shared';
|
||||
import { BlockItem, DragHandler, Grid, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
|
||||
import React from 'react';
|
||||
|
||||
const Block = observer((props) => {
|
||||
const fieldSchema = useFieldSchema();
|
||||
return (
|
||||
<Droppable id={fieldSchema.name} data={{ schema: fieldSchema }}>
|
||||
<div style={{ marginBottom: 20, padding: '0 20px', height: 50, lineHeight: '50px', background: '#f1f1f1' }}>
|
||||
Block {fieldSchema.name}
|
||||
<Draggable id={fieldSchema.name} data={{ schema: fieldSchema }}>
|
||||
Drag
|
||||
</Draggable>
|
||||
Block {fieldSchema.title}
|
||||
<DragHandler />
|
||||
</div>
|
||||
</Droppable>
|
||||
);
|
||||
});
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<SchemaComponentProvider components={{ Grid, Block }}>
|
||||
<SchemaComponentProvider components={{ Grid, Block, BlockItem }}>
|
||||
<SchemaComponent
|
||||
schema={{
|
||||
type: 'void',
|
||||
name: 'page',
|
||||
name: 'grid1',
|
||||
'x-component': 'Grid',
|
||||
'x-uid': uid(),
|
||||
properties: {
|
||||
[uid()]: {
|
||||
row1: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
'x-uid': uid(),
|
||||
properties: {
|
||||
[uid()]: {
|
||||
col11: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
[uid()]: {
|
||||
block1: {
|
||||
type: 'void',
|
||||
title: '1',
|
||||
'x-decorator': 'BlockItem',
|
||||
'x-component': 'Block',
|
||||
},
|
||||
block2: {
|
||||
type: 'void',
|
||||
title: '2',
|
||||
'x-decorator': 'BlockItem',
|
||||
'x-component': 'Block',
|
||||
},
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
col12: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
[uid()]: {
|
||||
block3: {
|
||||
type: 'void',
|
||||
title: '3',
|
||||
'x-decorator': 'BlockItem',
|
||||
'x-component': 'Block',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
row2: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
'x-uid': uid(),
|
||||
properties: {
|
||||
[uid()]: {
|
||||
col21: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
[uid()]: {
|
||||
block4: {
|
||||
type: 'void',
|
||||
title: '4',
|
||||
'x-decorator': 'BlockItem',
|
||||
'x-component': 'Block',
|
||||
},
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
col22: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
[uid()]: {
|
||||
block5: {
|
||||
type: 'void',
|
||||
title: '5',
|
||||
'x-decorator': 'BlockItem',
|
||||
'x-component': 'Block',
|
||||
},
|
||||
},
|
||||
|
@ -1,5 +1,9 @@
|
||||
import { useDroppable } from '@dnd-kit/core';
|
||||
import { css } from '@emotion/css';
|
||||
import { observer, RecursionField, Schema, useField, useFieldSchema } from '@formily/react';
|
||||
import { uid } from '@formily/shared';
|
||||
import cls from 'classnames';
|
||||
import React from 'react';
|
||||
import { observer } from '@formily/react';
|
||||
import { DndContext } from '../dnd-context';
|
||||
|
||||
export const Grid: any = observer((props) => {
|
||||
@ -10,10 +14,72 @@ export const Grid: any = observer((props) => {
|
||||
);
|
||||
});
|
||||
|
||||
const ColDivider = (props) => {
|
||||
const { isOver, setNodeRef } = useDroppable({
|
||||
id: props.id,
|
||||
data: props.data,
|
||||
});
|
||||
|
||||
const droppableStyle = {
|
||||
backgroundColor: isOver ? 'green' : undefined,
|
||||
};
|
||||
|
||||
return <div ref={setNodeRef} style={{ width: 24, ...droppableStyle }}></div>;
|
||||
};
|
||||
|
||||
Grid.Row = observer((props) => {
|
||||
return <div>{props.children}</div>;
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const addr = field.address.toString();
|
||||
const wrapSchema = (schema: Schema) => {
|
||||
const s = new Schema({
|
||||
type: 'void',
|
||||
name: `col_${uid()}`,
|
||||
'x-uid': uid(),
|
||||
'x-component': 'Grid.Col',
|
||||
});
|
||||
// parent 更新了,需要重新指定
|
||||
if (Schema.isSchemaInstance(schema)) {
|
||||
schema.parent = s;
|
||||
}
|
||||
s.addProperty(schema.name, schema);
|
||||
return s;
|
||||
};
|
||||
const onInsertAdjacent = ({ dn, draggedSchema }) => {
|
||||
dn.remove(draggedSchema, {
|
||||
removeEmptyParents: true,
|
||||
});
|
||||
};
|
||||
console.log('fieldSchema', fieldSchema.toJSON());
|
||||
return (
|
||||
<div
|
||||
className={cls(
|
||||
'nb-grid-row',
|
||||
css`
|
||||
margin: 0 -24px;
|
||||
display: flex;
|
||||
`,
|
||||
)}
|
||||
>
|
||||
<ColDivider
|
||||
id={`${addr}_0`}
|
||||
data={{ wrapSchema, insertAdjacent: 'afterBegin', schema: fieldSchema, onInsertAdjacent }}
|
||||
/>
|
||||
{fieldSchema.mapProperties((schema, key, index) => {
|
||||
return (
|
||||
<React.Fragment key={key}>
|
||||
<RecursionField name={key} schema={schema} />
|
||||
<ColDivider
|
||||
id={`${addr}_${index + 1}`}
|
||||
data={{ wrapSchema, insertAdjacent: 'afterEnd', schema, onInsertAdjacent }}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
Grid.Col = observer((props) => {
|
||||
return <div>{props.children}</div>;
|
||||
return <div className={cls('nb-grid-col')}>{props.children}</div>;
|
||||
});
|
||||
|
@ -25,8 +25,10 @@ export * from './radio';
|
||||
export * from './record-picker';
|
||||
export * from './row-selection';
|
||||
export * from './select';
|
||||
export * from './sortable-item';
|
||||
export * from './tabs';
|
||||
export * from './time-picker';
|
||||
export * from './tree-select';
|
||||
export * from './upload';
|
||||
export * from './void-table';
|
||||
|
||||
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
nav:
|
||||
path: /client
|
||||
group:
|
||||
path: /schema-components
|
||||
---
|
||||
|
||||
# SortableItem
|
||||
|
@ -0,0 +1,61 @@
|
||||
import { useDraggable, useDroppable } from '@dnd-kit/core';
|
||||
import { observer, useField, useFieldSchema } from '@formily/react';
|
||||
import React, { createContext, useContext } from 'react';
|
||||
|
||||
export const DraggableContext = createContext(null);
|
||||
|
||||
export const Sortable = (props: any) => {
|
||||
const draggable = useDraggable({
|
||||
id: props.id,
|
||||
data: props.data,
|
||||
});
|
||||
|
||||
const { isOver, setNodeRef } = useDroppable({
|
||||
id: props.id,
|
||||
data: props.data,
|
||||
});
|
||||
|
||||
const droppableStyle = {
|
||||
color: isOver ? 'green' : undefined,
|
||||
};
|
||||
|
||||
return (
|
||||
<DraggableContext.Provider value={draggable}>
|
||||
<div ref={setNodeRef} style={droppableStyle}>
|
||||
{props.children}
|
||||
</div>
|
||||
</DraggableContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const SortableItem = observer((props) => {
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const onInsertAdjacent = ({ dn, orginDraggedParentSchema }) => {
|
||||
dn.removeIfChildrenEmpty(orginDraggedParentSchema, {
|
||||
removeEmptyParents: true,
|
||||
});
|
||||
};
|
||||
return (
|
||||
<Sortable
|
||||
id={field.address.toString()}
|
||||
data={{ insertAdjacent: 'afterEnd', onInsertAdjacent, schema: fieldSchema }}
|
||||
>
|
||||
{props.children}
|
||||
</Sortable>
|
||||
);
|
||||
});
|
||||
|
||||
export const DragHandler = () => {
|
||||
const { attributes, listeners, setNodeRef, transform } = useContext(DraggableContext);
|
||||
const style = transform
|
||||
? {
|
||||
transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
|
||||
}
|
||||
: undefined;
|
||||
return (
|
||||
<div ref={setNodeRef} style={{ ...style, display: 'inline-block' }} {...listeners} {...attributes}>
|
||||
Drag
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,8 +1,8 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { ISchema, Schema, useField, useFieldSchema } from '@formily/react';
|
||||
import { SchemaComponentContext } from '../context';
|
||||
import set from 'lodash/set';
|
||||
import { uid } from '@formily/shared';
|
||||
import set from 'lodash/set';
|
||||
import React, { useContext } from 'react';
|
||||
import { SchemaComponentContext } from '../context';
|
||||
|
||||
interface CreateDesignableProps {
|
||||
current: Schema;
|
||||
@ -17,6 +17,11 @@ export function createDesignable(options: CreateDesignableProps) {
|
||||
*/
|
||||
type Position = 'beforeBegin' | 'afterBegin' | 'beforeEnd' | 'afterEnd';
|
||||
|
||||
interface InsertAdjacentOptions {
|
||||
wrap?: (s: ISchema) => ISchema;
|
||||
removeEmptyParents?: boolean;
|
||||
}
|
||||
|
||||
const generateUid = (s: ISchema) => {
|
||||
if (!s['x-uid']) {
|
||||
s['x-uid'] = uid();
|
||||
@ -26,6 +31,8 @@ const generateUid = (s: ISchema) => {
|
||||
});
|
||||
};
|
||||
|
||||
const defaultWrap = (s: ISchema) => s;
|
||||
|
||||
export class Designable {
|
||||
current: Schema;
|
||||
|
||||
@ -66,25 +73,63 @@ export class Designable {
|
||||
this.events[name].forEach((fn) => fn.bind(this)(...args));
|
||||
}
|
||||
|
||||
insertAdjacent(position: Position, schema: ISchema) {
|
||||
insertAdjacent(position: Position, schema: ISchema, options: InsertAdjacentOptions = {}) {
|
||||
switch (position) {
|
||||
case 'beforeBegin':
|
||||
return this.insertBeforeBegin(schema);
|
||||
return this.insertBeforeBegin(schema, options);
|
||||
case 'afterBegin':
|
||||
return this.insertAfterBegin(schema);
|
||||
return this.insertAfterBegin(schema, options);
|
||||
case 'beforeEnd':
|
||||
return this.insertBeforeEnd(schema);
|
||||
return this.insertBeforeEnd(schema, options);
|
||||
case 'afterEnd':
|
||||
return this.insertAfterEnd(schema);
|
||||
return this.insertAfterEnd(schema, options);
|
||||
}
|
||||
}
|
||||
|
||||
remove() {
|
||||
const s = this.current.parent.removeProperty(this.current.name);
|
||||
this.emit('afterRemove', s);
|
||||
removeIfChildrenEmpty(schema?: Schema, options: { recursive?: boolean } = {}) {
|
||||
if (!schema) {
|
||||
return;
|
||||
}
|
||||
const { recursive } = options;
|
||||
let s = schema;
|
||||
const count = Object.keys(s.properties || {}).length;
|
||||
console.log('removeIfChildrenEmpty', count, s.properties);
|
||||
if (count > 0) {
|
||||
return;
|
||||
}
|
||||
let removed;
|
||||
while (s.parent) {
|
||||
removed = s.parent.removeProperty(s.name);
|
||||
if (!recursive) {
|
||||
break;
|
||||
}
|
||||
const count = Object.keys(s.parent.properties || {}).length;
|
||||
if (count > 0) {
|
||||
break;
|
||||
}
|
||||
s = s.parent;
|
||||
}
|
||||
}
|
||||
|
||||
insertBeforeBeginOrAfterEnd(schema: ISchema) {
|
||||
remove(schema?: Schema, options: { removeEmptyParents?: boolean } = {}) {
|
||||
const { removeEmptyParents } = options;
|
||||
let s = schema || this.current;
|
||||
let removed;
|
||||
while (s.parent) {
|
||||
removed = s.parent.removeProperty(s.name);
|
||||
if (!removeEmptyParents) {
|
||||
break;
|
||||
}
|
||||
const count = Object.keys(s.parent.properties || {}).length;
|
||||
if (count > 0) {
|
||||
break;
|
||||
}
|
||||
s = s.parent;
|
||||
}
|
||||
this.emit('afterRemove', removed);
|
||||
}
|
||||
|
||||
insertBeforeBeginOrAfterEnd(schema: ISchema, options: InsertAdjacentOptions = {}) {
|
||||
if (!Schema.isSchemaInstance(this.current)) {
|
||||
return;
|
||||
}
|
||||
@ -104,22 +149,25 @@ export class Designable {
|
||||
fromIndex = index;
|
||||
}
|
||||
});
|
||||
return fromIndex > toIndex ? this.insertBeforeBegin(schema) : this.insertAfterEnd(schema);
|
||||
return fromIndex > toIndex ? this.insertBeforeBegin(schema, options) : this.insertAfterEnd(schema, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Before the current schema itself.
|
||||
*/
|
||||
insertBeforeBegin(schema: ISchema) {
|
||||
insertBeforeBegin(schema: ISchema, options: InsertAdjacentOptions = {}) {
|
||||
if (!Schema.isSchemaInstance(this.current)) {
|
||||
return;
|
||||
}
|
||||
const { wrap = defaultWrap, removeEmptyParents } = options;
|
||||
const properties = {};
|
||||
let start = false;
|
||||
|
||||
if (Schema.isSchemaInstance(schema)) {
|
||||
schema.parent.removeProperty(schema.name);
|
||||
schema.parent = this.current.parent;
|
||||
if (removeEmptyParents) {
|
||||
this.removeIfChildrenEmpty(schema.parent);
|
||||
}
|
||||
}
|
||||
|
||||
this.current.parent.mapProperties((property, key) => {
|
||||
@ -133,7 +181,9 @@ export class Designable {
|
||||
});
|
||||
|
||||
this.prepareProperty(schema);
|
||||
const s = this.current.parent.addProperty(schema.name, schema);
|
||||
const wrapped = wrap(schema);
|
||||
const s = this.current.parent.addProperty(wrapped.name, wrapped);
|
||||
s.parent = this.current.parent;
|
||||
this.current.parent.setProperties(properties);
|
||||
this.emit('afterInsertAdjacent', 'beforeBegin', s);
|
||||
}
|
||||
@ -144,13 +194,16 @@ export class Designable {
|
||||
* @param schema
|
||||
* @returns
|
||||
*/
|
||||
insertAfterBegin(schema: ISchema) {
|
||||
insertAfterBegin(schema: ISchema, options: InsertAdjacentOptions = {}) {
|
||||
if (!Schema.isSchemaInstance(this.current)) {
|
||||
return;
|
||||
}
|
||||
const { wrap = defaultWrap, removeEmptyParents } = options;
|
||||
if (Schema.isSchemaInstance(schema)) {
|
||||
schema.parent.removeProperty(schema.name);
|
||||
schema.parent = this.current;
|
||||
if (removeEmptyParents) {
|
||||
this.removeIfChildrenEmpty(schema.parent);
|
||||
}
|
||||
}
|
||||
const properties = {};
|
||||
this.current.mapProperties((schema, key) => {
|
||||
@ -158,7 +211,9 @@ export class Designable {
|
||||
});
|
||||
this.current.properties = {};
|
||||
this.prepareProperty(schema);
|
||||
const s = this.current.addProperty(schema.name, schema);
|
||||
const wrapped = wrap(schema);
|
||||
const s = this.current.addProperty(wrapped.name, wrapped);
|
||||
s.parent = this.current;
|
||||
this.current.setProperties(properties);
|
||||
this.emit('afterInsertAdjacent', 'afterBegin', s);
|
||||
}
|
||||
@ -169,32 +224,40 @@ export class Designable {
|
||||
* @param schema
|
||||
* @returns
|
||||
*/
|
||||
insertBeforeEnd(schema: ISchema) {
|
||||
insertBeforeEnd(schema: ISchema, options: InsertAdjacentOptions = {}) {
|
||||
if (!Schema.isSchemaInstance(this.current)) {
|
||||
return;
|
||||
}
|
||||
const { wrap = defaultWrap, removeEmptyParents } = options;
|
||||
if (Schema.isSchemaInstance(schema)) {
|
||||
schema.parent.removeProperty(schema.name);
|
||||
schema.parent = this.current;
|
||||
if (removeEmptyParents) {
|
||||
this.removeIfChildrenEmpty(schema.parent);
|
||||
}
|
||||
}
|
||||
this.prepareProperty(schema);
|
||||
const s = this.current.addProperty(schema.name || uid(), schema);
|
||||
const wrapped = wrap(schema);
|
||||
const s = this.current.addProperty(wrapped.name || uid(), wrapped);
|
||||
s.parent = this.current;
|
||||
this.emit('afterInsertAdjacent', 'beforeEnd', s);
|
||||
}
|
||||
|
||||
/**
|
||||
* After the current schema itself.
|
||||
*/
|
||||
insertAfterEnd(schema: ISchema) {
|
||||
insertAfterEnd(schema: ISchema, options: InsertAdjacentOptions = {}) {
|
||||
if (!Schema.isSchemaInstance(this.current)) {
|
||||
return;
|
||||
}
|
||||
const properties = {};
|
||||
let start = false;
|
||||
|
||||
const { wrap = defaultWrap, removeEmptyParents } = options;
|
||||
if (Schema.isSchemaInstance(schema)) {
|
||||
schema.parent.removeProperty(schema.name);
|
||||
schema.parent = this.current.parent;
|
||||
if (removeEmptyParents) {
|
||||
this.removeIfChildrenEmpty(schema.parent);
|
||||
}
|
||||
schema.parent = null;
|
||||
}
|
||||
|
||||
this.current.parent.mapProperties((property, key) => {
|
||||
@ -208,7 +271,11 @@ export class Designable {
|
||||
});
|
||||
|
||||
this.prepareProperty(schema);
|
||||
const s = this.current.parent.addProperty(schema.name || uid(), schema);
|
||||
|
||||
const wrapped = wrap(schema);
|
||||
|
||||
const s = this.current.parent.addProperty(wrapped.name || uid(), wrapped);
|
||||
s.parent = this.current.parent;
|
||||
this.current.parent.setProperties(properties);
|
||||
this.emit('afterInsertAdjacent', 'afterEnd', s);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user