selective-ui 1.2.1 → 1.2.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.
Files changed (48) hide show
  1. package/dist/selective-ui.css +3 -1
  2. package/dist/selective-ui.css.map +1 -1
  3. package/dist/selective-ui.esm.js +435 -405
  4. package/dist/selective-ui.esm.js.map +1 -1
  5. package/dist/selective-ui.esm.min.js +2 -2
  6. package/dist/selective-ui.esm.min.js.br +0 -0
  7. package/dist/selective-ui.min.css +1 -1
  8. package/dist/selective-ui.min.css.br +0 -0
  9. package/dist/selective-ui.min.js +2 -2
  10. package/dist/selective-ui.min.js.br +0 -0
  11. package/dist/selective-ui.umd.js +436 -406
  12. package/dist/selective-ui.umd.js.map +1 -1
  13. package/package.json +1 -1
  14. package/src/css/components/popup.css +3 -1
  15. package/src/ts/adapter/mixed-adapter.ts +40 -40
  16. package/src/ts/components/accessorybox.ts +49 -21
  17. package/src/ts/components/directive.ts +3 -3
  18. package/src/ts/components/empty-state.ts +7 -7
  19. package/src/ts/components/loading-state.ts +7 -7
  20. package/src/ts/components/option-handle.ts +17 -17
  21. package/src/ts/components/placeholder.ts +12 -12
  22. package/src/ts/components/popup.ts +93 -108
  23. package/src/ts/components/searchbox.ts +14 -14
  24. package/src/ts/components/selectbox.ts +25 -22
  25. package/src/ts/core/base/adapter.ts +12 -12
  26. package/src/ts/core/base/model.ts +12 -13
  27. package/src/ts/core/base/recyclerview.ts +7 -7
  28. package/src/ts/core/base/view.ts +6 -6
  29. package/src/ts/core/base/virtual-recyclerview.ts +50 -50
  30. package/src/ts/core/model-manager.ts +53 -53
  31. package/src/ts/core/search-controller.ts +69 -69
  32. package/src/ts/models/group-model.ts +21 -21
  33. package/src/ts/models/option-model.ts +30 -30
  34. package/src/ts/services/dataset-observer.ts +17 -17
  35. package/src/ts/services/ea-observer.ts +21 -21
  36. package/src/ts/services/effector.ts +25 -25
  37. package/src/ts/services/refresher.ts +1 -1
  38. package/src/ts/services/resize-observer.ts +29 -29
  39. package/src/ts/services/select-observer.ts +29 -29
  40. package/src/ts/types/components/popup.type.ts +15 -0
  41. package/src/ts/types/utils/istorage.type.ts +1 -1
  42. package/src/ts/utils/callback-scheduler.ts +4 -4
  43. package/src/ts/utils/ievents.ts +4 -4
  44. package/src/ts/utils/istorage.ts +5 -5
  45. package/src/ts/utils/libs.ts +38 -29
  46. package/src/ts/utils/selective.ts +11 -11
  47. package/src/ts/views/group-view.ts +7 -7
  48. package/src/ts/views/option-view.ts +51 -51
@@ -5,28 +5,28 @@ import type { GroupViewTags } from "../types/views/view.group.type";
5
5
  import { GroupView } from "../views/group-view";
6
6
  import { OptionModel } from "./option-model";
7
7
  import type { IEventCallback } from "../types/utils/ievents.type";
8
- import { DefaultConfig } from "../types/utils/istorage.type";
8
+ import { SelectiveOptions } from "../types/utils/selective.type";
9
9
 
10
10
  /**
11
11
  * @extends {Model<HTMLOptGroupElement, GroupViewTags, GroupView>}
12
12
  */
