@itwin/unified-selection 0.1.0

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE.md +9 -0
  3. package/README.md +90 -0
  4. package/lib/cjs/unified-selection/Selectable.d.ts +131 -0
  5. package/lib/cjs/unified-selection/Selectable.d.ts.map +1 -0
  6. package/lib/cjs/unified-selection/Selectable.js +221 -0
  7. package/lib/cjs/unified-selection/Selectable.js.map +1 -0
  8. package/lib/cjs/unified-selection/SelectionChangeEvent.d.ts +89 -0
  9. package/lib/cjs/unified-selection/SelectionChangeEvent.d.ts.map +1 -0
  10. package/lib/cjs/unified-selection/SelectionChangeEvent.js +43 -0
  11. package/lib/cjs/unified-selection/SelectionChangeEvent.js.map +1 -0
  12. package/lib/cjs/unified-selection/SelectionStorage.d.ts +78 -0
  13. package/lib/cjs/unified-selection/SelectionStorage.d.ts.map +1 -0
  14. package/lib/cjs/unified-selection/SelectionStorage.js +132 -0
  15. package/lib/cjs/unified-selection/SelectionStorage.js.map +1 -0
  16. package/lib/cjs/unified-selection.d.ts +10 -0
  17. package/lib/cjs/unified-selection.d.ts.map +1 -0
  18. package/lib/cjs/unified-selection.js +29 -0
  19. package/lib/cjs/unified-selection.js.map +1 -0
  20. package/lib/esm/unified-selection/Selectable.d.ts +131 -0
  21. package/lib/esm/unified-selection/Selectable.d.ts.map +1 -0
  22. package/lib/esm/unified-selection/Selectable.js +218 -0
  23. package/lib/esm/unified-selection/Selectable.js.map +1 -0
  24. package/lib/esm/unified-selection/SelectionChangeEvent.d.ts +89 -0
  25. package/lib/esm/unified-selection/SelectionChangeEvent.d.ts.map +1 -0
  26. package/lib/esm/unified-selection/SelectionChangeEvent.js +39 -0
  27. package/lib/esm/unified-selection/SelectionChangeEvent.js.map +1 -0
  28. package/lib/esm/unified-selection/SelectionStorage.d.ts +78 -0
  29. package/lib/esm/unified-selection/SelectionStorage.d.ts.map +1 -0
  30. package/lib/esm/unified-selection/SelectionStorage.js +128 -0
  31. package/lib/esm/unified-selection/SelectionStorage.js.map +1 -0
  32. package/lib/esm/unified-selection.d.ts +10 -0
  33. package/lib/esm/unified-selection.d.ts.map +1 -0
  34. package/lib/esm/unified-selection.js +13 -0
  35. package/lib/esm/unified-selection.js.map +1 -0
  36. package/package.json +57 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @itwin/unified-selection
