selective-ui 1.2.5 → 1.2.6
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/README.md +7 -0
- package/dist/selective-ui.css +64 -58
- package/dist/selective-ui.css.map +1 -1
- package/dist/selective-ui.esm.js +240 -125
- package/dist/selective-ui.esm.js.map +1 -1
- package/dist/selective-ui.esm.min.js +2 -2
- package/dist/selective-ui.esm.min.js.br +0 -0
- package/dist/selective-ui.min.css +1 -1
- package/dist/selective-ui.min.css.br +0 -0
- package/dist/selective-ui.min.js +2 -2
- package/dist/selective-ui.min.js.br +0 -0
- package/dist/selective-ui.umd.js +245 -126
- package/dist/selective-ui.umd.js.map +1 -1
- package/package.json +3 -3
- package/src/css/components/accessorybox.css +1 -1
- package/src/css/components/directive.css +2 -2
- package/src/css/components/option-handle.css +4 -4
- package/src/css/components/placeholder.css +1 -1
- package/src/css/components/popup/empty-state.css +3 -3
- package/src/css/components/popup/loading-state.css +3 -3
- package/src/css/components/popup/popup.css +5 -5
- package/src/css/components/searchbox.css +2 -2
- package/src/css/components/selectbox.css +7 -7
- package/src/css/views/group-view.css +8 -8
- package/src/css/views/option-view.css +22 -22
- package/src/ts/adapter/mixed-adapter.ts +1 -1
- package/src/ts/components/accessorybox.ts +9 -9
- package/src/ts/components/directive.ts +2 -2
- package/src/ts/components/option-handle.ts +9 -9
- package/src/ts/components/placeholder.ts +5 -5
- package/src/ts/components/popup/empty-state.ts +4 -4
- package/src/ts/components/popup/loading-state.ts +4 -4
- package/src/ts/components/popup/popup.ts +19 -38
- package/src/ts/components/searchbox.ts +6 -6
- package/src/ts/components/selectbox.ts +93 -11
- package/src/ts/core/base/adapter.ts +2 -2
- package/src/ts/core/base/virtual-recyclerview.ts +6 -6
- package/src/ts/core/model-manager.ts +10 -11
- package/src/ts/core/search-controller.ts +2 -2
- package/src/ts/global.ts +26 -5
- package/src/ts/index.ts +22 -3
- package/src/ts/models/option-model.ts +13 -5
- package/src/ts/services/refresher.ts +2 -1
- package/src/ts/services/resize-observer.ts +4 -4
- package/src/ts/types/core/base/view.type.ts +3 -3
- package/src/ts/types/core/base/virtual-recyclerview.type.ts +1 -1
- package/src/ts/types/plugins/plugin.type.ts +46 -0
- package/src/ts/types/utils/istorage.type.ts +8 -4
- package/src/ts/types/utils/libs.type.ts +2 -2
- package/src/ts/types/utils/selective.type.ts +14 -1
- package/src/ts/utils/callback-scheduler.ts +4 -4
- package/src/ts/utils/libs.ts +41 -65
- package/src/ts/utils/selective.ts +85 -21
- package/src/ts/views/group-view.ts +6 -6
- package/src/ts/views/option-view.ts +11 -11
|
@@ -229,7 +229,9 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
|
|
|
229
229
|
const input = this.view?.view?.tags?.OptionInput;
|
|
230
230
|
const viewEl = this.view?.getView?.();
|
|
231
231
|
|
|
232
|
-
if (input)
|
|
232
|
+
if (input) {
|
|
233
|
+
input.checked = value;
|
|
234
|
+
}
|
|
233
235
|
|
|
234
236
|
if (viewEl && this.targetElement) {
|
|
235
237
|
viewEl.classList.toggle("checked", !!value);
|
|
@@ -237,7 +239,9 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
|
|
|
237
239
|
this.targetElement.toggleAttribute("selected", !!value);
|
|
238
240
|
}
|
|
239
241
|
|
|
240
|
-
if (this.targetElement)
|
|
242
|
+
if (this.targetElement) {
|
|
243
|
+
this.targetElement.selected = value;
|
|
244
|
+
}
|
|
241
245
|
|
|
242
246
|
iEvents.callEvent<[OptionModel, boolean]>([this, value], ...this.privOnInternalSelected);
|
|
243
247
|
}
|
|
@@ -284,7 +288,7 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
|
|
|
284
288
|
* @returns {DOMStringMap}
|
|
285
289
|
*/
|
|
286
290
|
public get dataset(): DOMStringMap {
|
|
287
|
-
return this.targetElement?.dataset ??
|
|
291
|
+
return this.targetElement?.dataset ?? {};
|
|
288
292
|
}
|
|
289
293
|
|
|
290
294
|
/**
|
|
@@ -377,8 +381,12 @@ export class OptionModel extends Model<HTMLOptionElement, OptionViewTags, Option
|
|
|
377
381
|
|
|
378
382
|
const imageTag = this.view.view.tags.OptionImage;
|
|
379
383
|
if (imageTag && this.hasImage) {
|
|
380
|
-
(imageTag
|
|
381
|
-
|
|
384
|
+
if (imageTag.src != this.imageSrc) {
|
|
385
|
+
imageTag.src = this.imageSrc;
|
|
386
|
+
}
|
|
387
|
+
if (imageTag.alt != this.text) {
|
|
388
|
+
imageTag.alt = this.text;
|
|
389
|
+
}
|
|
382
390
|
}
|
|
383
391
|
|
|
384
392
|
if (this.targetElement) this.selectedNonTrigger = this.targetElement.selected;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BinderMap } from "../types/utils/istorage.type";
|
|
1
2
|
import { Libs } from "../utils/libs";
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -37,7 +38,7 @@ export class Refresher {
|
|
|
37
38
|
* @param view - View panel element whose inline styles will be updated.
|
|
38
39
|
*/
|
|
39
40
|
public static resizeBox(select: HTMLSelectElement, view: HTMLElement): void {
|
|
40
|
-
const bindedMap = Libs.getBinderMap(select);
|
|
41
|
+
const bindedMap = Libs.getBinderMap<BinderMap>(select);
|
|
41
42
|
if (!bindedMap?.options) return;
|
|
42
43
|
|
|
43
44
|
const options = bindedMap.options;
|
|
@@ -63,7 +63,7 @@ export class ResizeObserverService {
|
|
|
63
63
|
* @remarks
|
|
64
64
|
* Set by {@link connect} and cleared by {@link disconnect}.
|
|
65
65
|
*/
|
|
66
|
-
public element:
|
|
66
|
+
public element: HTMLElement | null = null;
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
69
|
* Underlying `ResizeObserver` instance.
|
|
@@ -132,7 +132,7 @@ export class ResizeObserverService {
|
|
|
132
132
|
* This method is the single funnel for all observation signals (internal + external).
|
|
133
133
|
*/
|
|
134
134
|
private updateChanged(): void {
|
|
135
|
-
const el = this.element
|
|
135
|
+
const el = this.element;
|
|
136
136
|
|
|
137
137
|
if (!el || typeof el.getBoundingClientRect !== "function") {
|
|
138
138
|
const defaultMetrics: ElementMetrics = {
|
|
@@ -213,8 +213,8 @@ export class ResizeObserverService {
|
|
|
213
213
|
* @remarks
|
|
214
214
|
* Not idempotent. Call {@link disconnect} before calling `connect()` again to avoid duplicates.
|
|
215
215
|
*/
|
|
216
|
-
public connect(element:
|
|
217
|
-
if (!(element instanceof
|
|
216
|
+
public connect(element: HTMLElement): void {
|
|
217
|
+
if (!(element instanceof HTMLElement)) {
|
|
218
218
|
throw new Error("Invalid element");
|
|
219
219
|
}
|
|
220
220
|
|
|
@@ -3,7 +3,7 @@ import { Lifecycle } from "src/ts/core/base/lifecycle";
|
|
|
3
3
|
import { MountViewResult } from "../../utils/libs.type";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Contract definition for a UI View created via `
|
|
6
|
+
* Contract definition for a UI View created via `mountNode`.
|
|
7
7
|
*
|
|
8
8
|
* A View encapsulates:
|
|
9
9
|
* - The mounted DOM structure
|
|
@@ -32,7 +32,7 @@ export interface ViewContract<TTags extends Record<string, HTMLElement>> extends
|
|
|
32
32
|
parent: HTMLElement | null;
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
* Internal representation of the mounted view returned by `
|
|
35
|
+
* Internal representation of the mounted view returned by `mountNode`.
|
|
36
36
|
*
|
|
37
37
|
* Contains:
|
|
38
38
|
* - The root element of the view
|
|
@@ -46,7 +46,7 @@ export interface ViewContract<TTags extends Record<string, HTMLElement>> extends
|
|
|
46
46
|
* Returns the root HTMLElement of the mounted view.
|
|
47
47
|
*
|
|
48
48
|
* This is typically the top-level container element
|
|
49
|
-
* created by `
|
|
49
|
+
* created by `mountNode`.
|
|
50
50
|
*
|
|
51
51
|
* @returns The root HTMLElement of the view.
|
|
52
52
|
* @throws {Error} If the view has not been mounted or initialized.
|
|
@@ -42,7 +42,7 @@ export type VirtualOptions = {
|
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Tag map for the virtual recycler view DOM structure.
|
|
45
|
-
* These nodes are typically produced by `
|
|
45
|
+
* These nodes are typically produced by `mountNode` and used to
|
|
46
46
|
* manipulate padding and host the rendered item elements.
|
|
47
47
|
*/
|
|
48
48
|
export type VirtualRecyclerViewTags = {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { SelectBox } from "../../components/selectbox";
|
|
2
|
+
import { SelectBoxAction, SelectBoxTags } from "../components/searchbox.type";
|
|
3
|
+
import { AdapterContract } from "../core/base/adapter.type";
|
|
4
|
+
import { RecyclerViewContract } from "../core/base/recyclerview.type";
|
|
5
|
+
import { SelectiveOptions } from "../utils/selective.type";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Runtime context passed to plugin hooks.
|
|
9
|
+
*/
|
|
10
|
+
export interface PluginContext<TTags extends Record<string, HTMLElement>> {
|
|
11
|
+
selectBox: SelectBox;
|
|
12
|
+
options: SelectiveOptions;
|
|
13
|
+
adapter: AdapterContract<any> | null;
|
|
14
|
+
recycler: RecyclerViewContract<AdapterContract<any>> | null;
|
|
15
|
+
viewTags: TTags & { id: string };
|
|
16
|
+
actions: SelectBoxAction;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Plugin contract for extending Selective lifecycle behavior.
|
|
21
|
+
*/
|
|
22
|
+
export interface SelectivePlugin {
|
|
23
|
+
/** Unique plugin identifier. */
|
|
24
|
+
id: string;
|
|
25
|
+
|
|
26
|
+
/** Initialization hook invoked during plugin setup. */
|
|
27
|
+
init?(context?: PluginContext<SelectBoxTags>): void;
|
|
28
|
+
|
|
29
|
+
/** Teardown hook invoked when plugin is destroyed. */
|
|
30
|
+
destroy?(context?: PluginContext<SelectBoxTags>): void;
|
|
31
|
+
|
|
32
|
+
/** Alias for destroy hook, invoked during global teardown. */
|
|
33
|
+
onDestroy?(context?: PluginContext<SelectBoxTags>): void;
|
|
34
|
+
|
|
35
|
+
/** Hook invoked when a SelectBox is bound. */
|
|
36
|
+
onBind?(context?: PluginContext<SelectBoxTags>): void;
|
|
37
|
+
|
|
38
|
+
/** Hook invoked when a SelectBox is opened. */
|
|
39
|
+
onOpen?(context?: PluginContext<SelectBoxTags>): void;
|
|
40
|
+
|
|
41
|
+
/** Hook invoked when a SelectBox is closed. */
|
|
42
|
+
onClose?(context?: PluginContext<SelectBoxTags>): void;
|
|
43
|
+
|
|
44
|
+
/** Hook invoked when selection changes. */
|
|
45
|
+
onChange?(context?: PluginContext<SelectBoxTags>, ...args: unknown[]): void;
|
|
46
|
+
}
|
|
@@ -70,11 +70,15 @@ export interface DefaultConfig {
|
|
|
70
70
|
* Represents a binding map for component initialization.
|
|
71
71
|
* Includes options, container reference, and lifecycle actions.
|
|
72
72
|
*/
|
|
73
|
-
export type BinderMap
|
|
73
|
+
export type BinderMap<
|
|
74
|
+
TContainer extends any = any,
|
|
75
|
+
TAction extends Record<string, any> = Record<string, any>,
|
|
76
|
+
TSelf extends { deInit?: () => void } & Record<string, any> = { deInit?: () => void } & Record<string, any>
|
|
77
|
+
> = {
|
|
74
78
|
options: SelectiveOptions; // Component options
|
|
75
|
-
container?:
|
|
76
|
-
action?:
|
|
77
|
-
self?:
|
|
79
|
+
container?: TContainer; // Reference to the container element
|
|
80
|
+
action?: TAction; // Action handlers or methods
|
|
81
|
+
self?: TSelf; // Self-reference with optional cleanup
|
|
78
82
|
};
|
|
79
83
|
|
|
80
84
|
/**
|
|
@@ -20,11 +20,11 @@ export type NodeSpec = {
|
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Generic mount result shape used across views.
|
|
23
|
-
* Returned by
|
|
23
|
+
* Returned by mountNode utilities.
|
|
24
24
|
*
|
|
25
25
|
* @template TTags - A map of tag names to their corresponding HTMLElement instances.
|
|
26
26
|
*/
|
|
27
|
-
export type MountViewResult<TTags extends Record<string, HTMLElement>> = {
|
|
27
|
+
export type MountViewResult<TTags extends Record<string, HTMLElement> = Record<string, HTMLElement>> = {
|
|
28
28
|
view: HTMLElement | null; // Root element of the mounted view
|
|
29
29
|
tags: TTags & { id: string }; // Tag map with an additional unique ID
|
|
30
30
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { EffectorInterface } from "../services/effector.type";
|
|
2
2
|
import { DefaultConfig } from "./istorage.type";
|
|
3
|
+
import type { SelectivePlugin } from "../plugins/plugin.type";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Represents configuration options for the Selective component.
|
|
@@ -56,6 +57,18 @@ export interface SelectiveUIGlobal {
|
|
|
56
57
|
*/
|
|
57
58
|
effector(element: string | HTMLElement): EffectorInterface;
|
|
58
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Register a Selective plugin implementation.
|
|
62
|
+
* @param plugin - Plugin instance to register.
|
|
63
|
+
*/
|
|
64
|
+
registerPlugin(plugin: SelectivePlugin): void;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Unregister a Selective plugin implementation by id.
|
|
68
|
+
* @param id - Plugin id to remove.
|
|
69
|
+
*/
|
|
70
|
+
unregisterPlugin(id: string): void;
|
|
71
|
+
|
|
59
72
|
/**
|
|
60
73
|
* Current version of the library.
|
|
61
74
|
*/
|
|
@@ -65,4 +78,4 @@ export interface SelectiveUIGlobal {
|
|
|
65
78
|
* Current version of the library.
|
|
66
79
|
*/
|
|
67
80
|
name: string;
|
|
68
|
-
}
|
|
81
|
+
}
|
|
@@ -150,12 +150,12 @@ export class CallbackScheduler {
|
|
|
150
150
|
* @public
|
|
151
151
|
* @param {TimerKey} key - Key whose callbacks will be scheduled.
|
|
152
152
|
* @param {...any[]} params - Parameters passed as a shared payload to all callbacks.
|
|
153
|
-
* @returns {Promise<void>
|
|
153
|
+
* @returns {Promise<void>} Promise resolving when all callbacks finish execution.
|
|
154
154
|
*/
|
|
155
|
-
public run(key: TimerKey, ...params: any[]):
|
|
155
|
+
public run<T extends Promise<void>>(key: TimerKey, ...params: any[]): T {
|
|
156
156
|
const executes = this.executeStored.get(key);
|
|
157
157
|
if (!executes || executes.length === 0) {
|
|
158
|
-
return Promise.resolve();
|
|
158
|
+
return Promise.resolve() as T;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
if (!this.timerRunner.has(key)) {
|
|
@@ -201,7 +201,7 @@ export class CallbackScheduler {
|
|
|
201
201
|
tasks.push(task);
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
return Promise.all(tasks).then(() => void 0);
|
|
204
|
+
return Promise.all(tasks).then(() => void 0) as T;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
/**
|
package/src/ts/utils/libs.ts
CHANGED
|
@@ -61,65 +61,65 @@ export class Libs {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
|
-
* Resolves a selector, NodeList, or single
|
|
64
|
+
* Resolves a selector, NodeList, or single HTMLElement into an array of elements.
|
|
65
65
|
* Returns an empty array if nothing is found.
|
|
66
66
|
*
|
|
67
|
-
* @param {string|NodeListOf<
|
|
68
|
-
* @returns {
|
|
67
|
+
* @param {string|NodeListOf<HTMLElement>|HTMLElement|HTMLElement|ArrayLike<HTMLElement>|null} queryCommon - CSS selector, NodeList, or HTMLElement.
|
|
68
|
+
* @returns {HTMLElement[]} - Array of matched elements (empty if none).
|
|
69
69
|
*/
|
|
70
|
-
public static getElements(
|
|
70
|
+
public static getElements<T extends HTMLElement[]>(
|
|
71
71
|
queryCommon:
|
|
72
72
|
| string
|
|
73
|
-
| NodeListOf<
|
|
73
|
+
| NodeListOf<HTMLElement>
|
|
74
74
|
| Element
|
|
75
75
|
| HTMLElement
|
|
76
|
-
| ArrayLike<
|
|
76
|
+
| ArrayLike<HTMLElement>
|
|
77
77
|
| null
|
|
78
78
|
| undefined
|
|
79
|
-
):
|
|
80
|
-
if (!queryCommon) return [];
|
|
79
|
+
): T {
|
|
80
|
+
if (!queryCommon) return [] as T;
|
|
81
81
|
|
|
82
82
|
if (typeof queryCommon === "string") {
|
|
83
|
-
const nodeList = document.querySelectorAll(queryCommon);
|
|
84
|
-
return Array.from(nodeList);
|
|
83
|
+
const nodeList = document.querySelectorAll<HTMLElement>(queryCommon);
|
|
84
|
+
return Array.from(nodeList) as T;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
if (queryCommon instanceof
|
|
88
|
-
return [queryCommon];
|
|
87
|
+
if (queryCommon instanceof HTMLElement) {
|
|
88
|
+
return [queryCommon] as T;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
// NodeList or array-like
|
|
92
92
|
if (queryCommon instanceof NodeList || Array.isArray(queryCommon)) {
|
|
93
|
-
return Array.from(queryCommon);
|
|
93
|
+
return Array.from(queryCommon) as T;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
return [];
|
|
96
|
+
return [] as T;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
|
-
* Creates a new
|
|
100
|
+
* Creates a new HTMLElement based on a NodeSpec and applies attributes, classes, styles, dataset, and events.
|
|
101
101
|
*
|
|
102
102
|
* @param {NodeSpec} data - Specification describing the element to create.
|
|
103
|
-
* @returns {
|
|
103
|
+
* @returns {HTMLElement} - The created element.
|
|
104
104
|
*/
|
|
105
|
-
public static nodeCreator(data: Partial<NodeSpec> = {}):
|
|
105
|
+
public static nodeCreator<T extends HTMLElement>(data: Partial<NodeSpec> = {}): T {
|
|
106
106
|
const nodeName = (data.node ?? "div") as string;
|
|
107
|
-
return this.nodeCloner(document.createElement(nodeName), data as NodeSpec, true);
|
|
107
|
+
return this.nodeCloner<T>(document.createElement(nodeName), data as NodeSpec, true);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
/**
|
|
111
|
-
* Clones an element (or converts a Node to
|
|
111
|
+
* Clones an element (or converts a Node to HTMLElement) and applies NodeSpec options.
|
|
112
112
|
* When systemNodeCreate=true, uses the provided node as-is.
|
|
113
113
|
*
|
|
114
|
-
* @param {
|
|
114
|
+
* @param {HTMLElement} node - The element to clone or use.
|
|
115
115
|
* @param {NodeSpec|null} _nodeOption - Options (classList, style, dataset, event, other props).
|
|
116
116
|
* @param {boolean} systemNodeCreate - If true, do not clone; use original node.
|
|
117
|
-
* @returns {
|
|
117
|
+
* @returns {HTMLElement} - The processed element.
|
|
118
118
|
*/
|
|
119
|
-
public static nodeCloner(node:
|
|
119
|
+
public static nodeCloner<T extends HTMLElement>(node: HTMLElement = document.documentElement, _nodeOption: NodeSpec | null = null, systemNodeCreate = false): T {
|
|
120
120
|
const nodeOption: Record<string, unknown> = { ...(_nodeOption ?? {}) };
|
|
121
121
|
|
|
122
|
-
const element_creation:
|
|
122
|
+
const element_creation: T = systemNodeCreate ? node as T : node.cloneNode(true) as T;
|
|
123
123
|
|
|
124
124
|
const classList = nodeOption.classList;
|
|
125
125
|
if (typeof classList === "string") {
|
|
@@ -184,55 +184,31 @@ export class Libs {
|
|
|
184
184
|
return element_creation;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
/**
|
|
188
|
-
* Ensures the given Node is an Element; throws if not.
|
|
189
|
-
*
|
|
190
|
-
* @param {Node} node - The node to validate.
|
|
191
|
-
* @returns {Element} - The element cast.
|
|
192
|
-
* @throws {TypeError} - If node is not an Element.
|
|
193
|
-
*/
|
|
194
|
-
public static nodeToElement(node: Node): Element {
|
|
195
|
-
if (node instanceof Element) return node;
|
|
196
|
-
throw new TypeError("Node is not an Element");
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Mounts a view from a plain object specification and returns a typed result
|
|
201
|
-
* containing the root element and a tag map.
|
|
202
|
-
*
|
|
203
|
-
* @template TTags
|
|
204
|
-
* @param {object} rawObj - The specification describing elements and tags.
|
|
205
|
-
* @returns {MountViewResult<TTags>} - The mounted view and its tag references.
|
|
206
|
-
*/
|
|
207
|
-
public static mountView<TTags extends Record<string, any>>(rawObj: Record<string, any>): MountViewResult<TTags> {
|
|
208
|
-
return this.mountNode<TTags>(rawObj) as MountViewResult<TTags>;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
187
|
/**
|
|
212
188
|
* Recursively builds DOM nodes from a specification object, appends/prepends them
|
|
213
189
|
* to an optional parent, and returns either a tag map or a full MountViewResult.
|
|
214
190
|
*
|
|
215
191
|
* @template TTags
|
|
216
192
|
* @param {Object<string, any>} rawObj - Node spec (keys -> { tag, child }).
|
|
217
|
-
* @param {
|
|
193
|
+
* @param {HTMLElement|null} [parentE=null] - Parent to attach into; if null, returns root.
|
|
218
194
|
* @param {boolean} [isPrepend=false] - If true, prepend; otherwise append.
|
|
219
195
|
* @param {boolean} [isRecusive=false] - Internal flag for recursion control.
|
|
220
196
|
* @param {TTags|Object} [recursiveTemp={}] - Accumulator for tag references.
|
|
221
|
-
* @returns {
|
|
197
|
+
* @returns {TTags} - Tag map or the final mount result.
|
|
222
198
|
*/
|
|
223
199
|
public static mountNode<TTags extends Record<string, any>>(
|
|
224
200
|
rawObj: Record<string, any>,
|
|
225
|
-
parentE:
|
|
201
|
+
parentE: HTMLElement | null = null,
|
|
226
202
|
isPrepend = false,
|
|
227
203
|
isRecusive = false,
|
|
228
204
|
recursiveTemp: any = {}
|
|
229
|
-
):
|
|
230
|
-
let view:
|
|
205
|
+
): TTags {
|
|
206
|
+
let view: HTMLElement | null = null;
|
|
231
207
|
|
|
232
208
|
for (const key in rawObj) {
|
|
233
209
|
const singleObj = rawObj[key];
|
|
234
|
-
const tag:
|
|
235
|
-
singleObj?.tag?.tagName ? (singleObj.tag as
|
|
210
|
+
const tag: HTMLElement =
|
|
211
|
+
singleObj?.tag?.tagName ? (singleObj.tag as HTMLElement) : (this.nodeCreator(singleObj.tag) as HTMLElement);
|
|
236
212
|
|
|
237
213
|
recursiveTemp[key] = tag;
|
|
238
214
|
|
|
@@ -349,7 +325,7 @@ export class Libs {
|
|
|
349
325
|
/**
|
|
350
326
|
* Removes a binder map entry for the given element from the global storage.
|
|
351
327
|
*
|
|
352
|
-
* @param {HTMLElement} element -
|
|
328
|
+
* @param {HTMLElement} element - HTMLElement key to remove from the binder map.
|
|
353
329
|
* @returns {boolean} - True if an entry existed and was removed.
|
|
354
330
|
*/
|
|
355
331
|
public static removeBinderMap(element: HTMLElement): boolean {
|
|
@@ -359,17 +335,17 @@ export class Libs {
|
|
|
359
335
|
/**
|
|
360
336
|
* Retrieves the binder map entry associated with the given element.
|
|
361
337
|
*
|
|
362
|
-
* @param {HTMLElement} item -
|
|
363
|
-
* @returns {BinderMap |
|
|
338
|
+
* @param {HTMLElement} item - HTMLElement key whose binder map is requested.
|
|
339
|
+
* @returns {BinderMap | any} - The stored binder map value or undefined if absent.
|
|
364
340
|
*/
|
|
365
|
-
public static getBinderMap(item: HTMLElement):
|
|
366
|
-
return this.iStorage.bindedMap.get(item);
|
|
341
|
+
public static getBinderMap<T extends BinderMap | any>(item: HTMLElement): T {
|
|
342
|
+
return this.iStorage.bindedMap.get(item) as T;
|
|
367
343
|
}
|
|
368
344
|
|
|
369
345
|
/**
|
|
370
346
|
* Sets or updates the binder map entry for a given element.
|
|
371
347
|
*
|
|
372
|
-
* @param {HTMLElement} item -
|
|
348
|
+
* @param {HTMLElement} item - HTMLElement key to associate with the binder map.
|
|
373
349
|
* @param {BinderMap} bindMap - Value to store in the binder map.
|
|
374
350
|
*/
|
|
375
351
|
public static setBinderMap(item: HTMLElement, bindMap: BinderMap): void {
|
|
@@ -379,7 +355,7 @@ export class Libs {
|
|
|
379
355
|
/**
|
|
380
356
|
* Removes an unbinder map entry for the given element from the global storage.
|
|
381
357
|
*
|
|
382
|
-
* @param {HTMLElement} element -
|
|
358
|
+
* @param {HTMLElement} element - HTMLElement key to remove from the unbinder map.
|
|
383
359
|
* @returns {boolean} - True if an entry existed and was removed.
|
|
384
360
|
*/
|
|
385
361
|
public static removeUnbinderMap(element: HTMLElement): boolean {
|
|
@@ -389,7 +365,7 @@ export class Libs {
|
|
|
389
365
|
/**
|
|
390
366
|
* Retrieves the unbinder map entry associated with the given element.
|
|
391
367
|
*
|
|
392
|
-
* @param {HTMLElement} item -
|
|
368
|
+
* @param {HTMLElement} item - HTMLElement key whose unbinder map is requested.
|
|
393
369
|
* @returns {unknown} - The stored unbinder map value or undefined if absent.
|
|
394
370
|
*/
|
|
395
371
|
public static getUnbinderMap(item: HTMLElement): unknown {
|
|
@@ -399,7 +375,7 @@ export class Libs {
|
|
|
399
375
|
/**
|
|
400
376
|
* Sets or updates the unbinder map entry for a given element.
|
|
401
377
|
*
|
|
402
|
-
* @param {HTMLElement} item -
|
|
378
|
+
* @param {HTMLElement} item - HTMLElement key to associate with the unbinder map.
|
|
403
379
|
* @param {BinderMap} bindMap - Value to store in the unbinder map.
|
|
404
380
|
*/
|
|
405
381
|
public static setUnbinderMap(item: HTMLElement, bindMap: BinderMap): void {
|
|
@@ -440,7 +416,7 @@ export class Libs {
|
|
|
440
416
|
.replace(/\`\>/g, ">")
|
|
441
417
|
.trim();
|
|
442
418
|
|
|
443
|
-
const doc = globalThis?.document
|
|
419
|
+
const doc = globalThis?.document;
|
|
444
420
|
|
|
445
421
|
if (!doc || typeof doc.createElement !== "function") {
|
|
446
422
|
s = s
|
|
@@ -560,7 +536,7 @@ export class Libs {
|
|
|
560
536
|
if (v.endsWith("rem")) return fs * parseFloat(v) + "px";
|
|
561
537
|
|
|
562
538
|
// fallback: DOM measure
|
|
563
|
-
const el = this.nodeCreator({ node: "div", style: { height: v, opacity: "0" } })
|
|
539
|
+
const el = this.nodeCreator({ node: "div", style: { height: v, opacity: "0" } });
|
|
564
540
|
document.body.appendChild(el);
|
|
565
541
|
const px = el.offsetHeight + "px";
|
|
566
542
|
el.remove();
|