@knotx/plugins-selection 0.3.0 → 0.3.2
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 +149 -90
- package/dist/index.d.cts +66 -16
- package/dist/index.d.mts +66 -16
- package/dist/index.d.ts +66 -16
- package/dist/index.js +150 -91
- 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,123 +73,185 @@ 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, _interaction_dec, _registerRules_dec, _selected_dec, _a, _init;
|
|
77
|
+
class Selection extends (_a = core.BasePlugin, _selected_dec = [decorators.register("selected")], _registerRules_dec = [decorators.register("registerRules")], _interaction_dec = [decorators.inject.interaction()], _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, "
|
|
89
|
-
__publicField(this, "
|
|
90
|
-
__publicField(this, "
|
|
91
|
-
__publicField(this, "
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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);
|
|
102
|
+
__publicField(this, "interaction", __runInitializers(_init, 16, this)), __runInitializers(_init, 19, this);
|
|
103
|
+
__publicField(this, "onBeforeStart", (_) => {
|
|
104
|
+
});
|
|
105
|
+
__publicField(this, "onBeforeDrag", () => {
|
|
106
|
+
this.isDragging = this.enableDrag;
|
|
107
|
+
return this.enableDrag && this.interaction.canInteract(core.InteractionPriority.MarqueeSelection);
|
|
108
|
+
});
|
|
109
|
+
__publicField(this, "onStart", ({ event, store }) => {
|
|
110
|
+
var _a2;
|
|
111
|
+
this.interaction.start(this.pluginId, "select", core.InteractionPriority.MarqueeSelection);
|
|
109
112
|
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
|
-
|
|
113
|
+
store.stored.forEach((element) => {
|
|
114
|
+
const rule = this.getElementRule(element);
|
|
115
|
+
if (rule == null ? void 0 : rule.activeClassName) {
|
|
116
|
+
element.classList.remove(rule.activeClassName);
|
|
113
117
|
}
|
|
114
118
|
});
|
|
115
|
-
selection.clearSelection();
|
|
116
|
-
this.selectedNodeIds = [];
|
|
119
|
+
(_a2 = this.selection) == null ? void 0 : _a2.clearSelection(true, true);
|
|
117
120
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
121
|
+
});
|
|
122
|
+
__publicField(this, "onMove", ({ store: { stored, changed: { added, removed } }, selection }) => {
|
|
123
|
+
const getSelectedElements = () => {
|
|
124
|
+
return stored.reduce((dict, item) => {
|
|
125
|
+
const rule = this.getElementRule(item);
|
|
126
|
+
if (rule) {
|
|
127
|
+
dict[rule.type] = [...dict[rule.type] || [], { id: rule.idGetter(item), element: item }];
|
|
128
|
+
}
|
|
129
|
+
return dict;
|
|
130
|
+
}, {});
|
|
131
|
+
};
|
|
132
|
+
const context = {
|
|
133
|
+
isDragging: this.isDragging,
|
|
134
|
+
getSelectedElements,
|
|
135
|
+
select: (elements) => {
|
|
136
|
+
elements.forEach((element) => {
|
|
137
|
+
selection.select(element);
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
deselect: (elements) => {
|
|
141
|
+
elements.forEach((element) => {
|
|
142
|
+
selection.deselect(element);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
removed.forEach((element) => {
|
|
147
|
+
const rule = this.getElementRule(element);
|
|
148
|
+
if (!rule) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (rule.activeClassName) {
|
|
152
|
+
element.classList.remove(rule.activeClassName);
|
|
136
153
|
}
|
|
137
154
|
});
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
155
|
+
added.forEach((element) => {
|
|
156
|
+
const rule = this.getElementRule(element);
|
|
157
|
+
if (!rule) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const type = rule.type;
|
|
161
|
+
const id = rule.idGetter(element);
|
|
162
|
+
for (const [, rule2] of this.ruleMap) {
|
|
163
|
+
if (rule2.onSelected) {
|
|
164
|
+
if (!rule2.onSelected(__spreadValues({ element, type, id }, context))) {
|
|
165
|
+
selection.deselect(element, true);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (rule.activeClassName) {
|
|
171
|
+
element.classList.add(rule.activeClassName);
|
|
145
172
|
}
|
|
146
173
|
});
|
|
147
|
-
|
|
148
|
-
|
|
174
|
+
});
|
|
175
|
+
__publicField(this, "onStop", ({ event }) => {
|
|
176
|
+
this.interaction.end(this.pluginId, "select");
|
|
149
177
|
if (event) {
|
|
150
|
-
|
|
178
|
+
if (this.isDragging) {
|
|
179
|
+
this.isDragging = false;
|
|
180
|
+
}
|
|
151
181
|
}
|
|
182
|
+
cancelAnimationFrame(this.updateFrameId);
|
|
183
|
+
this.updateFrameId = requestAnimationFrame(this.updateSelected);
|
|
184
|
+
});
|
|
185
|
+
__publicField(this, "updateSelected", () => {
|
|
186
|
+
var _a2;
|
|
187
|
+
const selected = [];
|
|
188
|
+
for (const element of ((_a2 = this.selection) == null ? void 0 : _a2.getSelection()) || []) {
|
|
189
|
+
const rule = this.getElementRule(element);
|
|
190
|
+
if (rule) {
|
|
191
|
+
selected.push({ type: rule.type, id: rule.idGetter(element) });
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
this.selected = selected;
|
|
152
195
|
});
|
|
153
196
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
197
|
+
init(config = {}) {
|
|
198
|
+
this.container = config.container || core.bemSelector("canvas", "wrapper");
|
|
199
|
+
this.selectionAreaClassName = config.selectionAreaClassName || core.bem("selection-area");
|
|
200
|
+
if (!config.disableDefaultRules) {
|
|
201
|
+
const nodeRule = {
|
|
202
|
+
type: "node",
|
|
203
|
+
className: core.bem("node", "wrapper"),
|
|
204
|
+
activeClassName: core.bem("node", "wrapper", "selected"),
|
|
205
|
+
idGetter: (element) => element.getAttribute("data-node-id") || ""
|
|
206
|
+
};
|
|
207
|
+
this.ruleMap.set(nodeRule.className, nodeRule);
|
|
208
|
+
}
|
|
209
|
+
for (const rule of config.rules || []) {
|
|
210
|
+
this.ruleMap.set(rule.className, rule);
|
|
211
|
+
}
|
|
212
|
+
if (config.enableDrag !== void 0) {
|
|
213
|
+
this.enableDrag = config.enableDrag;
|
|
214
|
+
}
|
|
215
|
+
queueMicrotask(() => this.createSelection());
|
|
165
216
|
}
|
|
166
|
-
|
|
167
|
-
|
|
217
|
+
createSelection() {
|
|
218
|
+
const container = this.container;
|
|
219
|
+
this.selection = new SelectionArea__default({
|
|
220
|
+
// container,
|
|
221
|
+
boundaries: [container],
|
|
222
|
+
selectionAreaClass: this.selectionAreaClassName,
|
|
223
|
+
selectables: Array.from(this.ruleMap.keys()).map((className) => `.${className}`)
|
|
224
|
+
}).on("beforedrag", this.onBeforeDrag).on("beforestart", this.onBeforeStart).on("start", this.onStart).on("move", this.onMove).on("stop", this.onStop);
|
|
168
225
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const currentNodeIds = this.selectedNodeIds;
|
|
175
|
-
this.selectedNodeIds = [
|
|
176
|
-
...currentNodeIds,
|
|
177
|
-
...nodeIds.filter((id) => !currentNodeIds.includes(id))
|
|
178
|
-
];
|
|
226
|
+
getElementRule(element) {
|
|
227
|
+
for (const [className, rule] of this.ruleMap) {
|
|
228
|
+
if (element.classList.contains(className)) {
|
|
229
|
+
return rule;
|
|
230
|
+
}
|
|
179
231
|
}
|
|
232
|
+
return void 0;
|
|
233
|
+
}
|
|
234
|
+
getSelected() {
|
|
235
|
+
return this.selected;
|
|
236
|
+
}
|
|
237
|
+
clearSelection() {
|
|
238
|
+
var _a2;
|
|
239
|
+
(_a2 = this.selection) == null ? void 0 : _a2.clearSelection(true, false);
|
|
180
240
|
}
|
|
181
241
|
destroy() {
|
|
182
242
|
var _a2;
|
|
183
243
|
(_a2 = this.selection) == null ? void 0 : _a2.destroy();
|
|
244
|
+
this.ruleMap.clear();
|
|
184
245
|
}
|
|
185
246
|
}
|
|
186
247
|
_init = __decoratorStart(_a);
|
|
187
248
|
__decorateElement(_init, 1, "init", _init_dec, Selection);
|
|
188
|
-
__decorateElement(_init, 1, "
|
|
249
|
+
__decorateElement(_init, 1, "getSelected", _getSelected_dec, Selection);
|
|
189
250
|
__decorateElement(_init, 1, "clearSelection", _clearSelection_dec, Selection);
|
|
190
251
|
__decorateElement(_init, 1, "destroy", _destroy_dec, Selection);
|
|
191
|
-
__decorateElement(_init, 5, "
|
|
192
|
-
__decorateElement(_init, 5, "
|
|
193
|
-
__decorateElement(_init, 5, "
|
|
194
|
-
__decorateElement(_init, 5, "endInteraction", _endInteraction_dec, Selection);
|
|
195
|
-
__decorateElement(_init, 5, "canInteract", _canInteract_dec, Selection);
|
|
252
|
+
__decorateElement(_init, 5, "selected", _selected_dec, Selection);
|
|
253
|
+
__decorateElement(_init, 5, "registerRules", _registerRules_dec, Selection);
|
|
254
|
+
__decorateElement(_init, 5, "interaction", _interaction_dec, Selection);
|
|
196
255
|
__decoratorMetadata(_init, Selection);
|
|
197
256
|
|
|
198
257
|
exports.Selection = Selection;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,38 +1,88 @@
|
|
|
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
|
-
|
|
26
|
-
private
|
|
27
|
-
private
|
|
28
|
-
private
|
|
29
|
-
|
|
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;
|
|
73
|
+
private interaction;
|
|
74
|
+
init(config?: SelectionConfig): void;
|
|
30
75
|
private createSelection;
|
|
31
|
-
private
|
|
32
|
-
|
|
76
|
+
private onBeforeStart;
|
|
77
|
+
private onBeforeDrag;
|
|
78
|
+
private onStart;
|
|
79
|
+
private onMove;
|
|
80
|
+
private onStop;
|
|
81
|
+
private getElementRule;
|
|
82
|
+
private updateSelected;
|
|
83
|
+
getSelected(): SelectionSelectedItem[];
|
|
33
84
|
clearSelection(): void;
|
|
34
|
-
selectNodes(nodeIds: string[], clearPrevious?: boolean): void;
|
|
35
85
|
destroy(): void;
|
|
36
86
|
}
|
|
37
87
|
|
|
38
|
-
export { Selection, type SelectionConfig };
|
|
88
|
+
export { Selection, type SelectionConfig, type SelectionRule, type SelectionSelectedItem };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,38 +1,88 @@
|
|
|
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
|
-
|
|
26
|
-
private
|
|
27
|
-
private
|
|
28
|
-
private
|
|
29
|
-
|
|
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;
|
|
73
|
+
private interaction;
|
|
74
|
+
init(config?: SelectionConfig): void;
|
|
30
75
|
private createSelection;
|
|
31
|
-
private
|
|
32
|
-
|
|
76
|
+
private onBeforeStart;
|
|
77
|
+
private onBeforeDrag;
|
|
78
|
+
private onStart;
|
|
79
|
+
private onMove;
|
|
80
|
+
private onStop;
|
|
81
|
+
private getElementRule;
|
|
82
|
+
private updateSelected;
|
|
83
|
+
getSelected(): SelectionSelectedItem[];
|
|
33
84
|
clearSelection(): void;
|
|
34
|
-
selectNodes(nodeIds: string[], clearPrevious?: boolean): void;
|
|
35
85
|
destroy(): void;
|
|
36
86
|
}
|
|
37
87
|
|
|
38
|
-
export { Selection, type SelectionConfig };
|
|
88
|
+
export { Selection, type SelectionConfig, type SelectionRule, type SelectionSelectedItem };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,38 +1,88 @@
|
|
|
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
|
-
|
|
26
|
-
private
|
|
27
|
-
private
|
|
28
|
-
private
|
|
29
|
-
|
|
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;
|
|
73
|
+
private interaction;
|
|
74
|
+
init(config?: SelectionConfig): void;
|
|
30
75
|
private createSelection;
|
|
31
|
-
private
|
|
32
|
-
|
|
76
|
+
private onBeforeStart;
|
|
77
|
+
private onBeforeDrag;
|
|
78
|
+
private onStart;
|
|
79
|
+
private onMove;
|
|
80
|
+
private onStop;
|
|
81
|
+
private getElementRule;
|
|
82
|
+
private updateSelected;
|
|
83
|
+
getSelected(): SelectionSelectedItem[];
|
|
33
84
|
clearSelection(): void;
|
|
34
|
-
selectNodes(nodeIds: string[], clearPrevious?: boolean): void;
|
|
35
85
|
destroy(): void;
|
|
36
86
|
}
|
|
37
87
|
|
|
38
|
-
export { Selection, type SelectionConfig };
|
|
88
|
+
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,123 +67,185 @@ 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, _interaction_dec, _registerRules_dec, _selected_dec, _a, _init;
|
|
71
|
+
class Selection extends (_a = BasePlugin, _selected_dec = [register("selected")], _registerRules_dec = [register("registerRules")], _interaction_dec = [inject.interaction()], _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, "
|
|
83
|
-
__publicField(this, "
|
|
84
|
-
__publicField(this, "
|
|
85
|
-
__publicField(this, "
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
this
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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);
|
|
96
|
+
__publicField(this, "interaction", __runInitializers(_init, 16, this)), __runInitializers(_init, 19, this);
|
|
97
|
+
__publicField(this, "onBeforeStart", (_) => {
|
|
98
|
+
});
|
|
99
|
+
__publicField(this, "onBeforeDrag", () => {
|
|
100
|
+
this.isDragging = this.enableDrag;
|
|
101
|
+
return this.enableDrag && this.interaction.canInteract(InteractionPriority.MarqueeSelection);
|
|
102
|
+
});
|
|
103
|
+
__publicField(this, "onStart", ({ event, store }) => {
|
|
104
|
+
var _a2;
|
|
105
|
+
this.interaction.start(this.pluginId, "select", InteractionPriority.MarqueeSelection);
|
|
103
106
|
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
|
-
|
|
107
|
+
store.stored.forEach((element) => {
|
|
108
|
+
const rule = this.getElementRule(element);
|
|
109
|
+
if (rule == null ? void 0 : rule.activeClassName) {
|
|
110
|
+
element.classList.remove(rule.activeClassName);
|
|
107
111
|
}
|
|
108
112
|
});
|
|
109
|
-
selection.clearSelection();
|
|
110
|
-
this.selectedNodeIds = [];
|
|
113
|
+
(_a2 = this.selection) == null ? void 0 : _a2.clearSelection(true, true);
|
|
111
114
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
115
|
+
});
|
|
116
|
+
__publicField(this, "onMove", ({ store: { stored, changed: { added, removed } }, selection }) => {
|
|
117
|
+
const getSelectedElements = () => {
|
|
118
|
+
return stored.reduce((dict, item) => {
|
|
119
|
+
const rule = this.getElementRule(item);
|
|
120
|
+
if (rule) {
|
|
121
|
+
dict[rule.type] = [...dict[rule.type] || [], { id: rule.idGetter(item), element: item }];
|
|
122
|
+
}
|
|
123
|
+
return dict;
|
|
124
|
+
}, {});
|
|
125
|
+
};
|
|
126
|
+
const context = {
|
|
127
|
+
isDragging: this.isDragging,
|
|
128
|
+
getSelectedElements,
|
|
129
|
+
select: (elements) => {
|
|
130
|
+
elements.forEach((element) => {
|
|
131
|
+
selection.select(element);
|
|
132
|
+
});
|
|
133
|
+
},
|
|
134
|
+
deselect: (elements) => {
|
|
135
|
+
elements.forEach((element) => {
|
|
136
|
+
selection.deselect(element);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
removed.forEach((element) => {
|
|
141
|
+
const rule = this.getElementRule(element);
|
|
142
|
+
if (!rule) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (rule.activeClassName) {
|
|
146
|
+
element.classList.remove(rule.activeClassName);
|
|
130
147
|
}
|
|
131
148
|
});
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
149
|
+
added.forEach((element) => {
|
|
150
|
+
const rule = this.getElementRule(element);
|
|
151
|
+
if (!rule) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const type = rule.type;
|
|
155
|
+
const id = rule.idGetter(element);
|
|
156
|
+
for (const [, rule2] of this.ruleMap) {
|
|
157
|
+
if (rule2.onSelected) {
|
|
158
|
+
if (!rule2.onSelected(__spreadValues({ element, type, id }, context))) {
|
|
159
|
+
selection.deselect(element, true);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (rule.activeClassName) {
|
|
165
|
+
element.classList.add(rule.activeClassName);
|
|
139
166
|
}
|
|
140
167
|
});
|
|
141
|
-
|
|
142
|
-
|
|
168
|
+
});
|
|
169
|
+
__publicField(this, "onStop", ({ event }) => {
|
|
170
|
+
this.interaction.end(this.pluginId, "select");
|
|
143
171
|
if (event) {
|
|
144
|
-
|
|
172
|
+
if (this.isDragging) {
|
|
173
|
+
this.isDragging = false;
|
|
174
|
+
}
|
|
145
175
|
}
|
|
176
|
+
cancelAnimationFrame(this.updateFrameId);
|
|
177
|
+
this.updateFrameId = requestAnimationFrame(this.updateSelected);
|
|
178
|
+
});
|
|
179
|
+
__publicField(this, "updateSelected", () => {
|
|
180
|
+
var _a2;
|
|
181
|
+
const selected = [];
|
|
182
|
+
for (const element of ((_a2 = this.selection) == null ? void 0 : _a2.getSelection()) || []) {
|
|
183
|
+
const rule = this.getElementRule(element);
|
|
184
|
+
if (rule) {
|
|
185
|
+
selected.push({ type: rule.type, id: rule.idGetter(element) });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
this.selected = selected;
|
|
146
189
|
});
|
|
147
190
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
191
|
+
init(config = {}) {
|
|
192
|
+
this.container = config.container || bemSelector("canvas", "wrapper");
|
|
193
|
+
this.selectionAreaClassName = config.selectionAreaClassName || bem("selection-area");
|
|
194
|
+
if (!config.disableDefaultRules) {
|
|
195
|
+
const nodeRule = {
|
|
196
|
+
type: "node",
|
|
197
|
+
className: bem("node", "wrapper"),
|
|
198
|
+
activeClassName: bem("node", "wrapper", "selected"),
|
|
199
|
+
idGetter: (element) => element.getAttribute("data-node-id") || ""
|
|
200
|
+
};
|
|
201
|
+
this.ruleMap.set(nodeRule.className, nodeRule);
|
|
202
|
+
}
|
|
203
|
+
for (const rule of config.rules || []) {
|
|
204
|
+
this.ruleMap.set(rule.className, rule);
|
|
205
|
+
}
|
|
206
|
+
if (config.enableDrag !== void 0) {
|
|
207
|
+
this.enableDrag = config.enableDrag;
|
|
208
|
+
}
|
|
209
|
+
queueMicrotask(() => this.createSelection());
|
|
159
210
|
}
|
|
160
|
-
|
|
161
|
-
|
|
211
|
+
createSelection() {
|
|
212
|
+
const container = this.container;
|
|
213
|
+
this.selection = new SelectionArea({
|
|
214
|
+
// container,
|
|
215
|
+
boundaries: [container],
|
|
216
|
+
selectionAreaClass: this.selectionAreaClassName,
|
|
217
|
+
selectables: Array.from(this.ruleMap.keys()).map((className) => `.${className}`)
|
|
218
|
+
}).on("beforedrag", this.onBeforeDrag).on("beforestart", this.onBeforeStart).on("start", this.onStart).on("move", this.onMove).on("stop", this.onStop);
|
|
162
219
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const currentNodeIds = this.selectedNodeIds;
|
|
169
|
-
this.selectedNodeIds = [
|
|
170
|
-
...currentNodeIds,
|
|
171
|
-
...nodeIds.filter((id) => !currentNodeIds.includes(id))
|
|
172
|
-
];
|
|
220
|
+
getElementRule(element) {
|
|
221
|
+
for (const [className, rule] of this.ruleMap) {
|
|
222
|
+
if (element.classList.contains(className)) {
|
|
223
|
+
return rule;
|
|
224
|
+
}
|
|
173
225
|
}
|
|
226
|
+
return void 0;
|
|
227
|
+
}
|
|
228
|
+
getSelected() {
|
|
229
|
+
return this.selected;
|
|
230
|
+
}
|
|
231
|
+
clearSelection() {
|
|
232
|
+
var _a2;
|
|
233
|
+
(_a2 = this.selection) == null ? void 0 : _a2.clearSelection(true, false);
|
|
174
234
|
}
|
|
175
235
|
destroy() {
|
|
176
236
|
var _a2;
|
|
177
237
|
(_a2 = this.selection) == null ? void 0 : _a2.destroy();
|
|
238
|
+
this.ruleMap.clear();
|
|
178
239
|
}
|
|
179
240
|
}
|
|
180
241
|
_init = __decoratorStart(_a);
|
|
181
242
|
__decorateElement(_init, 1, "init", _init_dec, Selection);
|
|
182
|
-
__decorateElement(_init, 1, "
|
|
243
|
+
__decorateElement(_init, 1, "getSelected", _getSelected_dec, Selection);
|
|
183
244
|
__decorateElement(_init, 1, "clearSelection", _clearSelection_dec, Selection);
|
|
184
245
|
__decorateElement(_init, 1, "destroy", _destroy_dec, Selection);
|
|
185
|
-
__decorateElement(_init, 5, "
|
|
186
|
-
__decorateElement(_init, 5, "
|
|
187
|
-
__decorateElement(_init, 5, "
|
|
188
|
-
__decorateElement(_init, 5, "endInteraction", _endInteraction_dec, Selection);
|
|
189
|
-
__decorateElement(_init, 5, "canInteract", _canInteract_dec, Selection);
|
|
246
|
+
__decorateElement(_init, 5, "selected", _selected_dec, Selection);
|
|
247
|
+
__decorateElement(_init, 5, "registerRules", _registerRules_dec, Selection);
|
|
248
|
+
__decorateElement(_init, 5, "interaction", _interaction_dec, Selection);
|
|
190
249
|
__decoratorMetadata(_init, Selection);
|
|
191
250
|
|
|
192
251
|
export { Selection };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knotx/plugins-selection",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
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.3.
|
|
34
|
-
"@knotx/decorators": "0.3.
|
|
33
|
+
"@knotx/core": "0.3.2",
|
|
34
|
+
"@knotx/decorators": "0.3.2"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@knotx/build-config": "0.3.
|
|
38
|
-
"@knotx/eslint-config": "0.3.
|
|
39
|
-
"@knotx/typescript-config": "0.3.
|
|
37
|
+
"@knotx/build-config": "0.3.2",
|
|
38
|
+
"@knotx/eslint-config": "0.3.2",
|
|
39
|
+
"@knotx/typescript-config": "0.3.2"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "unbuild",
|