Skip to content

Commit

Permalink
feat: add group, ungroup in helper
Browse files Browse the repository at this point in the history
  • Loading branch information
daybrush committed Jun 20, 2023
1 parent fb90fbd commit 8434ed1
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 51 deletions.
2 changes: 1 addition & 1 deletion packages/helper/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@moveable/helper",
"version": "0.1.2",
"version": "0.1.3",
"description": "Helper for demo of Moveable",
"main": "./dist/helper.cjs.js",
"module": "./dist/helper.esm.js",
Expand Down
108 changes: 60 additions & 48 deletions packages/helper/src/GroupManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,6 @@ import { GroupArrayChild, GroupSingleChild } from "./groups";
import { GroupChild, TargetGroupsObject, TargetGroupsType, TargetList } from "./types";


function createGroupChildren(
targetGroups: TargetGroupsObject,
parent: GroupArrayChild,
) {
const {
value,
map,
} = parent;
targetGroups.forEach(child => {
if ("groupId" in child) {
const group = new GroupArrayChild(parent);

group.id = child.groupId;
group.depth = parent.depth + 1;
value.push(group);

createGroupChildren(child.children, group);
} else if (isArray(child)) {
const group = new GroupArrayChild(parent);

group.depth = parent.depth + 1;
value.push(group);

createGroupChildren(child, group);
} else {
const element = "current" in child ? child.current : child;
const single = new GroupSingleChild(parent, element!);

single.depth = parent.depth + 1;
value.push(single);
map.set(element!, single);
}
});

value.forEach(child => {
if (child.type === "single") {
map.set(child.value, child);
} else {
child.map.forEach((nextChild, element) => {
map.set(element, nextChild);
});
}
});
return parent;
}

export function toTargetList(raw: GroupChild[]): TargetList {
function targets(childs: GroupChild[] = []) {
const arr: TargetGroupsType = [];
Expand Down Expand Up @@ -78,6 +32,8 @@ export function toTargetList(raw: GroupChild[]): TargetList {

export class GroupManager extends GroupArrayChild {
public type = "root" as const;
private _targets: Array<HTMLElement | SVGElement> = [];

constructor(
targetGroups: TargetGroupsType,
targets?: Array<HTMLElement | SVGElement>,
Expand All @@ -95,8 +51,7 @@ export class GroupManager extends GroupArrayChild {
const map = this.map;
const value = this.value;

createGroupChildren(targetGroups, this);

this.add(targetGroups);
targets.forEach(target => {
if (map.has(target)) {
return;
Expand All @@ -107,6 +62,7 @@ export class GroupManager extends GroupArrayChild {
value.push(single);
map.set(target, single);
});
this._targets = targets;
}
public selectSubChilds(targets: TargetGroupsType, target: HTMLElement | SVGElement) {
const root = this;
Expand Down Expand Up @@ -300,6 +256,62 @@ export class GroupManager extends GroupArrayChild {

return value;
}
public group(targets: TargetGroupsType, flatten?: boolean): TargetGroupsType | null {
const commonParent = this.findCommonParent(targets);
const groupChilds = targets.map(target => {
if (isArray(target)) {
return this.findArrayChild(target);
}
return this.toSingleChild(target);
});
const isGroupable = groupChilds.every(child => child?.parent === commonParent);

if (!isGroupable) {
return null;
}
const group = new GroupArrayChild(commonParent);
const nextChilds = commonParent.value.filter(target => groupChilds.indexOf(target) === -1);

nextChilds.unshift(group);

group.add(flatten ? deepFlat(targets) : targets);
commonParent.value = nextChilds;

this.set(this.toTargetGroups(), this._targets);

return group.toTargetGroups();
}
public ungroup(targets: TargetGroupsType) {
if (targets.length === 1 && isArray(targets[0])) {
targets = targets[0];
}
const commonParent = this.findCommonParent(targets);
const groupChilds = targets.map(target => {
if (isArray(target)) {
return this.findArrayChild(target);
}
return this.toSingleChild(target);
});
const isGroupable = commonParent.value.every(child => groupChilds.indexOf(child) > -1);

if (!isGroupable || commonParent === this) {
// has no group
return null;
}

const parent = commonParent.parent;

if (!parent) {
return null;
}
const nextChilds = parent.value.filter(target => target !== commonParent);

nextChilds.push(...commonParent.value);
parent.value = nextChilds;

this.set(this.toTargetGroups(), this._targets);
return commonParent.toTargetGroups();
}
protected _findParentGroup(
element: HTMLElement | SVGElement,
range: Array<HTMLElement | SVGElement>,
Expand Down
52 changes: 50 additions & 2 deletions packages/helper/src/groups.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { isArray, deepFlat, find } from "@daybrush/utils";
import { GroupChild, TargetGroupsType } from "./types";
import { GroupChild, TargetGroupsObject, TargetGroupsType } from "./types";

export class Child {
public type: "group" | "root" | "single" = "single";
public depth = 0;
protected _scope: string[] = [];
constructor(public parent?: GroupArrayChild) {}
constructor(public parent?: GroupArrayChild) {
if (parent) {
this.depth = parent.depth + 1;
}
}

public get scope(): string[] {
const parent = this.parent;
Expand Down Expand Up @@ -285,4 +289,48 @@ export class GroupArrayChild extends Child {
return selected.indexOf(child.value) > -1;
});
}
public add(targets: TargetGroupsObject) {
const {
value,
map,
} = this;
const depth = this.depth;

targets.forEach(child => {
if ("groupId" in child) {
const group = new GroupArrayChild(this);

group.id = child.groupId;
group.depth = depth + 1;
value.push(group);

group.add(child.children);
} else if (isArray(child)) {
const group = new GroupArrayChild(this);

group.depth = depth + 1;
value.push(group);

group.add(child);
} else {
const element = "current" in child ? child.current : child;
const single = new GroupSingleChild(this, element!);

single.depth = depth + 1;
value.push(single);
map.set(element!, single);
}
});

value.forEach(child => {
if (child.type === "single") {
map.set(child.value, child);
} else {
child.map.forEach((nextChild, element) => {
map.set(element, nextChild);
});
}
});
return parent;
}
}

0 comments on commit 8434ed1

Please sign in to comment.