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.
Files changed (50) hide show
  1. package/dist/selective-ui.css.map +1 -1
  2. package/dist/selective-ui.esm.js +2106 -624
  3. package/dist/selective-ui.esm.js.map +1 -1
  4. package/dist/selective-ui.esm.min.js +2 -2
  5. package/dist/selective-ui.esm.min.js.br +0 -0
  6. package/dist/selective-ui.min.js +2 -2
  7. package/dist/selective-ui.min.js.br +0 -0
  8. package/dist/selective-ui.umd.js +2107 -625
  9. package/dist/selective-ui.umd.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/ts/adapter/mixed-adapter.ts +156 -65
  12. package/src/ts/components/accessorybox.ts +153 -30
  13. package/src/ts/components/directive.ts +62 -11
  14. package/src/ts/components/option-handle.ts +124 -28
  15. package/src/ts/components/placeholder.ts +73 -16
  16. package/src/ts/components/popup/empty-state.ts +126 -0
  17. package/src/ts/components/popup/loading-state.ts +120 -0
  18. package/src/ts/components/{popup.ts → popup/popup.ts} +168 -71
  19. package/src/ts/components/searchbox.ts +82 -16
  20. package/src/ts/components/selectbox.ts +208 -109
  21. package/src/ts/core/base/adapter.ts +110 -44
  22. package/src/ts/core/base/lifecycle.ts +175 -0
  23. package/src/ts/core/base/model.ts +63 -32
  24. package/src/ts/core/base/recyclerview.ts +56 -18
  25. package/src/ts/core/base/view.ts +56 -19
  26. package/src/ts/core/base/virtual-recyclerview.ts +317 -126
  27. package/src/ts/core/model-manager.ts +4 -4
  28. package/src/ts/core/search-controller.ts +149 -24
  29. package/src/ts/global.ts +5 -5
  30. package/src/ts/index.ts +5 -5
  31. package/src/ts/models/group-model.ts +27 -6
  32. package/src/ts/models/option-model.ts +29 -6
  33. package/src/ts/services/ea-observer.ts +6 -6
  34. package/src/ts/types/components/searchbox.type.ts +1 -1
  35. package/src/ts/types/core/base/adapter.type.ts +2 -1
  36. package/src/ts/types/core/base/lifecycle.type.ts +62 -0
  37. package/src/ts/types/core/base/model.type.ts +3 -1
  38. package/src/ts/types/core/base/recyclerview.type.ts +2 -8
  39. package/src/ts/types/core/base/view.type.ts +36 -24
  40. package/src/ts/utils/istorage.ts +1 -1
  41. package/src/ts/utils/selective.ts +153 -36
  42. package/src/ts/views/group-view.ts +59 -21
  43. package/src/ts/views/option-view.ts +137 -68
  44. package/src/ts/components/empty-state.ts +0 -68
  45. package/src/ts/components/loading-state.ts +0 -66
  46. /package/src/css/components/{empty-state.css → popup/empty-state.css} +0 -0
  47. /package/src/css/components/{loading-state.css → popup/loading-state.css} +0 -0
  48. /package/src/css/components/{popup.css → popup/popup.css} +0 -0
  49. /package/src/css/{components/optgroup.css → views/group-view.css} +0 -0
  50. /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
- * @class
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
- * Represents a placeholder component for the Select UI, allowing dynamic updates to placeholder text.
14
- * Supports HTML content based on configuration and provides methods to get or set the placeholder value.
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
- if (options) this.init(options);
40
+ super();
41
+ if (options) this.initialize(options);
18
42
  }
19
43
 
20
44
  /**
21
- * Initializes the placeholder element with provided options and renders its initial content.
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 {object} options - Configuration object containing placeholder text and HTML allowance.
51
+ * @param options - Configuration object containing placeholder settings.
24
52
  */
25
- private init(options: SelectiveOptions): void {
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
- * Retrieves the current placeholder text from the configuration.
66
+ * Returns the current placeholder text from the configuration.
37
67
  *
38
- * @returns {string} - The current placeholder text.
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 text and optionally saves it to the configuration.
46
- * Applies HTML sanitization based on the allowHtml setting.
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 {string} value - The new placeholder text.
49
- * @param {boolean} [isSave=true] - Whether to persist the new value in the configuration.
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) this.options.placeholder = value;
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 ? translated : Libs.stripHtml(translated);
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
+ }