@cntwg/html-ctrls-lists 0.0.27

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.
@@ -0,0 +1,214 @@
1
+ // [v0.1.058-20250928]
2
+
3
+ // === module init block ===
4
+
5
+ const {
6
+ isPlainObject,
7
+ } = require('@ygracs/bsfoc-lib-js');
8
+
9
+ const {
10
+ isHTMLButton,
11
+ eventHelper, // [!] not oficialy exported yet
12
+ CSS_CLASS_STRING,
13
+ } = require('@cntwg/html-helper');
14
+
15
+ const {
16
+ THtmlButtonsSet,
17
+ } = require('@cntwg/html-helper');
18
+
19
+ const {
20
+ readOnClickEventInfo,
21
+ } = require('./mod-hfunc.js');
22
+
23
+ // === module inner block ===
24
+
25
+ const {
26
+ pushEventHandler, triggerEventHandler,
27
+ } = eventHelper;
28
+
29
+ const {
30
+ CSS_CLASS_DISABLED,
31
+ } = CSS_CLASS_STRING;
32
+
33
+ // === module main block ===
34
+
35
+ /***
36
+ * (* constant definitions *)
37
+ */
38
+
39
+ const BTS_DEF_GROUP_NAME = 'all';
40
+
41
+ /***
42
+ * (* function definitions *)
43
+ */
44
+
45
+ /***
46
+ * (* class definitions *)
47
+ */
48
+
49
+ /**
50
+ * A description for list buttons set.
51
+ * @typedef {Object} listButtonsSetDesc
52
+ * @property {?HTMLElement} btnFirst - button 'move to first'
53
+ * @property {?HTMLElement} btnPrev - button 'move to previous'
54
+ * @property {?HTMLElement} btnNext - button 'move to next'
55
+ * @property {?HTMLElement} btnLast - button 'move to last'
56
+ */
57
+
58
+ /**
59
+ * @classdesc This class implements an interface of a pre-defined
60
+ * buttons set that is used in pair with a list elements.
61
+ * A set provide a buttons: <next>, <previous>, <first> and <last>.
62
+ */
63
+ class THtmlListButtonsController {
64
+ /** @type {THtmlButtonsSet} */
65
+ #_btnSet;
66
+ /** @type {Map<string, Function>} */
67
+ #_events;
68
+
69
+ /**
70
+ * Creates an instance of a buttons set.
71
+ * @param {listButtonsSetDesc} [opt] - an options
72
+ */
73
+ constructor(opt) {
74
+ // load controls
75
+ /** @type {listButtonsSetDesc} */
76
+ let {
77
+ btnFirst,
78
+ btnPrev,
79
+ btnNext,
80
+ btnLast,
81
+ } = isPlainObject(opt) ? opt : {};
82
+ if (!isHTMLButton(btnFirst)) btnFirst = null;
83
+ if (!isHTMLButton(btnPrev)) btnPrev = null;
84
+ if (!isHTMLButton(btnNext)) btnNext = null;
85
+ if (!isHTMLButton(btnLast)) btnLast = null;
86
+ // init buttons set
87
+ const _btnSet = new THtmlButtonsSet();
88
+ this.#_btnSet = _btnSet;
89
+ _btnSet.addGroup('move_frwd');
90
+ _btnSet.addGroup('move_bkwd');
91
+ _btnSet.addGroup('dsbl_ctrls');
92
+ if (btnFirst && btnLast) {
93
+ _btnSet.addItem('btn_frst', btnFirst, 'move_bkwd');
94
+ _btnSet.addItem('btn_last', btnLast, 'move_frwd');
95
+ btnFirst.addEventListener('click', e => this.#_on_btn_pressed(e, 'first'));
96
+ btnLast.addEventListener('click', e => this.#_on_btn_pressed(e, 'last'));
97
+ } else {
98
+ _btnSet.addItem('btn_frst', btnFirst, 'dsbl_ctrls');
99
+ _btnSet.addItem('btn_last', btnLast, 'dsbl_ctrls');
100
+ };
101
+ if (btnPrev && btnNext) {
102
+ _btnSet.addItem('btn_prev', btnPrev, 'move_bkwd');
103
+ _btnSet.addItem('btn_next', btnNext, 'move_frwd');
104
+ btnPrev.addEventListener('click', e => this.#_on_btn_pressed(e, 'prev'));
105
+ btnNext.addEventListener('click', e => this.#_on_btn_pressed(e, 'next'));
106
+ } else {
107
+ _btnSet.addItem('btn_prev', btnPrev, 'dsbl_ctrls');
108
+ _btnSet.addItem('btn_next', btnNext, 'dsbl_ctrls');
109
+ };
110
+ _btnSet.disableGroup('move_frwd');
111
+ _btnSet.disableGroup('move_bkwd');
112
+ _btnSet.disableGroup('dsbl_ctrls');
113
+ // init events controller
114
+ this.#_events = new Map();
115
+ }
116
+
117
+ /**
118
+ * @param {object} e - event
119
+ * @param {string} key - button ID
120
+ * @returns {void}
121
+ * @private
122
+ */
123
+ #_on_btn_pressed = (e, key) => {
124
+ //console.log(`THtmlListButtonsController._on_btn_pressed().key(${key}) ==> was called...`);
125
+ //e.preventDefault(); /* need to reconsider reason for use */
126
+ const { item, onClickNum } = readOnClickEventInfo(e);
127
+ if (
128
+ item instanceof HTMLElement
129
+ && (onClickNum === 0 || onClickNum === 1)
130
+ && !item.classList.contains(CSS_CLASS_DISABLED)
131
+ ) {
132
+ this.#_triggerEvent(`btn-${key}-pressed`, e);
133
+ };
134
+ }
135
+
136
+ /**
137
+ * @param {string} name - event name
138
+ * @param {...any} args
139
+ * @returns {void}
140
+ * @private
141
+ * @see triggerEventHandler
142
+ */
143
+ #_triggerEvent = (name, ...args) => {
144
+ triggerEventHandler(this.#_events, name, ...args);
145
+ }
146
+
147
+ /**
148
+ * Disables all buttons.
149
+ * @returns {void}
150
+ */
151
+ disableAll() {
152
+ const _btnSet = this.#_btnSet;
153
+ _btnSet.disableGroup('move_bkwd');
154
+ _btnSet.disableGroup('move_frwd');
155
+ }
156
+
157
+ /**
158
+ * Disables all buttons in 'move_bkwd' group.
159
+ * @returns {void}
160
+ */
161
+ disableBkwd() {
162
+ this.#_btnSet.disableGroup('move_bkwd');
163
+ }
164
+
165
+ /**
166
+ * Disables all buttons in 'move_frwd' group.
167
+ * @returns {void}
168
+ */
169
+ disableFrwd() {
170
+ this.#_btnSet.disableGroup('move_frwd');
171
+ }
172
+
173
+ /**
174
+ * Enables all buttons.
175
+ * @returns {void}
176
+ */
177
+ enableAll() {
178
+ const _btnSet = this.#_btnSet;
179
+ _btnSet.enableGroup('move_bkwd');
180
+ _btnSet.enableGroup('move_frwd');
181
+ }
182
+
183
+ /**
184
+ * Enables all buttons in 'move_bkwd' group.
185
+ * @returns {void}
186
+ */
187
+ enableBkwd() {
188
+ this.#_btnSet.enableGroup('move_bkwd');
189
+ }
190
+
191
+ /**
192
+ * Enables all buttons in 'move_frwd' group.
193
+ * @returns {void}
194
+ */
195
+ enableFrwd() {
196
+ this.#_btnSet.enableGroup('move_frwd');
197
+ }
198
+
199
+ /**
200
+ * Sets a callback function to handle event.
201
+ * @param {string} name - event name
202
+ * @param {func} evnt - callback function
203
+ * @returns {void}
204
+ */
205
+ on(name, evnt) {
206
+ pushEventHandler(this.#_events, name, evnt);
207
+ }
208
+ };
209
+
210
+ // === module exports block ===
211
+
212
+ exports.THtmlListButtonsController = THtmlListButtonsController;
213
+
214
+ exports.BTS_DEF_GROUP_NAME = BTS_DEF_GROUP_NAME;
@@ -0,0 +1,298 @@
1
+ // [v0.1.051-20251002]
2
+
3
+ // === module init block ===
4
+
5
+ const {
6
+ isArray, isObject, isPlainObject,
7
+ } = require('@ygracs/bsfoc-lib-js');
8
+
9
+ const {
10
+ isHTMLElement,
11
+ } = require('@cntwg/html-helper');
12
+
13
+ // === module inner block ===
14
+
15
+ // === module main block ===
16
+
17
+ /***
18
+ * (* constant definitions *)
19
+ */
20
+
21
+ /***
22
+ * (* function definitions *)
23
+ */
24
+
25
+ /***
26
+ * (* class definitions *)
27
+ */
28
+
29
+ /**
30
+ * A settings to load a stub-elements.
31
+ * @typedef {Object} OPT_ldstubs
32
+ * @property {string} [defaultItem] - <*deprecated*> a default element name
33
+ * @property {boolean} [useClear=true] - to clear before load an elements
34
+ * @property {boolean} [force=false] - run in a force mode
35
+ * @todo [since v0.0.26] `defaultItem`-option deprecated
36
+ */
37
+
38
+ /**
39
+ * A stub-elements description list.
40
+ * @typedef {Object} OBJ_stubEList
41
+ * @property {Array} items - array of `name`-`element` pairs
42
+ * @property {string} [defaultItem] - a default element name
43
+ */
44
+
45
+ /**
46
+ * A an options set for a `THtmlStubItemsSet`-class constructor
47
+ * @typedef {Object} OPT_stubconsett
48
+ * @property {(any[])} items - array of `name`-`element` pairs
49
+ * @property {string} [defaultItem] - a default element name
50
+ * @property {boolean} [force=false] - run in a force mode
51
+ */
52
+
53
+ /**
54
+ * @classdesc This class implements an interface of a stub-items set
55
+ */
56
+ class THtmlStubItemsSet {
57
+ /** @type {?HTMLElement} */
58
+ #_host;
59
+ /** @type {Map<string, HTMLElement>} */
60
+ #_items;
61
+ /** @type {string} */
62
+ #_defItem;
63
+ #_shownItem = null;
64
+
65
+ /**
66
+ * Creates an instance of a stub-items set
67
+ * @param {HTMLElement} host - host element
68
+ * @param {(array|OPT_stubconsett|OBJ_stubEList)} [opt] - options
69
+ * @todo [since v0.0.26] use of an `array`-type as a value of an `opt` is deprecated
70
+ */
71
+ constructor(host, opt) {
72
+ this.#_host = isHTMLElement(host) ? host : null;
73
+ this.#_items = new Map();
74
+ this.#_defItem = '';
75
+ this.#_shownItem = null;
76
+ if (isObject(opt)) {
77
+ /** @type {(OPT_stubconsett|OBJ_stubEList)} */
78
+ const obj = isArray(opt) ? { items: opt } : opt;
79
+ const { items, defaultItem, force } = obj;
80
+ this.loadItems({
81
+ items,
82
+ defaultItem,
83
+ }, {
84
+ force,
85
+ });
86
+ };
87
+ }
88
+
89
+ /**
90
+ * Defines a default element name
91
+ * @type {string}
92
+ */
93
+ get defItem() {
94
+ return this.#_defItem;
95
+ }
96
+
97
+ set defItem(name) {
98
+ this.setDefItem(name);
99
+ }
100
+
101
+ /**
102
+ * Contains a Qty of an elements
103
+ * @type {number}
104
+ * @readonly
105
+ */
106
+ get count() {
107
+ return this.#_items.size;
108
+ }
109
+
110
+ /**
111
+ * Clears an instance content.
112
+ * @returns {void}
113
+ * @todo check if any item is shown
114
+ */
115
+ clear() {
116
+ this.#_items.clear();
117
+ this.#_defItem = '';
118
+ this.#_shownItem = null;
119
+ }
120
+
121
+ /**
122
+ * Sets a default item.
123
+ * @param {string} name - an element name
124
+ * @returns {boolean}
125
+ */
126
+ setDefItem(name) {
127
+ let isACCEPTED = false;
128
+ if (typeof name === 'string') {
129
+ const _name = name.trim();
130
+ isACCEPTED = this.#_items.has(_name);
131
+ if (isACCEPTED) this.#_defItem = _name;
132
+ };
133
+ return isACCEPTED;
134
+ }
135
+
136
+ /**
137
+ * Resets a default item.
138
+ * @returns {void}
139
+ * @todo check if item is shown
140
+ */
141
+ rstDefItem() {
142
+ this.#_defItem = '';
143
+ }
144
+
145
+ /**
146
+ * Checks if an item exists.
147
+ * @param {string} name - an element name
148
+ * @returns {boolean}
149
+ */
150
+ hasItem(name) {
151
+ const _name = typeof name === 'string' ? name.trim() : '';
152
+ return this.#_items.has(_name);
153
+ }
154
+
155
+ /**
156
+ * Checks if any items exists.
157
+ * @returns {boolean}
158
+ */
159
+ hasItems() {
160
+ return this.#_items.size > 0;
161
+ }
162
+
163
+ /**
164
+ * Returns an item by its name.
165
+ * @param {string} name - an element name
166
+ * @returns {?HTMLElement}
167
+ */
168
+ getItem(name) {
169
+ const _name = typeof name === 'string' ? name.trim() : '';
170
+ const item = this.#_items.has(_name) ? this.#_items.get(_name) : null;
171
+ return isHTMLElement(item) ? item : null;
172
+ }
173
+
174
+ /**
175
+ * Adds an item to an instance members.
176
+ * @param {string} name - an element name
177
+ * @param {HTMLElement} item - an element
178
+ * @param {boolean} [opt=false] - flag indicating a force mode
179
+ * @returns {boolean}
180
+ */
181
+ addItem(name, item, opt) {
182
+ const _name = typeof name === 'string' ? name.trim() : '';
183
+ let isSUCCEED = false;
184
+ if (_name !== '' && isHTMLElement(item)) {
185
+ const force = typeof opt === 'boolean' ? opt : false;
186
+ if (force || !this.#_items.has(_name)) {
187
+ this.#_items.set(_name, item);
188
+ isSUCCEED = true;
189
+ };
190
+ };
191
+ return isSUCCEED;
192
+ }
193
+
194
+ /**
195
+ * Deletes an item from an instance members.
196
+ * @param {string} name - an element name
197
+ * @returns {boolean}
198
+ * @todo check if item is shown
199
+ */
200
+ delItem(name) {
201
+ let _name = '';
202
+ let isSUCCEED = (
203
+ typeof name === 'string'
204
+ && ((_name = name.trim()) !== '')
205
+ );
206
+ if (isSUCCEED) {
207
+ this.#_items.delete(_name);
208
+ // // TODO: check if item is shown
209
+ };
210
+ return isSUCCEED;
211
+ }
212
+
213
+ /**
214
+ * Shows an item.
215
+ * @param {string} name - an element name
216
+ * @returns {boolean}
217
+ */
218
+ showItem(name) {
219
+ const item = this.getItem(name);
220
+ const isSUCCEED = this.#_host && item ? true : false;
221
+ if (isSUCCEED) this.#_host.append(item);
222
+ return isSUCCEED;
223
+ }
224
+
225
+ /**
226
+ * Shows a default item.
227
+ * @returns {boolean}
228
+ */
229
+ showDefItem() {
230
+ return this.showItem(this.#_defItem);
231
+ }
232
+
233
+ /**
234
+ * Hides an item.
235
+ * @param {string} name - an element name
236
+ * @returns {boolean}
237
+ */
238
+ hideItem(name) {
239
+ const item = this.getItem(name);
240
+ const isSUCCEED = this.#_host && item ? true : false;
241
+ if (isSUCCEED && this.#_host.contains(item)) item.remove();
242
+ return isSUCCEED;
243
+ }
244
+
245
+ /**
246
+ * Hides a default item.
247
+ * @returns {boolean}
248
+ */
249
+ hideDefItem() {
250
+ return this.hideItem(this.#_defItem);
251
+ }
252
+
253
+ /**
254
+ * Adds an items to an instance members.
255
+ * @param {(Array|OBJ_stubEList)} data - an array of entries or special object
256
+ * @param {(boolean|OPT_ldstubs)} [opt] - an options
257
+ * @returns {number}
258
+ * @todo [since 0.0.25] deprecate use of `opt` as `boolean`
259
+ * @todo [since v0.0.26] for `OPT_ldstubs` a `defaultItem`-option deprecated
260
+ */
261
+ loadItems(data, opt) {
262
+ /** @type {OBJ_stubEList} */
263
+ let {
264
+ items,
265
+ defaultItem,
266
+ } = isPlainObject(data) ? data : { items: data };
267
+ /** @type {OPT_ldstubs} */
268
+ let _options = isPlainObject(opt) ? opt : { useClear: opt };
269
+ let {
270
+ useClear,
271
+ force,
272
+ } = _options;
273
+ if (typeof useClear !== 'boolean') useClear = true;
274
+ if (typeof force !== 'boolean') force = false;
275
+ if (defaultItem === undefined) defaultItem = _options.defaultItem; /* deprecated */
276
+ const setDefs = defaultItem !== undefined;
277
+ let count = 0;
278
+ if (isArray(items)) {
279
+ if (useClear) this.clear();
280
+ items.forEach((obj) => {
281
+ if (isArray(obj)) {
282
+ const [ name, item ] = obj;
283
+ if (this.addItem(name, item, force)) count++;
284
+ } else if (isPlainObject(obj)) {
285
+ const { name, item } = obj;
286
+ if (this.addItem(name, item, force)) count++;
287
+ };
288
+ });
289
+ };
290
+ if (setDefs && count > 0) this.setDefItem(defaultItem);
291
+ return count;
292
+ }
293
+
294
+ };
295
+
296
+ // === module exports block ===
297
+
298
+ exports.THtmlStubItemsSet = THtmlStubItemsSet;
@@ -0,0 +1,66 @@
1
+ // [v0.1.064-20250831]
2
+
3
+ // === module init block ===
4
+
5
+ const {
6
+ eventHelper, // [!] not oficialy exported yet
7
+ } = require('@cntwg/html-helper');
8
+
9
+ // === module inner block ===
10
+
11
+ const {
12
+ pushEventHandler, removeEventHandler,
13
+ triggerEventHandler,
14
+ } = eventHelper;
15
+
16
+ // === module main block ===
17
+
18
+ /***
19
+ * (* constant definitions *)
20
+ */
21
+
22
+ /***
23
+ * (* function definitions *)
24
+ */
25
+
26
+ /**
27
+ * @function readOnClickEventInfo
28
+ * @param {object}
29
+ * @returns {object}
30
+ * @inner
31
+ */
32
+ function readOnClickEventInfo(e) {
33
+ let item = null;
34
+ const { eventPhase, detail: onClickNum } = e;
35
+ //console.log('CHECK: e => ditail:['+onClickNum+']');
36
+ //console.log('CHECK: e => phase:['+eventPhase+']');
37
+ switch (eventPhase) {
38
+ //*case 1:
39
+ //* // NOTE: currently on eventPhase = 2 and 3
40
+ case 2: {
41
+ /**/// capturing stage
42
+ item = e.target;
43
+ break;
44
+ }
45
+ case 3: {
46
+ /**/// bubblig stage
47
+ item = e.currentTarget;
48
+ break;
49
+ }
50
+ default: {}
51
+ };
52
+ return { item, onClickNum };
53
+ };
54
+
55
+ /***
56
+ * (* class definitions *)
57
+ */
58
+
59
+ // === module exports block ===
60
+
61
+ module.exports.readOnClickEventInfo = readOnClickEventInfo;
62
+
63
+ // * re-exported *
64
+ module.exports.pushEventHandler = pushEventHandler;
65
+ module.exports.removeEventHandler = removeEventHandler;
66
+ module.exports.triggerEventHandler = triggerEventHandler;
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@cntwg/html-ctrls-lists",
3
+ "version": "0.0.27",
4
+ "description": "An HTML-form component: lists",
5
+ "author": "ygracs <cs70th-om@rambler.ru>",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://gitlab.com/cntwg/html-ctrls-lists.git"
10
+ },
11
+ "keywords": [
12
+ "electron",
13
+ "html",
14
+ "component"
15
+ ],
16
+ "main": "./index.js",
17
+ "files": [
18
+ "doc/*.md",
19
+ "lib/lists-stubs.js",
20
+ "lib/lists-btn.js",
21
+ "lib/list.js",
22
+ "lib/mod-hfunc.js",
23
+ "index.js",
24
+ "CHANGELOG.md"
25
+ ],
26
+ "scripts": {
27
+ "test": "jest",
28
+ "test-lc2:bs": "jest THtmlItemsListController/base",
29
+ "test-lc2:ec": "jest THtmlItemsListController/events",
30
+ "build-doc-md": "jsdoc2md",
31
+ "build-doc-html": "jsdoc"
32
+ },
33
+ "imports": {
34
+ "#lib/*": "./lib/*",
35
+ "#test-dir/*": "./__test__/*"
36
+ },
37
+ "dependencies": {
38
+ "@cntwg/html-ctrls-buttons": "^0.0.27",
39
+ "@cntwg/html-helper": "^0.0.27",
40
+ "@ygracs/bsfoc-lib-js": "^0.3.0",
41
+ "@ygracs/lists-lib-js": "^0.1.0"
42
+ },
43
+ "devDependencies": {
44
+ "jest": "^30.2.0",
45
+ "jest-environment-jsdom": "^30.2.0",
46
+ "jsdoc-to-markdown": "^9.1.2",
47
+ "minimist": "^1.2.8"
48
+ }
49
+ }