2
+
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#491](https://github.com/iTwin/presentation/pull/491): Initial package release.
package/LICENSE.md ADDED
@@ -0,0 +1,9 @@
1
+ # MIT License
2
+
3
+ Copyright © 2017-2024 Bentley Systems, Incorporated. All rights reserved.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # @itwin/unified-selection
2
+
3
+ Copyright © Bentley Systems, Incorporated. All rights reserved. See LICENSE.md for license terms and full copyright notice.
4
+
5
+ The `@itwin/unified-selection` package provides API for managing [unified selection](https://www.itwinjs.org/presentation/unified-selection/).
6
+
7
+ ## Basic concepts
8
+
9
+ The API consists of a few very basic concepts:
10
+
11
+ - A `Selectable` is something that can be selected and is associated with an [EC](https://www.itwinjs.org/bis/ec/) instance. There are 2 types of selectables:
12
+
13
+ - `SelectableInstanceKey` uniquely identifies a single EC instance through a full class name and [ECInstanceId](https://www.itwinjs.org/learning/ecsql/#ecinstanceid-and-ecclassid).
14
+ - `CustomSelectable` is identified by an arbitrary `identifier` string and knows how to get any number of `SelectableInstanceKey` associated with it.
15
+
16
+ - `Selectables` is a container for multiple `Selectable` instances. The container is structured in a way that allows to quickly find specific selectables by their identifier.
17
+
18
+ - `SelectionStorage` is an interface that manages `Selectables` for different [iModels](https://www.itwinjs.org/learning/imodels/). It allows:
19
+
20
+ - Changing the selection (add, remove, replace, clear).
21
+ - Get active selection.
22
+ - Listen to selection changes.
23
+
24
+ The package delivers the `createStorage()` function to create an instance of `SelectionStorage`. Consumers are also expected to call `SelectionStorage.clearStorage` whenever an iModel is closed to free up memory.
25
+
26
+ ## Basic usage
27
+
28
+ ```ts
29
+ // create a global selection store (generally, somewhere in main.ts or similar)
30
+ import { createStore } from "@itwin/unified-selection";
31
+ const unifiedSelection = createStore();
32
+
33
+ // the store should to be cleaned up when iModels are closed to free up memory, e.g.:
34
+ import { IModelConnection } from "@itwin/core-frontend";
35
+ IModelConnection.onClose.addListener((iModel) => {
36
+ unifiedSelection.clearStorage(iModel.key);
37
+ });
38
+
39
+ // add a demo selection listener
40
+ import { Selectables } from "@itwin/unified-selection";
41
+ unifiedSelection.selectionChangeEvent.addListener(({ iModelKey, source, changeType, selectables }) => {
42
+ const suffix = `in ${iModelKey} iModel from ${source} component`;
43
+ const numSelectables = Selectables.size(selectables);
44
+ switch (changeType) {
45
+ case "add":
46
+ console.log(`Added ${numSelectables} items to selection ${suffix}.`);
47
+ break;
48
+ case "remove":
49
+ console.log(`Removed ${numSelectables} items from selection ${suffix}.`);
50
+ break;
51
+ case "replace":
52
+ console.log(`Replaced selection with ${numSelectables} items ${suffix}.`);
53
+ break;
54
+ case "clear":
55
+ console.log(`Cleared selection ${suffix}.`);
56
+ break;
57
+ }
58
+ });
59
+
60
+ // in some component
61
+ MyComponent.onECInstanceSelected((iModel: IModelConnection, key: { className: string; id: Id64String }) => {
62
+ unifiedSelection.addToSelection({ iModelKey: iModel.key, source: "MyComponent", selectables: [key] });
63
+ });
64
+ ```
65
+
66
+ ## Details
67
+
68
+ ### Selection levels
69
+
70
+ By default, whenever a component changes unified selection, that happens at 0th (top) selection level. And similarly, whenever a component requests current selection from the storage, by default the top selection level is used. However, there are cases when we want to have multiple levels of selection.
71
+
72
+ For example, let's say there're 3 components: _A_, _B_ and _C_:
73
+
74
+ - _Component A_ shows a list of elements and allows selecting them.
75
+ - _Component B_ shows a list of elements selected in _Component A_ and allows selecting them individually. Selecting an individual element should not change selection in _Component A_ or content in _Component B_ itself.
76
+ - _Component C_ shows properties of elements selected either in _Component A_ or _Component B_.
77
+
78
+ The behavior described above can't be achieved using just one level of selection, because as soon as selection is made in _Component B_, that selection would get represented in _Component A_, and _Component B_ would change what it's displaying to the individual element.
79
+
80
+ That can be fixed by introducing another selection level, but before the components can be configured, here are a few key facts about selection levels:
81
+
82
+ - Higher level selection has lower index. So top level selection is 0, lower level is 1, and so on.
83
+ - Changing higher level selection clears all lower level selections.
84
+ - Lower level selection doesn't have to be a sub-set of higher level selection.
85
+
86
+ With that in mind, the above components _A_, _B_ and _C_ can be configured as follows:
87
+
88
+ - _Component A_ only cares about top level selection. Whenever something is selected in the component, unified selection is updated at the top level. Similarly, whenever unified selection changes, the component only reacts if that happened at the top level.
89
+ - _Component B_ reloads its content if the selection changes at the top level. Row selection is handled using lower level, so selecting a row doesn't affect _Component A's_ selection or _Component B's_ content.
90
+ - _Component C_ reloads its content no matter the selection level.
@@ -0,0 +1,131 @@
1
+ /** @packageDocumentation
2
+ * @module UnifiedSelection
3
+ */
4
+ /**
5
+ * ECInstance selectable
6
+ * @beta
7
+ */
8
+ export interface SelectableInstanceKey {
9
+ /** Full class name in format `SchemaName:ClassName` or `SchemaName.ClassName`. */
10
+ className: string;
11
+ /** ECInstance ID */
12
+ id: string;
13
+ }
14
+ /**
15
+ * A custom selectable
16
+ * @beta
17
+ */
18
+ export interface CustomSelectable {
19
+ /** Unique identifier of the selectable. */
20
+ identifier: string;
21
+ /** Asynchronous function for loading instance keys associated with this selectable. */
22
+ loadInstanceKeys: () => AsyncIterableIterator<SelectableInstanceKey>;
23
+ /** Custom data associated with the selectable. */
24
+ data: unknown;
25
+ }
26
+ /**
27
+ * A single selectable that identifies something in an iTwin.js application
28
+ * @beta
29
+ */
30
+ export type Selectable = SelectableInstanceKey | CustomSelectable;
31
+ /**
32
+ * Type of identifier that can be used to identify selectable in storage.
33
+ * @beta
34
+ */
35
+ export type SelectableIdentifier = SelectableInstanceKey | Pick<CustomSelectable, "identifier">;
36
+ /** @beta */
37
+ export declare namespace Selectable {
38
+ /** Check if the supplied selectable is a `SelectableInstanceKey` */
39
+ function isInstanceKey(selectable: Selectable | SelectableIdentifier): selectable is SelectableInstanceKey;
40
+ /** Check if the supplied selectable is a `CustomSelectable` */
41
+ function isCustom(selectable: Selectable): selectable is CustomSelectable;
42
+ }
43
+ /**
44
+ * A collection of selectables that identify something that can be selected in an iTwin.js application
45
+ * @beta
46
+ */
47
+ export interface Selectables {
48
+ /**
49
+ * Map between `SelectableInstanceKey.className` and a set of selected element IDs.
50
+ */
51
+ instanceKeys: Map<string, Set<string>>;
52
+ /**
53
+ * Map between unique identifier of `CustomSelectable` and the selectable itself.
54
+ */
55
+ custom: Map<string, CustomSelectable>;
56
+ }
57
+ /** @beta */
58
+ export declare namespace Selectables {
59
+ /**
60
+ * Creates `Selectables` from array of selectable
61
+ * @param source Source to create selectables from
62
+ * @beta
63
+ */
64
+ function create(source: Selectable[]): Selectables;
65
+ /**
66
+ * Get the number of selectables stored in a `Selectables` object.
67
+ * @param selectables `Selectables` object to get size for
68
+ * @beta
69
+ */
70
+ function size(selectables: Selectables): number;
71
+ /**
72
+ * Is a `Selectables` object currently empty.
73
+ * @param selectables `Selectables` object to check
74
+ * @beta
75
+ */
76
+ function isEmpty(selectables: Selectables): boolean;
77
+ /**
78
+ * Check if a `Selectables` object contains the specified selectable.
79
+ * @param selectables `Selectables` object to check
80
+ * @param value The selectable to check for.
81
+ * @beta
82
+ */
83
+ function has(selectables: Selectables, value: SelectableIdentifier): boolean;
84
+ /**
85
+ * Check if a `Selectables` object contains all the specified selectables.
86
+ * @param selectables `Selectables` object to check
87
+ * @param values The selectables to check for.
88
+ * @beta
89
+ */
90
+ function hasAll(selectables: Selectables, values: SelectableIdentifier[]): boolean;
91
+ /**
92
+ * Check if a `Selectables` object contains any of the specified selectables.
93
+ * @param selectables `Selectables` object to check
94
+ * @param values The selectables to check for.
95
+ * @beta
96
+ */
97
+ function hasAny(selectables: Selectables, values: SelectableIdentifier[]): boolean;
98
+ /**
99
+ * Add a one or more selectables to a `Selectables`
100
+ * @param selectables `Selectables` object to add selectables for
101
+ * @param values Selectables to add.
102
+ * @beta
103
+ */
104
+ function add(selectables: Selectables, values: Selectable[]): boolean;
105
+ /**
106
+ * Removes one or more selectables from a `Selectables` object.
107
+ * @param selectables `Selectables` object to remove selectables for
108
+ * @param values Selectables to remove.
109
+ * @beta
110
+ */
111
+ function remove(selectables: Selectables, values: Selectable[]): boolean;
112
+ /**
113
+ * Clear a `Selectables` object.
114
+ * @param selectables `Selectables` object to clear selectables for
115
+ * @beta
116
+ */
117
+ function clear(selectables: Selectables): boolean;
118
+ /**
119
+ * Check whether at least one selectable passes a condition in a `Selectables` object.
120
+ * @param selectables `Selectables` object to check
121
+ * @beta
122
+ */
123
+ function some(selectables: Selectables, callback: (selectable: Selectable) => boolean): boolean;
124
+ /**
125
+ * Iterate over all keys in a `Selectables` object.
126
+ * @param selectables `Selectables` object to iterate over
127
+ * @beta
128
+ */
129
+ function forEach(selectables: Selectables, callback: (selectable: Selectable, index: number) => void): void;
130
+ }
131
+ //# sourceMappingURL=Selectable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Selectable.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/Selectable.ts"],"names":[],"mappings":"AAKA;;GAEG;AAEH;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,gBAAgB,EAAE,MAAM,qBAAqB,CAAC,qBAAqB,CAAC,CAAC;IACrE,kDAAkD;IAClD,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,qBAAqB,GAAG,gBAAgB,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,qBAAqB,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;AAEhG,YAAY;AAEZ,yBAAiB,UAAU,CAAC;IAC1B,oEAAoE;IACpE,SAAgB,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,oBAAoB,GAAG,UAAU,IAAI,qBAAqB,CAGhH;IAED,+DAA+D;IAC/D,SAAgB,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,IAAI,gBAAgB,CAE/E;CACF;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACvC;;OAEG;IACH,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CACvC;AAED,YAAY;AAEZ,yBAAiB,WAAW,CAAC;IAC3B;;;;OAIG;IACH,SAAgB,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,WAAW,CAOxD;IAED;;;;OAIG;IACH,SAAgB,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAIrD;IAED;;;;OAIG;IACH,SAAgB,OAAO,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAEzD;IAED;;;;;OAKG;IACH,SAAgB,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAOlF;IAED;;;;;OAKG;IACH,SAAgB,MAAM,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAUxF;IAED;;;;;OAKG;IACH,SAAgB,MAAM,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAOxF;IAED;;;;;OAKG;IACH,SAAgB,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAoB3E;IAED;;;;;OAKG;IACH,SAAgB,MAAM,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAmB9E;IAED;;;;OAIG;IACH,SAAgB,KAAK,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAOvD;IAED;;;;OAIG;IACH,SAAgB,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,OAAO,WAc3F;IAED;;;;OAIG;IACH,SAAgB,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,QAQ1G;CAKF"}
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.Selectables = exports.Selectable = void 0;
8
+ /** @beta */
9
+ // eslint-disable-next-line @typescript-eslint/no-redeclare
10
+ var Selectable;
11
+ (function (Selectable) {
12
+ /** Check if the supplied selectable is a `SelectableInstanceKey` */
13
+ function isInstanceKey(selectable) {
14
+ const instanceKey = selectable;
15
+ return !!instanceKey.className && !!instanceKey.id;
16
+ }
17
+ Selectable.isInstanceKey = isInstanceKey;
18
+ /** Check if the supplied selectable is a `CustomSelectable` */
19
+ function isCustom(selectable) {
20
+ return !!selectable.identifier;
21
+ }
22
+ Selectable.isCustom = isCustom;
23
+ })(Selectable = exports.Selectable || (exports.Selectable = {}));
24
+ /** @beta */
25
+ // eslint-disable-next-line @typescript-eslint/no-redeclare
26
+ var Selectables;
27
+ (function (Selectables) {
28
+ /**
29
+ * Creates `Selectables` from array of selectable
30
+ * @param source Source to create selectables from
31
+ * @beta
32
+ */
33
+ function create(source) {
34
+ const newSelectables = {
35
+ instanceKeys: new Map(),
36
+ custom: new Map(),
37
+ };
38
+ Selectables.add(newSelectables, source);
39
+ return newSelectables;
40
+ }
41
+ Selectables.create = create;
42
+ /**
43
+ * Get the number of selectables stored in a `Selectables` object.
44
+ * @param selectables `Selectables` object to get size for
45
+ * @beta
46
+ */
47
+ function size(selectables) {
48
+ let insatanceCount = 0;
49
+ selectables.instanceKeys.forEach((set) => (insatanceCount += set.size));
50
+ return insatanceCount + selectables.custom.size;
51
+ }
52
+ Selectables.size = size;
53
+ /**
54
+ * Is a `Selectables` object currently empty.
55
+ * @param selectables `Selectables` object to check
56
+ * @beta
57
+ */
58
+ function isEmpty(selectables) {
59
+ return Selectables.size(selectables) === 0;
60
+ }
61
+ Selectables.isEmpty = isEmpty;
62
+ /**
63
+ * Check if a `Selectables` object contains the specified selectable.
64
+ * @param selectables `Selectables` object to check
65
+ * @param value The selectable to check for.
66
+ * @beta
67
+ */
68
+ function has(selectables, value) {
69
+ if (Selectable.isInstanceKey(value)) {
70
+ const normalizedClassName = normalizeClassName(value.className);
71
+ const set = selectables.instanceKeys.get(normalizedClassName);
72
+ return !!(set && set.has(value.id));
73
+ }
74
+ return selectables.custom.has(value.identifier);
75
+ }
76
+ Selectables.has = has;
77
+ /**
78
+ * Check if a `Selectables` object contains all the specified selectables.
79
+ * @param selectables `Selectables` object to check
80
+ * @param values The selectables to check for.
81
+ * @beta
82
+ */
83
+ function hasAll(selectables, values) {
84
+ if (Selectables.size(selectables) < values.length) {
85
+ return false;
86
+ }
87
+ for (const selectable of values) {
88
+ if (!Selectables.has(selectables, selectable)) {
89
+ return false;
90
+ }
91
+ }
92
+ return true;
93
+ }
94
+ Selectables.hasAll = hasAll;
95
+ /**
96
+ * Check if a `Selectables` object contains any of the specified selectables.
97
+ * @param selectables `Selectables` object to check
98
+ * @param values The selectables to check for.
99
+ * @beta
100
+ */
101
+ function hasAny(selectables, values) {
102
+ for (const selectable of values) {
103
+ if (Selectables.has(selectables, selectable)) {
104
+ return true;
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+ Selectables.hasAny = hasAny;
110
+ /**
111
+ * Add a one or more selectables to a `Selectables`
112
+ * @param selectables `Selectables` object to add selectables for
113
+ * @param values Selectables to add.
114
+ * @beta
115
+ */
116
+ function add(selectables, values) {
117
+ let hasChanged = false;
118
+ for (const selectable of values) {
119
+ if (Selectable.isInstanceKey(selectable)) {
120
+ const normalizedClassName = normalizeClassName(selectable.className);
121
+ let set = selectables.instanceKeys.get(normalizedClassName);
122
+ if (!set) {
123
+ set = new Set();
124
+ }
125
+ if (!set.has(selectable.id)) {
126
+ set.add(selectable.id);
127
+ selectables.instanceKeys.set(normalizedClassName, set);
128
+ hasChanged = true;
129
+ }
130
+ }
131
+ else if (!selectables.custom.has(selectable.identifier)) {
132
+ selectables.custom.set(selectable.identifier, selectable);
133
+ hasChanged = true;
134
+ }
135
+ }
136
+ return hasChanged;
137
+ }
138
+ Selectables.add = add;
139
+ /**
140
+ * Removes one or more selectables from a `Selectables` object.
141
+ * @param selectables `Selectables` object to remove selectables for
142
+ * @param values Selectables to remove.
143
+ * @beta
144
+ */
145
+ function remove(selectables, values) {
146
+ let hasChanged = false;
147
+ for (const selectable of values) {
148
+ if (Selectable.isInstanceKey(selectable)) {
149
+ const normalizedClassName = normalizeClassName(selectable.className);
150
+ const set = selectables.instanceKeys.get(normalizedClassName);
151
+ if (set && set.has(selectable.id)) {
152
+ set.delete(selectable.id);
153
+ hasChanged = true;
154
+ if (set.size === 0) {
155
+ selectables.instanceKeys.delete(normalizedClassName);
156
+ }
157
+ }
158
+ }
159
+ else if (selectables.custom.has(selectable.identifier)) {
160
+ selectables.custom.delete(selectable.identifier);
161
+ hasChanged = true;
162
+ }
163
+ }
164
+ return hasChanged;
165
+ }
166
+ Selectables.remove = remove;
167
+ /**
168
+ * Clear a `Selectables` object.
169
+ * @param selectables `Selectables` object to clear selectables for
170
+ * @beta
171
+ */
172
+ function clear(selectables) {
173
+ if (Selectables.size(selectables) === 0) {
174
+ return false;
175
+ }
176
+ selectables.instanceKeys = new Map();
177
+ selectables.custom = new Map();
178
+ return true;
179
+ }
180
+ Selectables.clear = clear;
181
+ /**
182
+ * Check whether at least one selectable passes a condition in a `Selectables` object.
183
+ * @param selectables `Selectables` object to check
184
+ * @beta
185
+ */
186
+ function some(selectables, callback) {
187
+ for (const entry of selectables.instanceKeys) {
188
+ for (const item of entry[1]) {
189
+ if (callback({ className: entry[0], id: item })) {
190
+ return true;
191
+ }
192
+ }
193
+ }
194
+ for (const entry of selectables.custom) {
195
+ if (callback(entry[1])) {
196
+ return true;
197
+ }
198
+ }
199
+ return false;
200
+ }
201
+ Selectables.some = some;
202
+ /**
203
+ * Iterate over all keys in a `Selectables` object.
204
+ * @param selectables `Selectables` object to iterate over
205
+ * @beta
206
+ */
207
+ function forEach(selectables, callback) {
208
+ let index = 0;
209
+ selectables.instanceKeys.forEach((ids, className) => {
210
+ ids.forEach((id) => callback({ className, id }, index++));
211
+ });
212
+ selectables.custom.forEach((data) => {
213
+ callback(data, index++);
214
+ });
215
+ }
216
+ Selectables.forEach = forEach;
217
+ function normalizeClassName(className) {
218
+ return className.replace(".", ":");
219
+ }
220
+ })(Selectables = exports.Selectables || (exports.Selectables = {}));
221
+ //# sourceMappingURL=Selectable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Selectable.js","sourceRoot":"","sources":["../../../src/unified-selection/Selectable.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module UnifiedSelection\n */\n\n/**\n * ECInstance selectable\n * @beta\n */\nexport interface SelectableInstanceKey {\n /** Full class name in format `SchemaName:ClassName` or `SchemaName.ClassName`. */\n className: string;\n /** ECInstance ID */\n id: string;\n}\n\n/**\n * A custom selectable\n * @beta\n */\nexport interface CustomSelectable {\n /** Unique identifier of the selectable. */\n identifier: string;\n /** Asynchronous function for loading instance keys associated with this selectable. */\n loadInstanceKeys: () => AsyncIterableIterator<SelectableInstanceKey>;\n /** Custom data associated with the selectable. */\n data: unknown;\n}\n\n/**\n * A single selectable that identifies something in an iTwin.js application\n * @beta\n */\nexport type Selectable = SelectableInstanceKey | CustomSelectable;\n\n/**\n * Type of identifier that can be used to identify selectable in storage.\n * @beta\n */\nexport type SelectableIdentifier = SelectableInstanceKey | Pick<CustomSelectable, \"identifier\">;\n\n/** @beta */\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Selectable {\n /** Check if the supplied selectable is a `SelectableInstanceKey` */\n export function isInstanceKey(selectable: Selectable | SelectableIdentifier): selectable is SelectableInstanceKey {\n const instanceKey = selectable as SelectableInstanceKey;\n return !!instanceKey.className && !!instanceKey.id;\n }\n\n /** Check if the supplied selectable is a `CustomSelectable` */\n export function isCustom(selectable: Selectable): selectable is CustomSelectable {\n return !!(selectable as CustomSelectable).identifier;\n }\n}\n\n/**\n * A collection of selectables that identify something that can be selected in an iTwin.js application\n * @beta\n */\nexport interface Selectables {\n /**\n * Map between `SelectableInstanceKey.className` and a set of selected element IDs.\n */\n instanceKeys: Map<string, Set<string>>;\n /**\n * Map between unique identifier of `CustomSelectable` and the selectable itself.\n */\n custom: Map<string, CustomSelectable>;\n}\n\n/** @beta */\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace Selectables {\n /**\n * Creates `Selectables` from array of selectable\n * @param source Source to create selectables from\n * @beta\n */\n export function create(source: Selectable[]): Selectables {\n const newSelectables = {\n instanceKeys: new Map<string, Set<string>>(),\n custom: new Map<string, CustomSelectable>(),\n };\n Selectables.add(newSelectables, source);\n return newSelectables;\n }\n\n /**\n * Get the number of selectables stored in a `Selectables` object.\n * @param selectables `Selectables` object to get size for\n * @beta\n */\n export function size(selectables: Selectables): number {\n let insatanceCount = 0;\n selectables.instanceKeys.forEach((set: Set<string>) => (insatanceCount += set.size));\n return insatanceCount + selectables.custom.size;\n }\n\n /**\n * Is a `Selectables` object currently empty.\n * @param selectables `Selectables` object to check\n * @beta\n */\n export function isEmpty(selectables: Selectables): boolean {\n return Selectables.size(selectables) === 0;\n }\n\n /**\n * Check if a `Selectables` object contains the specified selectable.\n * @param selectables `Selectables` object to check\n * @param value The selectable to check for.\n * @beta\n */\n export function has(selectables: Selectables, value: SelectableIdentifier): boolean {\n if (Selectable.isInstanceKey(value)) {\n const normalizedClassName = normalizeClassName(value.className);\n const set = selectables.instanceKeys.get(normalizedClassName);\n return !!(set && set.has(value.id));\n }\n return selectables.custom.has(value.identifier);\n }\n\n /**\n * Check if a `Selectables` object contains all the specified selectables.\n * @param selectables `Selectables` object to check\n * @param values The selectables to check for.\n * @beta\n */\n export function hasAll(selectables: Selectables, values: SelectableIdentifier[]): boolean {\n if (Selectables.size(selectables) < values.length) {\n return false;\n }\n for (const selectable of values) {\n if (!Selectables.has(selectables, selectable)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Check if a `Selectables` object contains any of the specified selectables.\n * @param selectables `Selectables` object to check\n * @param values The selectables to check for.\n * @beta\n */\n export function hasAny(selectables: Selectables, values: SelectableIdentifier[]): boolean {\n for (const selectable of values) {\n if (Selectables.has(selectables, selectable)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Add a one or more selectables to a `Selectables`\n * @param selectables `Selectables` object to add selectables for\n * @param values Selectables to add.\n * @beta\n */\n export function add(selectables: Selectables, values: Selectable[]): boolean {\n let hasChanged = false;\n for (const selectable of values) {\n if (Selectable.isInstanceKey(selectable)) {\n const normalizedClassName = normalizeClassName(selectable.className);\n let set = selectables.instanceKeys.get(normalizedClassName);\n if (!set) {\n set = new Set<string>();\n }\n if (!set.has(selectable.id)) {\n set.add(selectable.id);\n selectables.instanceKeys.set(normalizedClassName, set);\n hasChanged = true;\n }\n } else if (!selectables.custom.has(selectable.identifier)) {\n selectables.custom.set(selectable.identifier, selectable);\n hasChanged = true;\n }\n }\n return hasChanged;\n }\n\n /**\n * Removes one or more selectables from a `Selectables` object.\n * @param selectables `Selectables` object to remove selectables for\n * @param values Selectables to remove.\n * @beta\n */\n export function remove(selectables: Selectables, values: Selectable[]): boolean {\n let hasChanged = false;\n for (const selectable of values) {\n if (Selectable.isInstanceKey(selectable)) {\n const normalizedClassName = normalizeClassName(selectable.className);\n const set = selectables.instanceKeys.get(normalizedClassName);\n if (set && set.has(selectable.id)) {\n set.delete(selectable.id);\n hasChanged = true;\n if (set.size === 0) {\n selectables.instanceKeys.delete(normalizedClassName);\n }\n }\n } else if (selectables.custom.has(selectable.identifier)) {\n selectables.custom.delete(selectable.identifier);\n hasChanged = true;\n }\n }\n return hasChanged;\n }\n\n /**\n * Clear a `Selectables` object.\n * @param selectables `Selectables` object to clear selectables for\n * @beta\n */\n export function clear(selectables: Selectables): boolean {\n if (Selectables.size(selectables) === 0) {\n return false;\n }\n selectables.instanceKeys = new Map<string, Set<string>>();\n selectables.custom = new Map<string, CustomSelectable>();\n return true;\n }\n\n /**\n * Check whether at least one selectable passes a condition in a `Selectables` object.\n * @param selectables `Selectables` object to check\n * @beta\n */\n export function some(selectables: Selectables, callback: (selectable: Selectable) => boolean) {\n for (const entry of selectables.instanceKeys) {\n for (const item of entry[1]) {\n if (callback({ className: entry[0], id: item })) {\n return true;\n }\n }\n }\n for (const entry of selectables.custom) {\n if (callback(entry[1])) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Iterate over all keys in a `Selectables` object.\n * @param selectables `Selectables` object to iterate over\n * @beta\n */\n export function forEach(selectables: Selectables, callback: (selectable: Selectable, index: number) => void) {\n let index = 0;\n selectables.instanceKeys.forEach((ids: Set<string>, className: string) => {\n ids.forEach((id: string) => callback({ className, id }, index++));\n });\n selectables.custom.forEach((data) => {\n callback(data, index++);\n });\n }\n\n function normalizeClassName(className: string): string {\n return className.replace(\".\", \":\");\n }\n}\n"]}
@@ -0,0 +1,89 @@
1
+ import { Selectables } from "./Selectable";
2
+ import { SelectionStorage } from "./SelectionStorage";
3
+ /** @packageDocumentation
4
+ * @module UnifiedSelection
5
+ */
6
+ /**
7
+ * The type of selection change
8
+ * @beta
9
+ */
10
+ export type StorageSelectionChangeType =
11
+ /** Added to selection. */
12
+ "add"
13
+ /** Removed from selection. */
14
+ | "remove"
15
+ /** Selection was replaced. */
16
+ | "replace"
17
+ /** Selection was cleared. */
18
+ | "clear";
19
+ /**
20
+ * The event object that is sent when the selection changes.
21
+ * @beta
22
+ */
23
+ export interface StorageSelectionChangeEventArgs {
24
+ /** The name of the selection source which caused the selection change. */
25
+ source: string;
26
+ /** Level of the selection. */
27
+ level: number;
28
+ /** The selection change type. */
29
+ changeType: StorageSelectionChangeType;
30
+ /** Selectables affected by this selection change event. */
31
+ selectables: Selectables;
32
+ /** iModel key with which the selection is associated with. */
33
+ iModelKey: string;
34
+ /** The timestamp of when the selection change happened */
35
+ timestamp: Date;
36
+ }
37
+ /**
38
+ * An interface for selection change listeners
39
+ * @beta
40
+ */
41
+ export declare type StorageSelectionChangesListener = (args: StorageSelectionChangeEventArgs, storage: SelectionStorage) => void;
42
+ /**
43
+ * An interface that allows subscribing and unsubscribing listeners that
44
+ * are called when a selection has changed.
45
+ * @beta
46
+ */
47
+ export interface SelectionChangeEvent {
48
+ /**
49
+ * Registers a Listener to be executed whenever this event is raised
50
+ * @param listener The function to be executed when the event is raised
51
+ * @returns A function that will remove this event listener
52
+ * @beta
53
+ */
54
+ addListener(listener: StorageSelectionChangesListener): () => void;
55
+ /**
56
+ * Un-register a previously registered listener
57
+ * @param listener The listener to be unregistered
58
+ * @beta
59
+ */
60
+ removeListener(listener: StorageSelectionChangesListener): void;
61
+ }
62
+ /**
63
+ * An event broadcasted on selection changes
64
+ * @internal
65
+ */
66
+ export declare class SelectionChangeEventImpl implements SelectionChangeEvent {
67
+ private _listeners;
68
+ /**
69
+ * Registers a Listener to be executed whenever this event is raised
70
+ * @param listener The function to be executed when the event is raised
71
+ * @returns A function that will remove this event listener
72
+ * @beta
73
+ */
74
+ addListener(listener: StorageSelectionChangesListener): () => void;
75
+ /**
76
+ * Un-register a previously registered listener
77
+ * @param listener The listener to be unregistered
78
+ * @beta
79
+ */
80
+ removeListener(listener: StorageSelectionChangesListener): void;
81
+ /**
82
+ * Raises the event by calling each registered listener with the supplied arguments
83
+ * @param args Event arguments
84
+ * @param storage Storage that the selection changed in
85
+ * @beta
86
+ */
87
+ raiseEvent(args: StorageSelectionChangeEventArgs, storage: SelectionStorage): void;
88
+ }
89
+ //# sourceMappingURL=SelectionChangeEvent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionChangeEvent.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/SelectionChangeEvent.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AAEH;;;GAGG;AACH,MAAM,MAAM,0BAA0B;AACpC,0BAA0B;AACxB,KAAK;AACP,8BAA8B;GAC5B,QAAQ;AACV,8BAA8B;GAC5B,SAAS;AACX,6BAA6B;GAC3B,OAAO,CAAC;AAEZ;;;GAGG;AACH,MAAM,WAAW,+BAA+B;IAC9C,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,UAAU,EAAE,0BAA0B,CAAC;IACvC,2DAA2D;IAC3D,WAAW,EAAE,WAAW,CAAC;IACzB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,CAAC,OAAO,MAAM,+BAA+B,GAAG,CAAC,IAAI,EAAE,+BAA+B,EAAE,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAEjI;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,+BAA+B,GAAG,MAAM,IAAI,CAAC;IACnE;;;;OAIG;IACH,cAAc,CAAC,QAAQ,EAAE,+BAA+B,GAAG,IAAI,CAAC;CACjE;AAED;;;GAGG;AACH,qBAAa,wBAAyB,YAAW,oBAAoB;IACnE,OAAO,CAAC,UAAU,CAAyC;IAE3D;;;;;OAKG;IACI,WAAW,CAAC,QAAQ,EAAE,+BAA+B,GAAG,MAAM,IAAI;IAKzE;;;;OAIG;IACI,cAAc,CAAC,QAAQ,EAAE,+BAA+B,GAAG,IAAI;IAItE;;;;;OAKG;IACI,UAAU,CAAC,IAAI,EAAE,+BAA+B,EAAE,OAAO,EAAE,gBAAgB;CAGnF"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.SelectionChangeEventImpl = void 0;
8
+ /**
9
+ * An event broadcasted on selection changes
10
+ * @internal
11
+ */
12
+ class SelectionChangeEventImpl {
13
+ _listeners = [];
14
+ /**
15
+ * Registers a Listener to be executed whenever this event is raised
16
+ * @param listener The function to be executed when the event is raised
17
+ * @returns A function that will remove this event listener
18
+ * @beta
19
+ */
20
+ addListener(listener) {
21
+ this._listeners.push(listener);
22
+ return () => this.removeListener(listener);
23
+ }
24
+ /**
25
+ * Un-register a previously registered listener
26
+ * @param listener The listener to be unregistered
27
+ * @beta
28
+ */
29
+ removeListener(listener) {
30
+ this._listeners = this._listeners.filter((x) => x !== listener);
31
+ }
32
+ /**
33
+ * Raises the event by calling each registered listener with the supplied arguments
34
+ * @param args Event arguments
35
+ * @param storage Storage that the selection changed in
36
+ * @beta
37
+ */
38
+ raiseEvent(args, storage) {
39
+ this._listeners.forEach((listener) => listener(args, storage));
40
+ }
41
+ }
42
+ exports.SelectionChangeEventImpl = SelectionChangeEventImpl;
43
+ //# sourceMappingURL=SelectionChangeEvent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionChangeEvent.js","sourceRoot":"","sources":["../../../src/unified-selection/SelectionChangeEvent.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAqEhG;;;GAGG;AACH,MAAa,wBAAwB;IAC3B,UAAU,GAAsC,EAAE,CAAC;IAE3D;;;;;OAKG;IACI,WAAW,CAAC,QAAyC;QAC1D,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED;;;;OAIG;IACI,cAAc,CAAC,QAAyC;QAC7D,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC;IAClE,CAAC;IAED;;;;;OAKG;IACI,UAAU,CAAC,IAAqC,EAAE,OAAyB;QAChF,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACjE,CAAC;CACF;AAhCD,4DAgCC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Selectables } from \"./Selectable\";\nimport { SelectionStorage } from \"./SelectionStorage\";\n\n/** @packageDocumentation\n * @module UnifiedSelection\n */\n\n/**\n * The type of selection change\n * @beta\n */\nexport type StorageSelectionChangeType =\n /** Added to selection. */\n | \"add\"\n /** Removed from selection. */\n | \"remove\"\n /** Selection was replaced. */\n | \"replace\"\n /** Selection was cleared. */\n | \"clear\";\n\n/**\n * The event object that is sent when the selection changes.\n * @beta\n */\nexport interface StorageSelectionChangeEventArgs {\n /** The name of the selection source which caused the selection change. */\n source: string;\n /** Level of the selection. */\n level: number;\n /** The selection change type. */\n changeType: StorageSelectionChangeType;\n /** Selectables affected by this selection change event. */\n selectables: Selectables;\n /** iModel key with which the selection is associated with. */\n iModelKey: string;\n /** The timestamp of when the selection change happened */\n timestamp: Date;\n}\n\n/**\n * An interface for selection change listeners\n * @beta\n */\nexport declare type StorageSelectionChangesListener = (args: StorageSelectionChangeEventArgs, storage: SelectionStorage) => void;\n\n/**\n * An interface that allows subscribing and unsubscribing listeners that\n * are called when a selection has changed.\n * @beta\n */\nexport interface SelectionChangeEvent {\n /**\n * Registers a Listener to be executed whenever this event is raised\n * @param listener The function to be executed when the event is raised\n * @returns A function that will remove this event listener\n * @beta\n */\n addListener(listener: StorageSelectionChangesListener): () => void;\n /**\n * Un-register a previously registered listener\n * @param listener The listener to be unregistered\n * @beta\n */\n removeListener(listener: StorageSelectionChangesListener): void;\n}\n\n/**\n * An event broadcasted on selection changes\n * @internal\n */\nexport class SelectionChangeEventImpl implements SelectionChangeEvent {\n private _listeners: StorageSelectionChangesListener[] = [];\n\n /**\n * Registers a Listener to be executed whenever this event is raised\n * @param listener The function to be executed when the event is raised\n * @returns A function that will remove this event listener\n * @beta\n */\n public addListener(listener: StorageSelectionChangesListener): () => void {\n this._listeners.push(listener);\n return () => this.removeListener(listener);\n }\n\n /**\n * Un-register a previously registered listener\n * @param listener The listener to be unregistered\n * @beta\n */\n public removeListener(listener: StorageSelectionChangesListener): void {\n this._listeners = this._listeners.filter((x) => x !== listener);\n }\n\n /**\n * Raises the event by calling each registered listener with the supplied arguments\n * @param args Event arguments\n * @param storage Storage that the selection changed in\n * @beta\n */\n public raiseEvent(args: StorageSelectionChangeEventArgs, storage: SelectionStorage) {\n this._listeners.forEach((listener) => listener(args, storage));\n }\n}\n"]}