selective-ui 1.2.3 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/selective-ui.css.map +1 -1
- package/dist/selective-ui.esm.js +2106 -624
- 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.js +2 -2
- package/dist/selective-ui.min.js.br +0 -0
- package/dist/selective-ui.umd.js +2107 -625
- package/dist/selective-ui.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/ts/adapter/mixed-adapter.ts +156 -65
- package/src/ts/components/accessorybox.ts +153 -30
- package/src/ts/components/directive.ts +62 -11
- package/src/ts/components/option-handle.ts +124 -28
- package/src/ts/components/placeholder.ts +73 -16
- package/src/ts/components/popup/empty-state.ts +126 -0
- package/src/ts/components/popup/loading-state.ts +120 -0
- package/src/ts/components/{popup.ts → popup/popup.ts} +168 -71
- package/src/ts/components/searchbox.ts +82 -16
- package/src/ts/components/selectbox.ts +208 -109
- package/src/ts/core/base/adapter.ts +110 -44
- package/src/ts/core/base/lifecycle.ts +175 -0
- package/src/ts/core/base/model.ts +63 -32
- package/src/ts/core/base/recyclerview.ts +56 -18
- package/src/ts/core/base/view.ts +56 -19
- package/src/ts/core/base/virtual-recyclerview.ts +317 -126
- package/src/ts/core/model-manager.ts +4 -4
- package/src/ts/core/search-controller.ts +149 -24
- package/src/ts/global.ts +5 -5
- package/src/ts/index.ts +5 -5
- package/src/ts/models/group-model.ts +27 -6
- package/src/ts/models/option-model.ts +29 -6
- package/src/ts/services/ea-observer.ts +6 -6
- package/src/ts/types/components/searchbox.type.ts +1 -1
- package/src/ts/types/core/base/adapter.type.ts +2 -1
- package/src/ts/types/core/base/lifecycle.type.ts +62 -0
- package/src/ts/types/core/base/model.type.ts +3 -1
- package/src/ts/types/core/base/recyclerview.type.ts +2 -8
- package/src/ts/types/core/base/view.type.ts +36 -24
- package/src/ts/utils/istorage.ts +1 -1
- package/src/ts/utils/selective.ts +153 -36
- package/src/ts/views/group-view.ts +59 -21
- package/src/ts/views/option-view.ts +137 -68
- package/src/ts/components/empty-state.ts +0 -68
- package/src/ts/components/loading-state.ts +0 -66
- /package/src/css/components/{empty-state.css → popup/empty-state.css} +0 -0
- /package/src/css/components/{loading-state.css → popup/loading-state.css} +0 -0
- /package/src/css/components/{popup.css → popup/popup.css} +0 -0
- /package/src/css/{components/optgroup.css → views/group-view.css} +0 -0
- /package/src/css/{components/option.css → views/option-view.css} +0 -0
|
@@ -1,28 +1,56 @@
|
|
|
1
|
+
import { Lifecycle } from "../core/base/lifecycle";
|
|
2
|
+
import { LifecycleState } from "../types/core/base/lifecycle.type";
|
|
1
3
|
import { SelectiveOptions } from "../types/utils/selective.type";
|
|
2
4
|
import { Libs } from "../utils/libs";
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
|
-
*
|
|
7
|
+
* UI component representing a placeholder for the Select UI.
|
|
8
|
+
*
|
|
9
|
+
* The placeholder displays contextual guidance when no value is selected.
|
|
10
|
+
* It supports dynamic updates and optional HTML content, depending on configuration.
|
|
11
|
+
*
|
|
12
|
+
* The component manages a single DOM node and participates
|
|
13
|
+
* in the standard `Lifecycle`.
|
|
14
|
+
*
|
|
15
|
+
* @extends Lifecycle
|
|
6
16
|
*/
|
|
7
|
-
export class PlaceHolder {
|
|
17
|
+
export class PlaceHolder extends Lifecycle {
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Root DOM element of the placeholder component.
|
|
21
|
+
* Created during initialization and removed on destroy.
|
|
22
|
+
*/
|
|
8
23
|
public node: HTMLElement | null = null;
|
|
9
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Configuration options containing placeholder text
|
|
27
|
+
* and rendering preferences (e.g., allowHtml).
|
|
28
|
+
*/
|
|
10
29
|
private options: SelectiveOptions | null = null;
|
|
11
30
|
|
|
12
31
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
32
|
+
* Creates a new PlaceHolder instance.
|
|
33
|
+
*
|
|
34
|
+
* If options are provided, the component is initialized immediately.
|
|
35
|
+
*
|
|
36
|
+
* @param options - Configuration object containing placeholder text
|
|
37
|
+
* and HTML rendering settings.
|
|
15
38
|
*/
|
|
16
39
|
constructor(options: SelectiveOptions | null) {
|
|
17
|
-
|
|
40
|
+
super();
|
|
41
|
+
if (options) this.initialize(options);
|
|
18
42
|
}
|
|
19
43
|
|
|
20
44
|
/**
|
|
21
|
-
* Initializes the placeholder
|
|
45
|
+
* Initializes the placeholder component.
|
|
46
|
+
*
|
|
47
|
+
* Creates the DOM node, applies base styling,
|
|
48
|
+
* renders the initial placeholder content,
|
|
49
|
+
* stores configuration options, and starts the lifecycle.
|
|
22
50
|
*
|
|
23
|
-
* @param
|
|
51
|
+
* @param options - Configuration object containing placeholder settings.
|
|
24
52
|
*/
|
|
25
|
-
private
|
|
53
|
+
private initialize(options: SelectiveOptions): void {
|
|
26
54
|
this.node = Libs.nodeCreator({
|
|
27
55
|
node: "div",
|
|
28
56
|
classList: "selective-ui-placeholder",
|
|
@@ -30,30 +58,59 @@ export class PlaceHolder {
|
|
|
30
58
|
}) as HTMLElement;
|
|
31
59
|
|
|
32
60
|
this.options = options;
|
|
61
|
+
|
|
62
|
+
this.init();
|
|
33
63
|
}
|
|
34
64
|
|
|
35
65
|
/**
|
|
36
|
-
*
|
|
66
|
+
* Returns the current placeholder text from the configuration.
|
|
37
67
|
*
|
|
38
|
-
* @returns
|
|
68
|
+
* @returns The current placeholder value, or an empty string if not set.
|
|
39
69
|
*/
|
|
40
70
|
public get(): string {
|
|
41
71
|
return this.options?.placeholder ?? "";
|
|
42
72
|
}
|
|
43
73
|
|
|
44
74
|
/**
|
|
45
|
-
* Updates the placeholder
|
|
46
|
-
*
|
|
75
|
+
* Updates the placeholder content.
|
|
76
|
+
*
|
|
77
|
+
* The value can optionally be persisted back into the configuration.
|
|
78
|
+
* HTML rendering is controlled by the `allowHtml` option:
|
|
79
|
+
* - When enabled, translated HTML is rendered
|
|
80
|
+
* - When disabled, HTML tags are stripped for safety
|
|
47
81
|
*
|
|
48
|
-
* @param
|
|
49
|
-
* @param
|
|
82
|
+
* @param value - The new placeholder content.
|
|
83
|
+
* @param isSave - Whether to persist the value in the configuration.
|
|
84
|
+
* Defaults to `true`.
|
|
50
85
|
*/
|
|
51
86
|
public set(value: string, isSave: boolean = true): void {
|
|
52
87
|
if (!this.node || !this.options) return;
|
|
53
88
|
|
|
54
|
-
if (isSave)
|
|
89
|
+
if (isSave) {
|
|
90
|
+
this.options.placeholder = value;
|
|
91
|
+
}
|
|
55
92
|
|
|
56
93
|
const translated = Libs.tagTranslate(value);
|
|
57
|
-
this.node.innerHTML = this.options.allowHtml
|
|
94
|
+
this.node.innerHTML = this.options.allowHtml
|
|
95
|
+
? translated
|
|
96
|
+
: Libs.stripHtml(translated);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Destroys the placeholder component.
|
|
101
|
+
*
|
|
102
|
+
* Removes the DOM node, clears stored options,
|
|
103
|
+
* and terminates the lifecycle.
|
|
104
|
+
*/
|
|
105
|
+
public override destroy(): void {
|
|
106
|
+
if (this.is(LifecycleState.DESTROYED)) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
this.node?.remove();
|
|
111
|
+
this.node = null;
|
|
112
|
+
this.options = null;
|
|
113
|
+
|
|
114
|
+
super.destroy();
|
|
58
115
|
}
|
|
59
116
|
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Lifecycle } from "../../core/base/lifecycle";
|
|
2
|
+
import { EmptyStateType } from "../../types/components/state.box.type";
|
|
3
|
+
import { LifecycleState } from "../../types/core/base/lifecycle.type";
|
|
4
|
+
import { SelectiveOptions } from "../../types/utils/selective.type";
|
|
5
|
+
import { Libs } from "../../utils/libs";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* UI component that represents an empty state.
|
|
9
|
+
*
|
|
10
|
+
* The empty state is used to display contextual feedback when:
|
|
11
|
+
* - No data is available
|
|
12
|
+
* - A search yields no matching results
|
|
13
|
+
*
|
|
14
|
+
* It manages a single DOM node and participates in the standard lifecycle.
|
|
15
|
+
*
|
|
16
|
+
* @extends Lifecycle
|
|
17
|
+
*/
|
|
18
|
+
export class EmptyState extends Lifecycle {
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Root DOM element of the empty state component.
|
|
22
|
+
* Created during initialization and removed on destroy.
|
|
23
|
+
*/
|
|
24
|
+
public node: HTMLDivElement | null = null;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Configuration options providing display text
|
|
28
|
+
* for different empty state scenarios.
|
|
29
|
+
*/
|
|
30
|
+
public options: SelectiveOptions | null = null;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Creates a new EmptyState instance.
|
|
34
|
+
*
|
|
35
|
+
* If options are provided, the component is initialized immediately.
|
|
36
|
+
*
|
|
37
|
+
* @param options - Configuration containing messages for
|
|
38
|
+
* "no data" and "not found" states.
|
|
39
|
+
*/
|
|
40
|
+
public constructor(options: SelectiveOptions | null = null) {
|
|
41
|
+
super();
|
|
42
|
+
if (options) this.initialize(options);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Initializes the empty state component.
|
|
47
|
+
*
|
|
48
|
+
* Creates the root DOM element, applies accessibility attributes,
|
|
49
|
+
* stores configuration options, and starts the lifecycle.
|
|
50
|
+
*
|
|
51
|
+
* @param options - Configuration object containing empty state messages.
|
|
52
|
+
*/
|
|
53
|
+
private initialize(options: SelectiveOptions): void {
|
|
54
|
+
this.options = options;
|
|
55
|
+
|
|
56
|
+
this.node = Libs.nodeCreator({
|
|
57
|
+
node: "div",
|
|
58
|
+
classList: ["selective-ui-empty-state", "hide"],
|
|
59
|
+
role: "status",
|
|
60
|
+
ariaLive: "polite",
|
|
61
|
+
}) as HTMLDivElement;
|
|
62
|
+
|
|
63
|
+
this.init();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Displays the empty state message.
|
|
68
|
+
*
|
|
69
|
+
* The message content depends on the provided type:
|
|
70
|
+
* - `"nodata"`: no data available
|
|
71
|
+
* - `"notfound"`: no matching search results
|
|
72
|
+
*
|
|
73
|
+
* @param type - Type of empty state to display.
|
|
74
|
+
* Defaults to `"nodata"`.
|
|
75
|
+
*/
|
|
76
|
+
public show(type: EmptyStateType = "nodata"): void {
|
|
77
|
+
if (!this.node || !this.options) return;
|
|
78
|
+
|
|
79
|
+
const text =
|
|
80
|
+
type === "notfound"
|
|
81
|
+
? this.options.textNotFound
|
|
82
|
+
: this.options.textNoData;
|
|
83
|
+
|
|
84
|
+
this.node.textContent = text;
|
|
85
|
+
this.node.classList.remove("hide");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Hides the empty state component.
|
|
90
|
+
*
|
|
91
|
+
* This does not remove the element from the DOM;
|
|
92
|
+
* it only updates its visibility via CSS.
|
|
93
|
+
*/
|
|
94
|
+
public hide(): void {
|
|
95
|
+
if (!this.node) return;
|
|
96
|
+
this.node.classList.add("hide");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Indicates whether the empty state is currently visible.
|
|
101
|
+
*
|
|
102
|
+
* @returns True if the empty state is shown; otherwise false.
|
|
103
|
+
*/
|
|
104
|
+
public get isVisible(): boolean {
|
|
105
|
+
return !!this.node && !this.node.classList.contains("hide");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Destroys the empty state component.
|
|
110
|
+
*
|
|
111
|
+
* Removes the DOM node, clears stored options,
|
|
112
|
+
* and terminates the lifecycle.
|
|
113
|
+
*/
|
|
114
|
+
public override destroy(): void {
|
|
115
|
+
if (this.is(LifecycleState.DESTROYED)) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
this.options = null;
|
|
120
|
+
|
|
121
|
+
this.node?.remove();
|
|
122
|
+
this.node = null;
|
|
123
|
+
|
|
124
|
+
super.destroy();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Lifecycle } from "../../core/base/lifecycle";
|
|
2
|
+
import { LifecycleState } from "../../types/core/base/lifecycle.type";
|
|
3
|
+
import { SelectiveOptions } from "../../types/utils/selective.type";
|
|
4
|
+
import { Libs } from "../../utils/libs";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* UI component representing a loading state.
|
|
8
|
+
*
|
|
9
|
+
* The loading state is displayed while data is being fetched,
|
|
10
|
+
* processed, or updated asynchronously.
|
|
11
|
+
*
|
|
12
|
+
* It manages a single DOM element and participates in the
|
|
13
|
+
* standard lifecycle provided by `Lifecycle`.
|
|
14
|
+
*
|
|
15
|
+
* @extends Lifecycle
|
|
16
|
+
*/
|
|
17
|
+
export class LoadingState extends Lifecycle {
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Root DOM element of the loading state component.
|
|
21
|
+
* Created during initialization and removed on destroy.
|
|
22
|
+
*/
|
|
23
|
+
public node: HTMLDivElement | null = null;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Configuration options containing the loading message text.
|
|
27
|
+
*/
|
|
28
|
+
public options: SelectiveOptions | null = null;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new LoadingState instance.
|
|
32
|
+
*
|
|
33
|
+
* If options are provided, the component is initialized immediately.
|
|
34
|
+
*
|
|
35
|
+
* @param options - Configuration object containing the loading message text.
|
|
36
|
+
*/
|
|
37
|
+
public constructor(options: SelectiveOptions | null = null) {
|
|
38
|
+
super();
|
|
39
|
+
if (options) this.initialize(options);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Initializes the loading state component.
|
|
44
|
+
*
|
|
45
|
+
* Creates the root DOM element, sets the initial loading text,
|
|
46
|
+
* applies accessibility attributes, stores configuration options,
|
|
47
|
+
* and starts the lifecycle.
|
|
48
|
+
*
|
|
49
|
+
* @param options - Configuration object containing loading text.
|
|
50
|
+
*/
|
|
51
|
+
private initialize(options: SelectiveOptions): void {
|
|
52
|
+
this.options = options;
|
|
53
|
+
|
|
54
|
+
this.node = Libs.nodeCreator({
|
|
55
|
+
node: "div",
|
|
56
|
+
classList: ["selective-ui-loading-state", "hide"],
|
|
57
|
+
textContent: options.textLoading,
|
|
58
|
+
role: "status",
|
|
59
|
+
ariaLive: "polite",
|
|
60
|
+
}) as HTMLDivElement;
|
|
61
|
+
|
|
62
|
+
this.init();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Displays the loading state.
|
|
67
|
+
*
|
|
68
|
+
* When items are already present, the loading state can be shown
|
|
69
|
+
* in a compact form by applying a reduced ("small") style.
|
|
70
|
+
*
|
|
71
|
+
* @param hasItems - True if existing items are present,
|
|
72
|
+
* enabling a compact loading indicator.
|
|
73
|
+
*/
|
|
74
|
+
public show(hasItems: boolean): void {
|
|
75
|
+
if (!this.node || !this.options) return;
|
|
76
|
+
|
|
77
|
+
this.node.textContent = this.options.textLoading;
|
|
78
|
+
this.node.classList.toggle("small", !!hasItems);
|
|
79
|
+
this.node.classList.remove("hide");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Hides the loading state.
|
|
84
|
+
*
|
|
85
|
+
* This only toggles visibility via CSS and does not
|
|
86
|
+
* remove the element from the DOM.
|
|
87
|
+
*/
|
|
88
|
+
public hide(): void {
|
|
89
|
+
if (!this.node) return;
|
|
90
|
+
this.node.classList.add("hide");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Indicates whether the loading state is currently visible.
|
|
95
|
+
*
|
|
96
|
+
* @returns True if the loading indicator is shown; otherwise false.
|
|
97
|
+
*/
|
|
98
|
+
public get isVisible(): boolean {
|
|
99
|
+
return !!this.node && !this.node.classList.contains("hide");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Destroys the loading state component.
|
|
104
|
+
*
|
|
105
|
+
* Removes the DOM node, clears stored options,
|
|
106
|
+
* and terminates the lifecycle.
|
|
107
|
+
*/
|
|
108
|
+
public override destroy(): void {
|
|
109
|
+
if (this.is(LifecycleState.DESTROYED)) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.options = null;
|
|
114
|
+
|
|
115
|
+
this.node?.remove();
|
|
116
|
+
this.node = null;
|
|
117
|
+
|
|
118
|
+
super.destroy();
|
|
119
|
+
}
|
|
120
|
+
}
|