13
- export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupView, DefaultConfig> {
14
- label = "";
13
+ export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupView, SelectiveOptions> {
14
+ public label = "";
15
15
 
16
- items: OptionModel[] = [];
16
+ public items: OptionModel[] = [];
17
17
 
18
- collapsed = false;
18
+ public collapsed = false;
19
19
 
20
- private _privOnCollapsedChanged: Array<(evtToken: IEventCallback, model: GroupModel, collapsed: boolean) => void> = [];
20
+ private privOnCollapsedChanged: Array<(evtToken: IEventCallback, model: GroupModel, collapsed: boolean) => void> = [];
21
21
 
22
22
  /**
23
23
  * Initializes a group model with options and an optional <optgroup> target.
24
24
  * Reads the label and collapsed state from the target element's attributes/dataset.
25
25
  *
26
- * @param {DefaultConfig} options - Configuration for the model.
26
+ * @param {SelectiveOptions} options - Configuration for the model.
27
27
  * @param {HTMLOptGroupElement} [targetElement] - The source <optgroup> element.
28
28
  */
29
- constructor(options: DefaultConfig, targetElement?: HTMLOptGroupElement) {
29
+ public constructor(options: SelectiveOptions, targetElement?: HTMLOptGroupElement) {
30
30
  super(options, targetElement ?? null, null);
31
31
 
32
32
  if (targetElement) {
@@ -40,7 +40,7 @@ export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupV
40
40
  *
41
41
  * @type {string[]}
42
42
  */
43
- get value(): string[] {
43
+ public get value(): string[] {
44
44
  return this.items.map((item) => item.value);
45
45
  }
46
46
 
@@ -49,7 +49,7 @@ export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupV
49
49
  *
50
50
  * @type {OptionModel[]}
51
51
  */
52
- get selectedItems(): OptionModel[] {
52
+ public get selectedItems(): OptionModel[] {
53
53
  return this.items.filter((item) => item.selected);
54
54
  }
55
55
 
@@ -58,7 +58,7 @@ export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupV
58
58
  *
59
59
  * @type {OptionModel[]}
60
60
  */
61
- get visibleItems(): OptionModel[] {
61
+ public get visibleItems(): OptionModel[] {
62
62
  return this.items.filter((item) => item.visible);
63
63
  }
64
64
 
@@ -67,7 +67,7 @@ export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupV
67
67
  *
68
68
  * @type {boolean}
69
69
  */
70
- get hasVisibleItems(): boolean {
70
+ public get hasVisibleItems(): boolean {
71
71
  return this.visibleItems.length > 0;
72
72
  }
73
73
 
@@ -76,7 +76,7 @@ export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupV
76
76
  *
77
77
  * @param {HTMLOptGroupElement} targetElement - The updated <optgroup> element.
78
78
  */
79
- update(targetElement: HTMLOptGroupElement): void {
79
+ public update(targetElement: HTMLOptGroupElement): void {
80
80
  this.label = targetElement.label;
81
81
  this.view?.updateLabel(this.label);
82
82
  }
@@ -85,7 +85,7 @@ export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupV
85
85
  * Hook invoked when the target element reference changes.
86
86
  * Updates the view's label and collapsed state to keep UI in sync.
87
87
  */
88
- onTargetChanged(): void {
88
+ public onTargetChanged(): void {
89
89
  if (this.view) {
90
90
  this.view.updateLabel(this.label);
91
91
  this.view.setCollapsed(this.collapsed);
@@ -97,18 +97,18 @@ export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupV
97
97
  *
98
98
  * @param {(evtToken: IEventCallback, model: GroupModel, collapsed: boolean) => void} callback - Listener for collapse changes.
99
99
  */
100
- onCollapsedChanged(callback: (evtToken: IEventCallback, model: GroupModel, collapsed: boolean) => void): void {
101
- this._privOnCollapsedChanged.push(callback);
100
+ public onCollapsedChanged(callback: (evtToken: IEventCallback, model: GroupModel, collapsed: boolean) => void): void {
101
+ this.privOnCollapsedChanged.push(callback);
102
102
  }
103
103
 
104
104
  /**
105
105
  * Toggles the group's collapsed state, updates the view, and notifies registered listeners.
106
106
  */
107
- toggleCollapse(): void {
107
+ public toggleCollapse(): void {
108
108
  this.collapsed = !this.collapsed;
109
109
  this.view?.setCollapsed(this.collapsed);
110
110
 
111
- iEvents.callEvent<[GroupModel, boolean]>([this, this.collapsed], ...this._privOnCollapsedChanged);
111
+ iEvents.callEvent<[GroupModel, boolean]>([this, this.collapsed], ...this.privOnCollapsedChanged);
112
112
  }
113
113
 
114
114
  /**
@@ -116,7 +116,7 @@ export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupV
116
116
  *
117
117
  * @param {OptionModel} optionModel - The option to add.
118
118
  */
119
- addItem(optionModel: OptionModel): void {
119
+ public addItem(optionModel: OptionModel): void {
120
120
  this.items.push(optionModel);
121
121
  optionModel.group = this;
122
122
  }
@@ -126,7 +126,7 @@ export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupV
126
126
  *
127
127
  * @param {OptionModel} optionModel - The option to remove.
128
128
  */
129
- removeItem(optionModel: OptionModel): void {
129
+ public removeItem(optionModel: OptionModel): void {
130
130
  const index = this.items.indexOf(optionModel);
131
131
  if (index > -1) {
132
132
  this.items.splice(index, 1);
@@ -138,7 +138,7 @@ export class GroupModel extends Model<HTMLOptGroupElement, GroupViewTags, GroupV
138
138
  * Updates the group's visibility in the view, typically based on children visibility.
139
139
  * No-ops if the view is not initialized.
140
140
  */
141
- updateVisibility(): void {
141
+ public updateVisibility(): void {
142
142
  this.view?.updateVisibility();
143
143
  }
144
144
  }
@@ -12,17 +12,17 @@ import { SelectiveOptions } from "../types/utils/selective.type";
12
12
  * @extends {Model<HTMLOptionElement, OptionViewTags, OptionView, SelectiveOptions>}
13
13
  */
14
14
  export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, OptionView, SelectiveOptions> {
15
- private _privOnSelected: Array<(evtToken: IEventCallback, el: OptionModel, selected: boolean) => void> = [];
15
+ private privOnSelected: Array<(evtToken: IEventCallback, el: OptionModel, selected: boolean) => void> = [];
16
16
 
17
- private _privOnInternalSelected: Array<(evtToken: IEventCallback, el: OptionModel, selected: boolean) => void> = [];
17
+ private privOnInternalSelected: Array<(evtToken: IEventCallback, el: OptionModel, selected: boolean) => void> = [];
18
18
 
19
- private _privOnVisibilityChanged: Array<(evtToken: IEventCallback, model: OptionModel, visible: boolean) => void> = [];
19
+ private privOnVisibilityChanged: Array<(evtToken: IEventCallback, model: OptionModel, visible: boolean) => void> = [];
20
20
 
21
21
  private _visible = true;
22
22
 
23
23
  private _highlighted = false;
24
24
 
25
- group: GroupModel | null = null;
25
+ public group: GroupModel | null = null;
26
26
 
27
27
  /**
28
28
  * Constructs a Model instance with configuration options and optional bindings to a target element and view.
@@ -32,7 +32,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
32
32
  * @param {HTMLOptionElement|null} [targetElement=null] - The underlying element (e.g., <option> or group node).
33
33
  * @param {OptionView|null} [view=null] - The associated view responsible for rendering the model.
34
34
  */
35
- constructor(options: SelectiveOptions, targetElement: HTMLOptionElement | null = null, view: OptionView | null = null) {
35
+ public constructor(options: SelectiveOptions, targetElement: HTMLOptionElement | null = null, view: OptionView | null = null) {
36
36
  super(options, targetElement, view);
37
37
 
38
38
  (async () => {
@@ -45,7 +45,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
45
45
  *
46
46
  * @type {string}
47
47
  */
48
- get imageSrc(): string {
48
+ public get imageSrc(): string {
49
49
  return this.dataset?.imgsrc || this.dataset?.image || "";
50
50
  }
51
51
 
@@ -54,7 +54,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
54
54
  *
55
55
  * @type {boolean}
56
56
  */
57
- get hasImage(): boolean {
57
+ public get hasImage(): boolean {
58
58
  return !!this.imageSrc;
59
59
  }
60
60
 
@@ -63,7 +63,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
63
63
  *
64
64
  * @type {string}
65
65
  */
66
- get value(): string {
66
+ public get value(): string {
67
67
  return this.targetElement?.value ?? "";
68
68
  }
69
69
 
@@ -72,7 +72,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
72
72
  *
73
73
  * @type {boolean}
74
74
  */
75
- get selected(): boolean {
75
+ public get selected(): boolean {
76
76
  return !!this.targetElement?.selected;
77
77
  }
78
78
 
@@ -82,9 +82,9 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
82
82
  *
83
83
  * @type {boolean}
84
84
  */
85
- set selected(value: boolean) {
85
+ public set selected(value: boolean) {
86
86
  this.selectedNonTrigger = value;
87
- iEvents.callEvent<[OptionModel, boolean]>([this, value], ...this._privOnSelected);
87
+ iEvents.callEvent<[OptionModel, boolean]>([this, value], ...this.privOnSelected);
88
88
  }
89
89
 
90
90
  /**
@@ -92,7 +92,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
92
92
  *
93
93
  * @type {boolean}
94
94
  */
95
- get visible(): boolean {
95
+ public get visible(): boolean {
96
96
  return this._visible;
97
97
  }
98
98
 
@@ -101,14 +101,14 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
101
101
  *
102
102
  * @type {boolean}
103
103
  */
104
- set visible(value: boolean) {
104
+ public set visible(value: boolean) {
105
105
  if (this._visible === value) return;
106
106
  this._visible = value;
107
107
 
108
108
  const viewEl = this.view?.getView?.();
109
109
  if (viewEl) viewEl.classList.toggle("hide", !value);
110
110
 
111
- iEvents.callEvent<[OptionModel, boolean]>([this, value], ...this._privOnVisibilityChanged);
111
+ iEvents.callEvent<[OptionModel, boolean]>([this, value], ...this.privOnVisibilityChanged);
112
112
  }
113
113
 
114
114
  /**
@@ -116,7 +116,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
116
116
  *
117
117
  * @type {boolean}
118
118
  */
119
- get selectedNonTrigger(): boolean {
119
+ public get selectedNonTrigger(): boolean {
120
120
  return this.selected;
121
121
  }
122
122
 
@@ -126,7 +126,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
126
126
  *
127
127
  * @type {boolean}
128
128
  */
129
- set selectedNonTrigger(value: boolean) {
129
+ public set selectedNonTrigger(value: boolean) {
130
130
  const input = this.view?.view?.tags?.OptionInput;
131
131
  const viewEl = this.view?.getView?.();
132
132
 
@@ -140,7 +140,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
140
140
 
141
141
  if (this.targetElement) this.targetElement.selected = value;
142
142
 
143
- iEvents.callEvent<[OptionModel, boolean]>([this, value], ...this._privOnInternalSelected);
143
+ iEvents.callEvent<[OptionModel, boolean]>([this, value], ...this.privOnInternalSelected);
144
144
  }
145
145
 
146
146
  /**
@@ -149,7 +149,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
149
149
  *
150
150
  * @type {string}
151
151
  */
152
- get text(): string {
152
+ public get text(): string {
153
153
  const raw = this.dataset?.mask ?? this.targetElement?.text ?? "";
154
154
  const translated = Libs.tagTranslate(raw);
155
155
  return this.options.allowHtml ? translated : Libs.stripHtml(translated);
@@ -161,18 +161,18 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
161
161
  *
162
162
  * @type {string}
163
163
  */
164
- get textContent(): string {
164
+ public get textContent(): string {
165
165
  return this.options.allowHtml ? Libs.stripHtml(this.text).trim() : this.text.trim();
166
166
  }
167
167
 
168
- textToFind: string;
168
+ public textToFind: string;
169
169
 
170
170
  /**
171
171
  * Returns the dataset object of the underlying <option> element, or an empty object.
172
172
  *
173
173
  * @type {DOMStringMap|Record<string, string>}
174
174
  */
175
- get dataset(): DOMStringMap {
175
+ public get dataset(): DOMStringMap {
176
176
  return this.targetElement?.dataset ?? ({} as DOMStringMap);
177
177
  }
178
178
 
@@ -181,7 +181,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
181
181
  *
182
182
  * @type {boolean}
183
183
  */
184
- get highlighted(): boolean {
184
+ public get highlighted(): boolean {
185
185
  return this._highlighted;
186
186
  }
187
187
 
@@ -191,7 +191,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
191
191
  *
192
192
  * @type {boolean}
193
193
  */
194
- set highlighted(value: boolean) {
194
+ public set highlighted(value: boolean) {
195
195
  const val = !!value;
196
196
  const viewEl = this.view?.getView?.();
197
197
 
@@ -204,8 +204,8 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
204
204
  *
205
205
  * @param {(evtToken: IEventCallback, el: OptionModel, selected: boolean) => void} callback - Selection listener.
206
206
  */
207
- onSelected(callback: (evtToken: IEventCallback, el: OptionModel, selected: boolean) => void): void {
208
- this._privOnSelected.push(callback);
207
+ public onSelected(callback: (evtToken: IEventCallback, el: OptionModel, selected: boolean) => void): void {
208
+ this.privOnSelected.push(callback);
209
209
  }
210
210
 
211
211
  /**
@@ -213,8 +213,8 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
213
213
  *
214
214
  * @param {(evtToken: IEventCallback, el: OptionModel, selected: boolean) => void} callback - Internal selection listener.
215
215
  */
216
- onInternalSelected(callback: (evtToken: IEventCallback, el: OptionModel, selected: boolean) => void): void {
217
- this._privOnInternalSelected.push(callback);
216
+ public onInternalSelected(callback: (evtToken: IEventCallback, el: OptionModel, selected: boolean) => void): void {
217
+ this.privOnInternalSelected.push(callback);
218
218
  }
219
219
 
220
220
  /**
@@ -222,8 +222,8 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
222
222
  *
223
223
  * @param {(evtToken: IEventCallback, model: OptionModel, visible: boolean) => void} callback - Visibility listener.
224
224
  */
225
- onVisibilityChanged(callback: (evtToken: IEventCallback, model: OptionModel, visible: boolean) => void): void {
226
- this._privOnVisibilityChanged.push(callback);
225
+ public onVisibilityChanged(callback: (evtToken: IEventCallback, model: OptionModel, visible: boolean) => void): void {
226
+ this.privOnVisibilityChanged.push(callback);
227
227
  }
228
228
 
229
229
  /**
@@ -231,7 +231,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
231
231
  * Updates label content (HTML or text), image src/alt if present,
232
232
  * and synchronizes initial selected state to the view.
233
233
  */
234
- onTargetChanged(): void {
234
+ public onTargetChanged(): void {
235
235
  this.textToFind = Libs.string2normalize(this.textContent.toLowerCase());
236
236
  if (!this.view) return;
237
237
 
@@ -2,11 +2,11 @@
2
2
  * @class
3
3
  */
4
4
  export class DatasetObserver {
5
- private _observer: MutationObserver;
5
+ private observer: MutationObserver;
6
6
 
7
- private _element: HTMLElement;
7
+ private element: HTMLElement;
8
8
 
9
- private _debounceTimer: ReturnType<typeof setTimeout> | null = null;
9
+ private debounceTimer: ReturnType<typeof setTimeout> | null = null;
10
10
 
11
11
  /**
12
12
  * Observes data-* attribute changes on a target element and debounces notifications.
@@ -14,10 +14,10 @@ export class DatasetObserver {
14
14
  *
15
15
  * @param {HTMLElement} element - The element whose dataset (data-* attributes) will be observed.
16
16
  */
17
- constructor(element: HTMLElement) {
18
- this._element = element;
17
+ public constructor(element: HTMLElement) {
18
+ this.element = element;
19
19
 
20
- this._observer = new MutationObserver((mutations: MutationRecord[]) => {
20
+ this.observer = new MutationObserver((mutations: MutationRecord[]) => {
21
21
  let datasetChanged = false;
22
22
 
23
23
  for (const mutation of mutations) {
@@ -29,14 +29,14 @@ export class DatasetObserver {
29
29
 
30
30
  if (!datasetChanged) return;
31
31
 
32
- if (this._debounceTimer) clearTimeout(this._debounceTimer);
33
- this._debounceTimer = setTimeout(() => {
34
- this.onChanged({ ...this._element.dataset });
32
+ if (this.debounceTimer) clearTimeout(this.debounceTimer);
33
+ this.debounceTimer = setTimeout(() => {
34
+ this.onChanged({ ...this.element.dataset });
35
35
  }, 50);
36
36
  });
37
37
 
38
38
  element.addEventListener("dataset:changed", () => {
39
- this.onChanged({ ...this._element.dataset });
39
+ this.onChanged({ ...this.element.dataset });
40
40
  });
41
41
  }
42
42
 
@@ -44,8 +44,8 @@ export class DatasetObserver {
44
44
  * Starts observing the element for attribute changes, including old values.
45
45
  * Uses MutationObserver to track updates to data-* attributes.
46
46
  */
47
- connect(): void {
48
- this._observer.observe(this._element, {
47
+ public connect(): void {
48
+ this.observer.observe(this.element, {
49
49
  attributes: true,
50
50
  attributeOldValue: true,
51
51
  });
@@ -58,16 +58,16 @@ export class DatasetObserver {
58
58
  * @param {Record<string, string>} dataset - A shallow copy of the element's current dataset.
59
59
  */
60
60
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
61
- onChanged(dataset: Record<string, string>): void {
61
+ public onChanged(dataset: Record<string, string>): void {
62
62
  // override
63
63
  }
64
64
 
65
65
  /**
66
66
  * Stops observing the element and clears any pending debounce timers.
67
67
  */
68
- disconnect(): void {
69
- if (this._debounceTimer) clearTimeout(this._debounceTimer);
70
- this._debounceTimer = null;
71
- this._observer.disconnect();
68
+ public disconnect(): void {
69
+ if (this.debounceTimer) clearTimeout(this.debounceTimer);
70
+ this.debounceTimer = null;
71
+ this.observer.disconnect();
72
72
  }
73
73
  }
@@ -2,26 +2,26 @@
2
2
  * @class
3
3
  */
4
4
  export class ElementAdditionObserver<T extends Element = Element> {
5
- private _isActive = false;
5
+ private isActive = false;
6
6
 
7
- private _observer: MutationObserver | null = null;
7
+ private observer: MutationObserver | null = null;
8
8
 
9
- private _actions: Array<(el: T) => void> = [];
9
+ private actions: Array<(el: T) => void> = [];
10
10
 
11
11
  /**
12
12
  * Registers a callback to be invoked whenever a matching element is detected being added to the DOM.
13
13
  *
14
14
  * @param {(el: T) => void} action - Function executed with the newly added element.
15
15
  */
16
- onDetect(action: (el: T) => void): void {
17
- this._actions.push(action);
16
+ public onDetect(action: (el: T) => void): void {
17
+ this.actions.push(action);
18
18
  }
19
19
 
20
20
  /**
21
21
  * Clears all previously registered detection callbacks.
22
22
  */
23
- clearDetect(): void {
24
- this._actions = [];
23
+ public clearDetect(): void {
24
+ this.actions = [];
25
25
  }
26
26
 
27
27
  /**
@@ -30,15 +30,15 @@ export class ElementAdditionObserver<T extends Element = Element> {
30
30
  *
31
31
  * @param {string} tag - The tag name to watch for (e.g., "select", "div").
32
32
  */
33
- start(tag: string): void {
34
- if (this._isActive) return;
33
+ public start(tag: string): void {
34
+ if (this.isActive) return;
35
35
 
36
- this._isActive = true;
36
+ this.isActive = true;
37
37
 
38
38
  const upperTag = tag.toUpperCase();
39
39
  const lowerTag = tag.toLowerCase();
40
40
 
41
- this._observer = new MutationObserver((mutations: MutationRecord[]) => {
41
+ this.observer = new MutationObserver((mutations: MutationRecord[]) => {
42
42
  for (const mutation of mutations) {
43
43
  mutation.addedNodes.forEach((node) => {
44
44
  if (node.nodeType !== 1) return;
@@ -46,16 +46,16 @@ export class ElementAdditionObserver<T extends Element = Element> {
46
46
  const subnode = node as HTMLElement;
47
47
 
48
48
  if (subnode.tagName === upperTag) {
49
- this._handle(subnode as unknown as T);
49
+ this.handle(subnode as unknown as T);
50
50
  }
51
51
 
52
52
  const matches = subnode.querySelectorAll(lowerTag);
53
- matches.forEach((el) => this._handle(el as unknown as T));
53
+ matches.forEach((el) => this.handle(el as unknown as T));
54
54
  });
55
55
  }
56
56
  });
57
57
 
58
- this._observer.observe(document.body, {
58
+ this.observer.observe(document.body, {
59
59
  childList: true,
60
60
  subtree: true,
61
61
  });
@@ -65,12 +65,12 @@ export class ElementAdditionObserver<T extends Element = Element> {
65
65
  * Stops observing for element additions and releases internal resources.
66
66
  * No-ops if the observer is not active.
67
67
  */
68
- stop(): void {
69
- if (!this._isActive) return;
68
+ public stop(): void {
69
+ if (!this.isActive) return;
70
70
 
71
- this._isActive = false;
72
- this._observer?.disconnect();
73
- this._observer = null;
71
+ this.isActive = false;
72
+ this.observer?.disconnect();
73
+ this.observer = null;
74
74
  }
75
75
 
76
76
  /**
@@ -78,7 +78,7 @@ export class ElementAdditionObserver<T extends Element = Element> {
78
78
  *
79
79
  * @param {T} element - The element that was detected as added to the DOM.
80
80
  */
81
- private _handle(element: T): void {
82
- this._actions.forEach((action) => action(element));
81
+ private handle(element: T): void {
82
+ this.actions.forEach((action) => action(element));
83
83
  }
84
84
  }