Skip to content

Commit

Permalink
* kanban: support for dragging item from outside of kanban to create …
Browse files Browse the repository at this point in the history
…new item.
  • Loading branch information
catouse committed Feb 29, 2024
1 parent 3efaaaa commit cc13018
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 5 deletions.
24 changes: 23 additions & 1 deletion lib/kanban/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,27 @@
## 示例

```html:example: bg-surface
<div id="kanbanList"></div>
<div id="kanbanExample">
<div id="kanbanDragItems" class="card-list card-grid mb-4 gap-2">
<div class="card kanban-new-item">
<div class="card-heading"><div class="card-title">卡片1</div></div>
</div>
<div class="card kanban-new-item">
<div class="card-heading"><div class="card-title">卡片2</div></div>
</div>
<div class="card kanban-new-item">
<div class="card-heading"><div class="card-title">卡片3</div></div>
</div>
<div class="card kanban-new-item">
<div class="card-heading"><div class="card-title">卡片4</div></div>
</div>
<div class="card kanban-new-item">
<div class="card-heading"><div class="card-title">卡片5</div></div>
</div>
<div class="card kanban-new-item">
<div class="card-heading"><div class="card-title">卡片6</div></div>
</div>
</div>
<div id="kanbanList"></div>
</div>
```
10 changes: 9 additions & 1 deletion lib/kanban/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {$} from '@zui/core';
import {KanbanRegionProps, KanbanList, KanbanProps} from './src/main';
import {createKanbanData} from './dev/create-kanban-data';

onPageLoad(() => {
onPageUpdate(() => {
const kanban1Options: KanbanProps = {
key: 'kanban1',
data: {
Expand Down Expand Up @@ -257,6 +257,14 @@ onPageLoad(() => {
return dropInfo.col === 'assigned';
}
},
draggable: {
// 指定可以从哪个元素内部监听拖拽事件,可以为看板的或看板列表的父级元素,这样就可以实现从看板外部拖拽新的卡片到看板内部。
dragContainer: '#kanbanExample',
},
onDropNewItem: (info) => {
// 返回需要创建的新的卡片数据
return {id: `new-${$.guid++}`, title: info.drag.element.innerText};
},
};
const kanbanList = new KanbanList('#kanbanList', {
items: [kanbanOptions, kanbanRegionOptions],
Expand Down
33 changes: 31 additions & 2 deletions lib/kanban/src/component/kanban.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ export class Kanban<P extends KanbanProps = KanbanProps, S extends KanbanState =
return {type: 'item', element, item, lane: item.lane, col: item.col};
}
}
const $newItem = $element.closest('.kanban-new-item');
if ($newItem.length) {
return {type: 'newItem', element};
}
const $col = $element.closest('.kanban-header-col,.kanban-lane-col');
if ($col.length) {
return {type: 'col', element, col: $col.attr('z-col') as string, lane: $col.attr('z-lane') as string};
Expand Down Expand Up @@ -366,6 +370,29 @@ export class Kanban<P extends KanbanProps = KanbanProps, S extends KanbanState =
changeData.list.push(changeItem[itemKey] as string);
});
}
} else if (drag.type === 'newItem') {
const {onDropNewItem} = this.props;
let newItem: Partial<KanbanItem> | undefined;
if (onDropNewItem) {
newItem = onDropNewItem.call(this, info);
} else {
newItem = $(drag.element).data();
if (newItem?.item) {
newItem = newItem.item;
}
}
newItem = {
lane: drop.lane,
col: drop.col,
...newItem,
};
if (newItem) {
const colItems = data.items[drop.lane!][drop.col!];
const newColItems = [...colItems];
newColItems.push(newItem);
changes.items = newColItems;
changeData.list.push(newItem[itemKey] as string);
}
}
return {changes, data: changeData};
}
Expand All @@ -376,12 +403,13 @@ export class Kanban<P extends KanbanProps = KanbanProps, S extends KanbanState =
if (!draggable || !element) {
return;
}
const {dragTypes = 'item', onDragStart, onDrop, canDrop, dropRules} = this.props;
const {dragTypes = ['item', 'newItem'], onDragStart, onDrop, canDrop, dropRules} = this.props;
const dragTypeList = typeof dragTypes === 'string' ? dragTypes.split(',') : dragTypes;
const dragTypeSelectors: Record<string, string> = {
item: '.kanban-item',
lane: '.kanban-lane-name',
col: '.kanban-header-col',
newItem: '.kanban-new-item',
};
const userOptions = typeof draggable === 'object' ? draggable : {};
const updateDropElementAttr = (dropElement: HTMLElement, info?: KanbanDropInfo) => {
Expand All @@ -393,7 +421,7 @@ export class Kanban<P extends KanbanProps = KanbanProps, S extends KanbanState =
};
const dragOptions: DraggableOptions = {
...userOptions,
selector: userOptions.selector || dragTypeList.map(x => dragTypeSelectors[x] || '').join(''),
selector: userOptions.selector || dragTypeList.map(x => dragTypeSelectors[x] || '').filter(Boolean).join(','),
target: userOptions.target || ((dragElement: HTMLElement) => {
const info = this._getElementInfo(dragElement);
if (!info) {
Expand All @@ -403,6 +431,7 @@ export class Kanban<P extends KanbanProps = KanbanProps, S extends KanbanState =
lane: '.kanban-lane',
col: '.kanban-header-col',
item: '.kanban-item,.kanban-items',
newItem: '.kanban-item,.kanban-items',
})[info.type];
return $(element).find(selector);
}),
Expand Down
2 changes: 1 addition & 1 deletion lib/kanban/src/types/kanban-dnd-info.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {KanbanItemInfo} from './kanban-item-info';

export type KanbanDnDType = 'item' | 'lane' | 'col';
export type KanbanDnDType = 'item' | 'lane' | 'col' | 'newItem';

export type KanbanDropSide = 'before' | 'after' | 'inside';

Expand Down
1 change: 1 addition & 0 deletions lib/kanban/src/types/kanban-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export interface KanbanProps extends HElementProps {
canDrop?: (dragInfo: KanbanElementInfo, dropInfo: KanbanElementInfo) => boolean | void;
onDragStart?: (info: KanbanDragInfo) => void | boolean;
onDrop?: (changes: Partial<KanbanData>, info: KanbanDropInfo, restore: () => void) => void | false;
onDropNewItem?: (info: KanbanDropInfo) => KanbanItem | undefined;

/* Component lifecycle. */
beforeRender?: (options: KanbanProps) => void;
Expand Down

0 comments on commit cc13018

Please sign in to comment.