@knotx/plugins-selection 0.2.15 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +147 -84
- package/dist/index.d.cts +64 -12
- package/dist/index.d.mts +64 -12
- package/dist/index.d.ts +64 -12
- package/dist/index.js +148 -85
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -10,9 +10,7 @@ const SelectionArea__default = /*#__PURE__*/_interopDefaultCompat(SelectionArea)
|
|
|
10
10
|
|
|
11
11
|
var __create = Object.create;
|
|
12
12
|
var __defProp = Object.defineProperty;
|
|
13
|
-
var __defProps = Object.defineProperties;
|
|
14
13
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
15
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
16
14
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
17
15
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
18
16
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -32,7 +30,6 @@ var __spreadValues = (a, b) => {
|
|
|
32
30
|
}
|
|
33
31
|
return a;
|
|
34
32
|
};
|
|
35
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
36
33
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
37
34
|
var __decoratorStart = (base) => {
|
|
38
35
|
var _a2;
|
|
@@ -76,120 +73,186 @@ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use
|
|
|
76
73
|
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
77
74
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
78
75
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
79
|
-
var _destroy_dec, _clearSelection_dec,
|
|
80
|
-
class Selection extends (_a = core.BasePlugin,
|
|
76
|
+
var _destroy_dec, _clearSelection_dec, _getSelected_dec, _init_dec, _canInteract_dec, _endInteraction_dec, _startInteraction_dec, _registerRules_dec, _selected_dec, _a, _init;
|
|
77
|
+
class Selection extends (_a = core.BasePlugin, _selected_dec = [decorators.register("selected")], _registerRules_dec = [decorators.register("registerRules")], _startInteraction_dec = [decorators.inject.startInteraction()], _endInteraction_dec = [decorators.inject.endInteraction()], _canInteract_dec = [decorators.inject.canInteract()], _init_dec = [decorators.OnInit], _getSelected_dec = [decorators.tool("Get selected items", {})], _clearSelection_dec = [decorators.tool("Clear selection", {})], _destroy_dec = [decorators.OnDestroy], _a) {
|
|
81
78
|
constructor() {
|
|
82
79
|
super(...arguments);
|
|
83
80
|
__runInitializers(_init, 5, this);
|
|
84
81
|
__publicField(this, "name", "selection");
|
|
85
|
-
__publicField(this, "config");
|
|
86
82
|
__publicField(this, "selection");
|
|
87
|
-
__publicField(this, "
|
|
88
|
-
__publicField(this, "
|
|
83
|
+
__publicField(this, "container", "body");
|
|
84
|
+
__publicField(this, "selectionAreaClassName");
|
|
85
|
+
__publicField(this, "ruleMap", /* @__PURE__ */ new Map());
|
|
86
|
+
__publicField(this, "enableDrag", true);
|
|
87
|
+
__publicField(this, "isDragging", false);
|
|
88
|
+
__publicField(this, "updateFrameId");
|
|
89
|
+
__publicField(this, "selected", __runInitializers(_init, 8, this, [])), __runInitializers(_init, 11, this);
|
|
90
|
+
__publicField(this, "registerRules", __runInitializers(_init, 12, this, (rules) => {
|
|
91
|
+
rules.forEach((rule) => {
|
|
92
|
+
this.ruleMap.set(rule.className, rule);
|
|
93
|
+
});
|
|
94
|
+
return () => {
|
|
95
|
+
rules.forEach((rule) => {
|
|
96
|
+
if (this.ruleMap.get(rule.className) === rule) {
|
|
97
|
+
this.ruleMap.delete(rule.className);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
})), __runInitializers(_init, 15, this);
|
|
89
102
|
__publicField(this, "startInteraction", __runInitializers(_init, 16, this)), __runInitializers(_init, 19, this);
|
|
90
103
|
__publicField(this, "endInteraction", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);
|
|
91
104
|
__publicField(this, "canInteract", __runInitializers(_init, 24, this)), __runInitializers(_init, 27, this);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const nodeClassName = core.addBemModifier(nodeWrapperClassName, "selected");
|
|
102
|
-
const selectionAreaClass = core.bem("selection-area");
|
|
103
|
-
const selectables = [`.${nodeWrapperClassName}`];
|
|
104
|
-
const endSelect = () => {
|
|
105
|
-
this.endInteraction(this.pluginId, "select");
|
|
106
|
-
this.selectStatus = "stop";
|
|
107
|
-
};
|
|
108
|
-
this.selection = new SelectionArea__default(__spreadProps(__spreadValues({}, this.config), { selectionAreaClass, selectables })).on("start", ({ store, event, selection }) => {
|
|
105
|
+
__publicField(this, "onBeforeStart", (_) => {
|
|
106
|
+
});
|
|
107
|
+
__publicField(this, "onBeforeDrag", () => {
|
|
108
|
+
this.isDragging = this.enableDrag;
|
|
109
|
+
return this.enableDrag && this.canInteract(this.pluginId, "select", core.InteractionPriority.MarqueeSelection);
|
|
110
|
+
});
|
|
111
|
+
__publicField(this, "onStart", ({ event, store }) => {
|
|
112
|
+
var _a2;
|
|
113
|
+
this.startInteraction(this.pluginId, "select", core.InteractionPriority.MarqueeSelection);
|
|
109
114
|
if (!(event == null ? void 0 : event.ctrlKey) && !(event == null ? void 0 : event.metaKey) && !(event == null ? void 0 : event.shiftKey)) {
|
|
110
|
-
store.stored.forEach((
|
|
111
|
-
|
|
112
|
-
|
|
115
|
+
store.stored.forEach((element) => {
|
|
116
|
+
const rule = this.getElementRule(element);
|
|
117
|
+
if (rule == null ? void 0 : rule.activeClassName) {
|
|
118
|
+
element.classList.remove(rule.activeClassName);
|
|
113
119
|
}
|
|
114
120
|
});
|
|
115
|
-
selection.clearSelection();
|
|
116
|
-
this.selectedNodeIds = [];
|
|
121
|
+
(_a2 = this.selection) == null ? void 0 : _a2.clearSelection(true, true);
|
|
117
122
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
123
|
+
});
|
|
124
|
+
__publicField(this, "onMove", ({ store: { stored, changed: { added, removed } }, selection }) => {
|
|
125
|
+
const getSelectedElements = () => {
|
|
126
|
+
return stored.reduce((dict, item) => {
|
|
127
|
+
const rule = this.getElementRule(item);
|
|
128
|
+
if (rule) {
|
|
129
|
+
dict[rule.type] = [...dict[rule.type] || [], { id: rule.idGetter(item), element: item }];
|
|
130
|
+
}
|
|
131
|
+
return dict;
|
|
132
|
+
}, {});
|
|
133
|
+
};
|
|
134
|
+
const context = {
|
|
135
|
+
isDragging: this.isDragging,
|
|
136
|
+
getSelectedElements,
|
|
137
|
+
select: (elements) => {
|
|
138
|
+
elements.forEach((element) => {
|
|
139
|
+
selection.select(element);
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
deselect: (elements) => {
|
|
143
|
+
elements.forEach((element) => {
|
|
144
|
+
selection.deselect(element);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
removed.forEach((element) => {
|
|
149
|
+
const rule = this.getElementRule(element);
|
|
150
|
+
if (!rule) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (rule.activeClassName) {
|
|
154
|
+
element.classList.remove(rule.activeClassName);
|
|
136
155
|
}
|
|
137
156
|
});
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
157
|
+
added.forEach((element) => {
|
|
158
|
+
const rule = this.getElementRule(element);
|
|
159
|
+
if (!rule) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const type = rule.type;
|
|
163
|
+
const id = rule.idGetter(element);
|
|
164
|
+
for (const [, rule2] of this.ruleMap) {
|
|
165
|
+
if (rule2.onSelected) {
|
|
166
|
+
if (!rule2.onSelected(__spreadValues({ element, type, id }, context))) {
|
|
167
|
+
selection.deselect(element, true);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (rule.activeClassName) {
|
|
173
|
+
element.classList.add(rule.activeClassName);
|
|
145
174
|
}
|
|
146
175
|
});
|
|
147
|
-
|
|
148
|
-
|
|
176
|
+
});
|
|
177
|
+
__publicField(this, "onStop", ({ event }) => {
|
|
178
|
+
this.endInteraction(this.pluginId, "select");
|
|
149
179
|
if (event) {
|
|
150
|
-
|
|
180
|
+
if (this.isDragging) {
|
|
181
|
+
this.isDragging = false;
|
|
182
|
+
}
|
|
151
183
|
}
|
|
184
|
+
cancelAnimationFrame(this.updateFrameId);
|
|
185
|
+
this.updateFrameId = requestAnimationFrame(this.updateSelection);
|
|
186
|
+
});
|
|
187
|
+
__publicField(this, "updateSelection", () => {
|
|
188
|
+
var _a2;
|
|
189
|
+
const selected = [];
|
|
190
|
+
for (const element of ((_a2 = this.selection) == null ? void 0 : _a2.getSelection()) || []) {
|
|
191
|
+
const rule = this.getElementRule(element);
|
|
192
|
+
if (rule) {
|
|
193
|
+
selected.push({ type: rule.type, id: rule.idGetter(element) });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
this.selected = selected;
|
|
152
197
|
});
|
|
153
198
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
199
|
+
init(config = {}) {
|
|
200
|
+
this.container = config.container || core.bemSelector("canvas", "wrapper");
|
|
201
|
+
this.selectionAreaClassName = config.selectionAreaClassName || core.bem("selection-area");
|
|
202
|
+
if (!config.disableDefaultRules) {
|
|
203
|
+
const nodeRule = {
|
|
204
|
+
type: "node",
|
|
205
|
+
className: core.bem("node", "wrapper"),
|
|
206
|
+
activeClassName: core.bem("node", "wrapper", "selected"),
|
|
207
|
+
idGetter: (element) => element.getAttribute("data-node-id") || ""
|
|
208
|
+
};
|
|
209
|
+
this.ruleMap.set(nodeRule.className, nodeRule);
|
|
210
|
+
}
|
|
211
|
+
for (const rule of config.rules || []) {
|
|
212
|
+
this.ruleMap.set(rule.className, rule);
|
|
213
|
+
}
|
|
214
|
+
if (config.enableDrag !== void 0) {
|
|
215
|
+
this.enableDrag = config.enableDrag;
|
|
216
|
+
}
|
|
217
|
+
queueMicrotask(() => this.createSelection());
|
|
165
218
|
}
|
|
166
|
-
|
|
167
|
-
|
|
219
|
+
createSelection() {
|
|
220
|
+
const container = this.container;
|
|
221
|
+
this.selection = new SelectionArea__default({
|
|
222
|
+
// container,
|
|
223
|
+
boundaries: [container],
|
|
224
|
+
selectionAreaClass: this.selectionAreaClassName,
|
|
225
|
+
selectables: Array.from(this.ruleMap.keys()).map((className) => `.${className}`)
|
|
226
|
+
}).on("beforedrag", this.onBeforeDrag).on("beforestart", this.onBeforeStart).on("start", this.onStart).on("move", this.onMove).on("stop", this.onStop);
|
|
168
227
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const currentNodeIds = this.selectedNodeIds;
|
|
175
|
-
this.selectedNodeIds = [
|
|
176
|
-
...currentNodeIds,
|
|
177
|
-
...nodeIds.filter((id) => !currentNodeIds.includes(id))
|
|
178
|
-
];
|
|
228
|
+
getElementRule(element) {
|
|
229
|
+
for (const [className, rule] of this.ruleMap) {
|
|
230
|
+
if (element.classList.contains(className)) {
|
|
231
|
+
return rule;
|
|
232
|
+
}
|
|
179
233
|
}
|
|
234
|
+
return void 0;
|
|
235
|
+
}
|
|
236
|
+
getSelected() {
|
|
237
|
+
return this.selected;
|
|
238
|
+
}
|
|
239
|
+
clearSelection() {
|
|
240
|
+
var _a2;
|
|
241
|
+
(_a2 = this.selection) == null ? void 0 : _a2.clearSelection(true, false);
|
|
180
242
|
}
|
|
181
243
|
destroy() {
|
|
182
244
|
var _a2;
|
|
183
245
|
(_a2 = this.selection) == null ? void 0 : _a2.destroy();
|
|
246
|
+
this.ruleMap.clear();
|
|
184
247
|
}
|
|
185
248
|
}
|
|
186
249
|
_init = __decoratorStart(_a);
|
|
187
250
|
__decorateElement(_init, 1, "init", _init_dec, Selection);
|
|
188
|
-
__decorateElement(_init, 1, "
|
|
251
|
+
__decorateElement(_init, 1, "getSelected", _getSelected_dec, Selection);
|
|
189
252
|
__decorateElement(_init, 1, "clearSelection", _clearSelection_dec, Selection);
|
|
190
253
|
__decorateElement(_init, 1, "destroy", _destroy_dec, Selection);
|
|
191
|
-
__decorateElement(_init, 5, "
|
|
192
|
-
__decorateElement(_init, 5, "
|
|
254
|
+
__decorateElement(_init, 5, "selected", _selected_dec, Selection);
|
|
255
|
+
__decorateElement(_init, 5, "registerRules", _registerRules_dec, Selection);
|
|
193
256
|
__decorateElement(_init, 5, "startInteraction", _startInteraction_dec, Selection);
|
|
194
257
|
__decorateElement(_init, 5, "endInteraction", _endInteraction_dec, Selection);
|
|
195
258
|
__decorateElement(_init, 5, "canInteract", _canInteract_dec, Selection);
|
package/dist/index.d.cts
CHANGED
|
@@ -1,38 +1,90 @@
|
|
|
1
|
-
import { PartialSelectionOptions } from '@viselect/vanilla';
|
|
2
1
|
import { BasePlugin } from '@knotx/core';
|
|
3
2
|
|
|
3
|
+
interface SelectionSelectedItem {
|
|
4
|
+
type: string;
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
4
7
|
declare module '@knotx/core' {
|
|
5
8
|
interface PluginData {
|
|
6
9
|
selection: {
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
selected: SelectionSelectedItem[];
|
|
11
|
+
registerRules: (rules: SelectionRule[]) => () => void;
|
|
9
12
|
};
|
|
10
13
|
}
|
|
11
14
|
interface PluginTools {
|
|
12
15
|
selection: {
|
|
13
|
-
|
|
16
|
+
getSelected: () => SelectionSelectedItem[];
|
|
14
17
|
clearSelection: () => void;
|
|
15
18
|
};
|
|
16
19
|
}
|
|
17
20
|
}
|
|
18
|
-
interface
|
|
21
|
+
interface SelectionRule {
|
|
22
|
+
/**
|
|
23
|
+
* resource type
|
|
24
|
+
*/
|
|
25
|
+
type: string;
|
|
26
|
+
className: string;
|
|
27
|
+
idGetter: (element: Element) => string;
|
|
28
|
+
/**
|
|
29
|
+
* default: null
|
|
30
|
+
*/
|
|
31
|
+
activeClassName?: string;
|
|
32
|
+
onSelected?: (context: {
|
|
33
|
+
element: Element;
|
|
34
|
+
type: string;
|
|
35
|
+
id: string;
|
|
36
|
+
isDragging: boolean;
|
|
37
|
+
getSelectedElements: () => Record<string, {
|
|
38
|
+
id: string;
|
|
39
|
+
element: Element;
|
|
40
|
+
}[]>;
|
|
41
|
+
select: (elements: Element[]) => void;
|
|
42
|
+
deselect: (elements: Element[]) => void;
|
|
43
|
+
}) => boolean;
|
|
44
|
+
}
|
|
45
|
+
interface SelectionConfig {
|
|
46
|
+
selectionAreaClassName?: string;
|
|
47
|
+
/**
|
|
48
|
+
* default: true
|
|
49
|
+
*/
|
|
50
|
+
enableDrag?: boolean;
|
|
51
|
+
rules?: SelectionRule[];
|
|
52
|
+
/**
|
|
53
|
+
* default:
|
|
54
|
+
* [{type: 'node', className: bem('node', 'wrapper'), activeClassName: bem('node', 'wrapper', 'selected') }]
|
|
55
|
+
*/
|
|
56
|
+
disableDefaultRules?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* default: bemSelector('canvas', 'wrapper')
|
|
59
|
+
*/
|
|
60
|
+
container?: string;
|
|
19
61
|
}
|
|
20
62
|
declare class Selection extends BasePlugin<'selection', SelectionConfig> {
|
|
21
63
|
name: "selection";
|
|
22
|
-
private config;
|
|
23
64
|
private selection;
|
|
24
|
-
|
|
25
|
-
|
|
65
|
+
private container;
|
|
66
|
+
private selectionAreaClassName;
|
|
67
|
+
private ruleMap;
|
|
68
|
+
private enableDrag;
|
|
69
|
+
private isDragging;
|
|
70
|
+
private updateFrameId;
|
|
71
|
+
selected: SelectionSelectedItem[];
|
|
72
|
+
registerRules: (rules: SelectionRule[]) => () => void;
|
|
26
73
|
private startInteraction;
|
|
27
74
|
private endInteraction;
|
|
28
75
|
private canInteract;
|
|
29
|
-
init(config
|
|
76
|
+
init(config?: SelectionConfig): void;
|
|
30
77
|
private createSelection;
|
|
78
|
+
private onBeforeStart;
|
|
79
|
+
private onBeforeDrag;
|
|
80
|
+
private onStart;
|
|
81
|
+
private onMove;
|
|
82
|
+
private onStop;
|
|
83
|
+
private getElementRule;
|
|
31
84
|
private updateSelection;
|
|
32
|
-
|
|
85
|
+
getSelected(): SelectionSelectedItem[];
|
|
33
86
|
clearSelection(): void;
|
|
34
|
-
selectNodes(nodeIds: string[], clearPrevious?: boolean): void;
|
|
35
87
|
destroy(): void;
|
|
36
88
|
}
|
|
37
89
|
|
|
38
|
-
export { Selection, type SelectionConfig };
|
|
90
|
+
export { Selection, type SelectionConfig, type SelectionRule, type SelectionSelectedItem };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,38 +1,90 @@
|
|
|
1
|
-
import { PartialSelectionOptions } from '@viselect/vanilla';
|
|
2
1
|
import { BasePlugin } from '@knotx/core';
|
|
3
2
|
|
|
3
|
+
interface SelectionSelectedItem {
|
|
4
|
+
type: string;
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
4
7
|
declare module '@knotx/core' {
|
|
5
8
|
interface PluginData {
|
|
6
9
|
selection: {
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
selected: SelectionSelectedItem[];
|
|
11
|
+
registerRules: (rules: SelectionRule[]) => () => void;
|
|
9
12
|
};
|
|
10
13
|
}
|
|
11
14
|
interface PluginTools {
|
|
12
15
|
selection: {
|
|
13
|
-
|
|
16
|
+
getSelected: () => SelectionSelectedItem[];
|
|
14
17
|
clearSelection: () => void;
|
|
15
18
|
};
|
|
16
19
|
}
|
|
17
20
|
}
|
|
18
|
-
interface
|
|
21
|
+
interface SelectionRule {
|
|
22
|
+
/**
|
|
23
|
+
* resource type
|
|
24
|
+
*/
|
|
25
|
+
type: string;
|
|
26
|
+
className: string;
|
|
27
|
+
idGetter: (element: Element) => string;
|
|
28
|
+
/**
|
|
29
|
+
* default: null
|
|
30
|
+
*/
|
|
31
|
+
activeClassName?: string;
|
|
32
|
+
onSelected?: (context: {
|
|
33
|
+
element: Element;
|
|
34
|
+
type: string;
|
|
35
|
+
id: string;
|
|
36
|
+
isDragging: boolean;
|
|
37
|
+
getSelectedElements: () => Record<string, {
|
|
38
|
+
id: string;
|
|
39
|
+
element: Element;
|
|
40
|
+
}[]>;
|
|
41
|
+
select: (elements: Element[]) => void;
|
|
42
|
+
deselect: (elements: Element[]) => void;
|
|
43
|
+
}) => boolean;
|
|
44
|
+
}
|
|
45
|
+
interface SelectionConfig {
|
|
46
|
+
selectionAreaClassName?: string;
|
|
47
|
+
/**
|
|
48
|
+
* default: true
|
|
49
|
+
*/
|
|
50
|
+
enableDrag?: boolean;
|
|
51
|
+
rules?: SelectionRule[];
|
|
52
|
+
/**
|
|
53
|
+
* default:
|
|
54
|
+
* [{type: 'node', className: bem('node', 'wrapper'), activeClassName: bem('node', 'wrapper', 'selected') }]
|
|
55
|
+
*/
|
|
56
|
+
disableDefaultRules?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* default: bemSelector('canvas', 'wrapper')
|
|
59
|
+
*/
|
|
60
|
+
container?: string;
|
|
19
61
|
}
|
|
20
62
|
declare class Selection extends BasePlugin<'selection', SelectionConfig> {
|
|
21
63
|
name: "selection";
|
|
22
|
-
private config;
|
|
23
64
|
private selection;
|
|
24
|
-
|
|
25
|
-
|
|
65
|
+
private container;
|
|
66
|
+
private selectionAreaClassName;
|
|
67
|
+
private ruleMap;
|
|
68
|
+
private enableDrag;
|
|
69
|
+
private isDragging;
|
|
70
|
+
private updateFrameId;
|
|
71
|
+
selected: SelectionSelectedItem[];
|
|
72
|
+
registerRules: (rules: SelectionRule[]) => () => void;
|
|
26
73
|
private startInteraction;
|
|
27
74
|
private endInteraction;
|
|
28
75
|
private canInteract;
|
|
29
|
-
init(config
|
|
76
|
+
init(config?: SelectionConfig): void;
|
|
30
77
|
private createSelection;
|
|
78
|
+
private onBeforeStart;
|
|
79
|
+
private onBeforeDrag;
|
|
80
|
+
private onStart;
|
|
81
|
+
private onMove;
|
|
82
|
+
private onStop;
|
|
83
|
+
private getElementRule;
|
|
31
84
|
private updateSelection;
|
|
32
|
-
|
|
85
|
+
getSelected(): SelectionSelectedItem[];
|
|
33
86
|
clearSelection(): void;
|
|
34
|
-
selectNodes(nodeIds: string[], clearPrevious?: boolean): void;
|
|
35
87
|
destroy(): void;
|
|
36
88
|
}
|
|
37
89
|
|
|
38
|
-
export { Selection, type SelectionConfig };
|
|
90
|
+
export { Selection, type SelectionConfig, type SelectionRule, type SelectionSelectedItem };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,38 +1,90 @@
|
|
|
1
|
-
import { PartialSelectionOptions } from '@viselect/vanilla';
|
|
2
1
|
import { BasePlugin } from '@knotx/core';
|
|
3
2
|
|
|
3
|
+
interface SelectionSelectedItem {
|
|
4
|
+
type: string;
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
4
7
|
declare module '@knotx/core' {
|
|
5
8
|
interface PluginData {
|
|
6
9
|
selection: {
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
selected: SelectionSelectedItem[];
|
|
11
|
+
registerRules: (rules: SelectionRule[]) => () => void;
|
|
9
12
|
};
|
|
10
13
|
}
|
|
11
14
|
interface PluginTools {
|
|
12
15
|
selection: {
|
|
13
|
-
|
|
16
|
+
getSelected: () => SelectionSelectedItem[];
|
|
14
17
|
clearSelection: () => void;
|
|
15
18
|
};
|
|
16
19
|
}
|
|
17
20
|
}
|
|
18
|
-
interface
|
|
21
|
+
interface SelectionRule {
|
|
22
|
+
/**
|
|
23
|
+
* resource type
|
|
24
|
+
*/
|
|
25
|
+
type: string;
|
|
26
|
+
className: string;
|
|
27
|
+
idGetter: (element: Element) => string;
|
|
28
|
+
/**
|
|
29
|
+
* default: null
|
|
30
|
+
*/
|
|
31
|
+
activeClassName?: string;
|
|
32
|
+
onSelected?: (context: {
|
|
33
|
+
element: Element;
|
|
34
|
+
type: string;
|
|
35
|
+
id: string;
|
|
36
|
+
isDragging: boolean;
|
|
37
|
+
getSelectedElements: () => Record<string, {
|
|
38
|
+
id: string;
|
|
39
|
+
element: Element;
|
|
40
|
+
}[]>;
|
|
41
|
+
select: (elements: Element[]) => void;
|
|
42
|
+
deselect: (elements: Element[]) => void;
|
|
43
|
+
}) => boolean;
|
|
44
|
+
}
|
|
45
|
+
interface SelectionConfig {
|
|
46
|
+
selectionAreaClassName?: string;
|
|
47
|
+
/**
|
|
48
|
+
* default: true
|
|
49
|
+
*/
|
|
50
|
+
enableDrag?: boolean;
|
|
51
|
+
rules?: SelectionRule[];
|
|
52
|
+
/**
|
|
53
|
+
* default:
|
|
54
|
+
* [{type: 'node', className: bem('node', 'wrapper'), activeClassName: bem('node', 'wrapper', 'selected') }]
|
|
55
|
+
*/
|
|
56
|
+
disableDefaultRules?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* default: bemSelector('canvas', 'wrapper')
|
|
59
|
+
*/
|
|
60
|
+
container?: string;
|
|
19
61
|
}
|
|
20
62
|
declare class Selection extends BasePlugin<'selection', SelectionConfig> {
|
|
21
63
|
name: "selection";
|
|
22
|
-
private config;
|
|
23
64
|
private selection;
|
|
24
|
-
|
|
25
|
-
|
|
65
|
+
private container;
|
|
66
|
+
private selectionAreaClassName;
|
|
67
|
+
private ruleMap;
|
|
68
|
+
private enableDrag;
|
|
69
|
+
private isDragging;
|
|
70
|
+
private updateFrameId;
|
|
71
|
+
selected: SelectionSelectedItem[];
|
|
72
|
+
registerRules: (rules: SelectionRule[]) => () => void;
|
|
26
73
|
private startInteraction;
|
|
27
74
|
private endInteraction;
|
|
28
75
|
private canInteract;
|
|
29
|
-
init(config
|
|
76
|
+
init(config?: SelectionConfig): void;
|
|
30
77
|
private createSelection;
|
|
78
|
+
private onBeforeStart;
|
|
79
|
+
private onBeforeDrag;
|
|
80
|
+
private onStart;
|
|
81
|
+
private onMove;
|
|
82
|
+
private onStop;
|
|
83
|
+
private getElementRule;
|
|
31
84
|
private updateSelection;
|
|
32
|
-
|
|
85
|
+
getSelected(): SelectionSelectedItem[];
|
|
33
86
|
clearSelection(): void;
|
|
34
|
-
selectNodes(nodeIds: string[], clearPrevious?: boolean): void;
|
|
35
87
|
destroy(): void;
|
|
36
88
|
}
|
|
37
89
|
|
|
38
|
-
export { Selection, type SelectionConfig };
|
|
90
|
+
export { Selection, type SelectionConfig, type SelectionRule, type SelectionSelectedItem };
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { bem,
|
|
1
|
+
import { bemSelector, bem, BasePlugin, InteractionPriority } from '@knotx/core';
|
|
2
2
|
import { register, inject, tool, OnInit, OnDestroy } from '@knotx/decorators';
|
|
3
3
|
import SelectionArea from '@viselect/vanilla';
|
|
4
4
|
|
|
5
5
|
var __create = Object.create;
|
|
6
6
|
var __defProp = Object.defineProperty;
|
|
7
|
-
var __defProps = Object.defineProperties;
|
|
8
7
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
10
8
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
11
9
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
10
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -26,7 +24,6 @@ var __spreadValues = (a, b) => {
|
|
|
26
24
|
}
|
|
27
25
|
return a;
|
|
28
26
|
};
|
|
29
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
30
27
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
31
28
|
var __decoratorStart = (base) => {
|
|
32
29
|
var _a2;
|
|
@@ -70,120 +67,186 @@ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use
|
|
|
70
67
|
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
71
68
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
72
69
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
73
|
-
var _destroy_dec, _clearSelection_dec,
|
|
74
|
-
class Selection extends (_a = BasePlugin,
|
|
70
|
+
var _destroy_dec, _clearSelection_dec, _getSelected_dec, _init_dec, _canInteract_dec, _endInteraction_dec, _startInteraction_dec, _registerRules_dec, _selected_dec, _a, _init;
|
|
71
|
+
class Selection extends (_a = BasePlugin, _selected_dec = [register("selected")], _registerRules_dec = [register("registerRules")], _startInteraction_dec = [inject.startInteraction()], _endInteraction_dec = [inject.endInteraction()], _canInteract_dec = [inject.canInteract()], _init_dec = [OnInit], _getSelected_dec = [tool("Get selected items", {})], _clearSelection_dec = [tool("Clear selection", {})], _destroy_dec = [OnDestroy], _a) {
|
|
75
72
|
constructor() {
|
|
76
73
|
super(...arguments);
|
|
77
74
|
__runInitializers(_init, 5, this);
|
|
78
75
|
__publicField(this, "name", "selection");
|
|
79
|
-
__publicField(this, "config");
|
|
80
76
|
__publicField(this, "selection");
|
|
81
|
-
__publicField(this, "
|
|
82
|
-
__publicField(this, "
|
|
77
|
+
__publicField(this, "container", "body");
|
|
78
|
+
__publicField(this, "selectionAreaClassName");
|
|
79
|
+
__publicField(this, "ruleMap", /* @__PURE__ */ new Map());
|
|
80
|
+
__publicField(this, "enableDrag", true);
|
|
81
|
+
__publicField(this, "isDragging", false);
|
|
82
|
+
__publicField(this, "updateFrameId");
|
|
83
|
+
__publicField(this, "selected", __runInitializers(_init, 8, this, [])), __runInitializers(_init, 11, this);
|
|
84
|
+
__publicField(this, "registerRules", __runInitializers(_init, 12, this, (rules) => {
|
|
85
|
+
rules.forEach((rule) => {
|
|
86
|
+
this.ruleMap.set(rule.className, rule);
|
|
87
|
+
});
|
|
88
|
+
return () => {
|
|
89
|
+
rules.forEach((rule) => {
|
|
90
|
+
if (this.ruleMap.get(rule.className) === rule) {
|
|
91
|
+
this.ruleMap.delete(rule.className);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
})), __runInitializers(_init, 15, this);
|
|
83
96
|
__publicField(this, "startInteraction", __runInitializers(_init, 16, this)), __runInitializers(_init, 19, this);
|
|
84
97
|
__publicField(this, "endInteraction", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);
|
|
85
98
|
__publicField(this, "canInteract", __runInitializers(_init, 24, this)), __runInitializers(_init, 27, this);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
this
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const nodeClassName = addBemModifier(nodeWrapperClassName, "selected");
|
|
96
|
-
const selectionAreaClass = bem("selection-area");
|
|
97
|
-
const selectables = [`.${nodeWrapperClassName}`];
|
|
98
|
-
const endSelect = () => {
|
|
99
|
-
this.endInteraction(this.pluginId, "select");
|
|
100
|
-
this.selectStatus = "stop";
|
|
101
|
-
};
|
|
102
|
-
this.selection = new SelectionArea(__spreadProps(__spreadValues({}, this.config), { selectionAreaClass, selectables })).on("start", ({ store, event, selection }) => {
|
|
99
|
+
__publicField(this, "onBeforeStart", (_) => {
|
|
100
|
+
});
|
|
101
|
+
__publicField(this, "onBeforeDrag", () => {
|
|
102
|
+
this.isDragging = this.enableDrag;
|
|
103
|
+
return this.enableDrag && this.canInteract(this.pluginId, "select", InteractionPriority.MarqueeSelection);
|
|
104
|
+
});
|
|
105
|
+
__publicField(this, "onStart", ({ event, store }) => {
|
|
106
|
+
var _a2;
|
|
107
|
+
this.startInteraction(this.pluginId, "select", InteractionPriority.MarqueeSelection);
|
|
103
108
|
if (!(event == null ? void 0 : event.ctrlKey) && !(event == null ? void 0 : event.metaKey) && !(event == null ? void 0 : event.shiftKey)) {
|
|
104
|
-
store.stored.forEach((
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
store.stored.forEach((element) => {
|
|
110
|
+
const rule = this.getElementRule(element);
|
|
111
|
+
if (rule == null ? void 0 : rule.activeClassName) {
|
|
112
|
+
element.classList.remove(rule.activeClassName);
|
|
107
113
|
}
|
|
108
114
|
});
|
|
109
|
-
selection.clearSelection();
|
|
110
|
-
this.selectedNodeIds = [];
|
|
115
|
+
(_a2 = this.selection) == null ? void 0 : _a2.clearSelection(true, true);
|
|
111
116
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
117
|
+
});
|
|
118
|
+
__publicField(this, "onMove", ({ store: { stored, changed: { added, removed } }, selection }) => {
|
|
119
|
+
const getSelectedElements = () => {
|
|
120
|
+
return stored.reduce((dict, item) => {
|
|
121
|
+
const rule = this.getElementRule(item);
|
|
122
|
+
if (rule) {
|
|
123
|
+
dict[rule.type] = [...dict[rule.type] || [], { id: rule.idGetter(item), element: item }];
|
|
124
|
+
}
|
|
125
|
+
return dict;
|
|
126
|
+
}, {});
|
|
127
|
+
};
|
|
128
|
+
const context = {
|
|
129
|
+
isDragging: this.isDragging,
|
|
130
|
+
getSelectedElements,
|
|
131
|
+
select: (elements) => {
|
|
132
|
+
elements.forEach((element) => {
|
|
133
|
+
selection.select(element);
|
|
134
|
+
});
|
|
135
|
+
},
|
|
136
|
+
deselect: (elements) => {
|
|
137
|
+
elements.forEach((element) => {
|
|
138
|
+
selection.deselect(element);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
removed.forEach((element) => {
|
|
143
|
+
const rule = this.getElementRule(element);
|
|
144
|
+
if (!rule) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (rule.activeClassName) {
|
|
148
|
+
element.classList.remove(rule.activeClassName);
|
|
130
149
|
}
|
|
131
150
|
});
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
151
|
+
added.forEach((element) => {
|
|
152
|
+
const rule = this.getElementRule(element);
|
|
153
|
+
if (!rule) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const type = rule.type;
|
|
157
|
+
const id = rule.idGetter(element);
|
|
158
|
+
for (const [, rule2] of this.ruleMap) {
|
|
159
|
+
if (rule2.onSelected) {
|
|
160
|
+
if (!rule2.onSelected(__spreadValues({ element, type, id }, context))) {
|
|
161
|
+
selection.deselect(element, true);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (rule.activeClassName) {
|
|
167
|
+
element.classList.add(rule.activeClassName);
|
|
139
168
|
}
|
|
140
169
|
});
|
|
141
|
-
|
|
142
|
-
|
|
170
|
+
});
|
|
171
|
+
__publicField(this, "onStop", ({ event }) => {
|
|
172
|
+
this.endInteraction(this.pluginId, "select");
|
|
143
173
|
if (event) {
|
|
144
|
-
|
|
174
|
+
if (this.isDragging) {
|
|
175
|
+
this.isDragging = false;
|
|
176
|
+
}
|
|
145
177
|
}
|
|
178
|
+
cancelAnimationFrame(this.updateFrameId);
|
|
179
|
+
this.updateFrameId = requestAnimationFrame(this.updateSelection);
|
|
180
|
+
});
|
|
181
|
+
__publicField(this, "updateSelection", () => {
|
|
182
|
+
var _a2;
|
|
183
|
+
const selected = [];
|
|
184
|
+
for (const element of ((_a2 = this.selection) == null ? void 0 : _a2.getSelection()) || []) {
|
|
185
|
+
const rule = this.getElementRule(element);
|
|
186
|
+
if (rule) {
|
|
187
|
+
selected.push({ type: rule.type, id: rule.idGetter(element) });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
this.selected = selected;
|
|
146
191
|
});
|
|
147
192
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
193
|
+
init(config = {}) {
|
|
194
|
+
this.container = config.container || bemSelector("canvas", "wrapper");
|
|
195
|
+
this.selectionAreaClassName = config.selectionAreaClassName || bem("selection-area");
|
|
196
|
+
if (!config.disableDefaultRules) {
|
|
197
|
+
const nodeRule = {
|
|
198
|
+
type: "node",
|
|
199
|
+
className: bem("node", "wrapper"),
|
|
200
|
+
activeClassName: bem("node", "wrapper", "selected"),
|
|
201
|
+
idGetter: (element) => element.getAttribute("data-node-id") || ""
|
|
202
|
+
};
|
|
203
|
+
this.ruleMap.set(nodeRule.className, nodeRule);
|
|
204
|
+
}
|
|
205
|
+
for (const rule of config.rules || []) {
|
|
206
|
+
this.ruleMap.set(rule.className, rule);
|
|
207
|
+
}
|
|
208
|
+
if (config.enableDrag !== void 0) {
|
|
209
|
+
this.enableDrag = config.enableDrag;
|
|
210
|
+
}
|
|
211
|
+
queueMicrotask(() => this.createSelection());
|
|
159
212
|
}
|
|
160
|
-
|
|
161
|
-
|
|
213
|
+
createSelection() {
|
|
214
|
+
const container = this.container;
|
|
215
|
+
this.selection = new SelectionArea({
|
|
216
|
+
// container,
|
|
217
|
+
boundaries: [container],
|
|
218
|
+
selectionAreaClass: this.selectionAreaClassName,
|
|
219
|
+
selectables: Array.from(this.ruleMap.keys()).map((className) => `.${className}`)
|
|
220
|
+
}).on("beforedrag", this.onBeforeDrag).on("beforestart", this.onBeforeStart).on("start", this.onStart).on("move", this.onMove).on("stop", this.onStop);
|
|
162
221
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const currentNodeIds = this.selectedNodeIds;
|
|
169
|
-
this.selectedNodeIds = [
|
|
170
|
-
...currentNodeIds,
|
|
171
|
-
...nodeIds.filter((id) => !currentNodeIds.includes(id))
|
|
172
|
-
];
|
|
222
|
+
getElementRule(element) {
|
|
223
|
+
for (const [className, rule] of this.ruleMap) {
|
|
224
|
+
if (element.classList.contains(className)) {
|
|
225
|
+
return rule;
|
|
226
|
+
}
|
|
173
227
|
}
|
|
228
|
+
return void 0;
|
|
229
|
+
}
|
|
230
|
+
getSelected() {
|
|
231
|
+
return this.selected;
|
|
232
|
+
}
|
|
233
|
+
clearSelection() {
|
|
234
|
+
var _a2;
|
|
235
|
+
(_a2 = this.selection) == null ? void 0 : _a2.clearSelection(true, false);
|
|
174
236
|
}
|
|
175
237
|
destroy() {
|
|
176
238
|
var _a2;
|
|
177
239
|
(_a2 = this.selection) == null ? void 0 : _a2.destroy();
|
|
240
|
+
this.ruleMap.clear();
|
|
178
241
|
}
|
|
179
242
|
}
|
|
180
243
|
_init = __decoratorStart(_a);
|
|
181
244
|
__decorateElement(_init, 1, "init", _init_dec, Selection);
|
|
182
|
-
__decorateElement(_init, 1, "
|
|
245
|
+
__decorateElement(_init, 1, "getSelected", _getSelected_dec, Selection);
|
|
183
246
|
__decorateElement(_init, 1, "clearSelection", _clearSelection_dec, Selection);
|
|
184
247
|
__decorateElement(_init, 1, "destroy", _destroy_dec, Selection);
|
|
185
|
-
__decorateElement(_init, 5, "
|
|
186
|
-
__decorateElement(_init, 5, "
|
|
248
|
+
__decorateElement(_init, 5, "selected", _selected_dec, Selection);
|
|
249
|
+
__decorateElement(_init, 5, "registerRules", _registerRules_dec, Selection);
|
|
187
250
|
__decorateElement(_init, 5, "startInteraction", _startInteraction_dec, Selection);
|
|
188
251
|
__decorateElement(_init, 5, "endInteraction", _endInteraction_dec, Selection);
|
|
189
252
|
__decorateElement(_init, 5, "canInteract", _canInteract_dec, Selection);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knotx/plugins-selection",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Selection Plugin for Knotx",
|
|
5
5
|
"author": "boenfu",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@viselect/vanilla": "^3.9.0",
|
|
32
32
|
"rxjs": "^7.8.1",
|
|
33
|
-
"@knotx/core": "0.
|
|
34
|
-
"@knotx/decorators": "0.
|
|
33
|
+
"@knotx/core": "0.3.1",
|
|
34
|
+
"@knotx/decorators": "0.3.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@knotx/build-config": "0.
|
|
38
|
-
"@knotx/eslint-config": "0.
|
|
39
|
-
"@knotx/typescript-config": "0.
|
|
37
|
+
"@knotx/build-config": "0.3.1",
|
|
38
|
+
"@knotx/eslint-config": "0.3.1",
|
|
39
|
+
"@knotx/typescript-config": "0.3.1"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "unbuild",
|