@yuneta/gobj-ui 2.6.0 → 3.0.0

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/src/c_yui_tabs.js DELETED
@@ -1,487 +0,0 @@
1
- /***********************************************************************
2
- * c_yui_tabs.js
3
- *
4
- * Container of sub-containers, selected by tabs
5
- *
6
- * The tabs is created when a child is append, and remove when child is destroyed.
7
- * This child must have another subscriber than this yui_tabs.
8
- *
9
- * The child must manage the sub-container and must supply next attributes
10
- * in order to create and select the tab:
11
- *
12
- * "href": (optional) Href to select the tab.
13
- * If href attr not set or not exists then is set internally:
14
- * `{yui_tabs_name}?{service_name_of_child}`
15
- * |-> yui_tabs_name must have '#' as prefix !!
16
- *
17
- * yui_ui_routing manage the href.
18
- *
19
- * "label": String or html? insert as text in the tab.
20
- * "icon": Icon to show in the tab.
21
- * "image": Image to show in the tab.
22
- *
23
- * Use icon or image, not both
24
- *
25
- * Copyright (c) 2025, ArtGins.
26
- * All Rights Reserved.
27
- ***********************************************************************/
28
- import {
29
- SDATA,
30
- SDATA_END,
31
- data_type_t,
32
- gclass_create,
33
- log_error,
34
- gobj_subscribe_event,
35
- gobj_read_pointer_attr,
36
- gobj_parent,
37
- createElement2,
38
- gobj_write_attr,
39
- gobj_read_attr,
40
- gobj_send_event,
41
- gobj_name,
42
- gobj_read_str_attr,
43
- empty_string,
44
- clean_name,
45
- gobj_find_service,
46
- gobj_short_name,
47
- gobj_write_str_attr,
48
- gobj_has_attr, gobj_is_service, gobj_stop_children,
49
- } from "@yuneta/gobj-js";
50
-
51
-
52
- /***************************************************************
53
- * Constants
54
- ***************************************************************/
55
- const GCLASS_NAME = "C_YUI_TABS";
56
-
57
- /***************************************************************
58
- * Data
59
- ***************************************************************/
60
- /*
61
- * Helpers of Bulma tabs
62
- * Style: is-boxed
63
- * Sizes: is-small is-medium is-large
64
- * Alignment: is-centered is-right
65
- * Mutually exclusive: is-toggle is-toggle-rounded
66
- * Whole width available: is-fullwidth
67
- */
68
- const attrs_table = [
69
- SDATA(data_type_t.DTP_POINTER, "subscriber", 0, null, "Subscriber of output events"),
70
-
71
- SDATA(data_type_t.DTP_STRING, "tabs_style", 0, "is-toggle is-medium is-centered is-toggle-rounded", "Bulma tabs style, see https://bulma.io/documentation/components/tabs/"),
72
- SDATA(data_type_t.DTP_STRING, "image_style", 0, "image is-medium", "Image bulma style, see https://bulma.io/documentation/elements/image/"),
73
- SDATA(data_type_t.DTP_STRING, "icon_style", 0, "icon is-medium", "Icon bulma style, see https://bulma.io/documentation/elements/icon/"),
74
-
75
- /*---------------- UI/Routing ----------------*/
76
- SDATA(data_type_t.DTP_POINTER, "$container", 0, null, "HTMLElement root, show/hide managed by external routing"),
77
- SDATA(data_type_t.DTP_POINTER, "$current_item", 0, null, "Current item selected"),
78
- SDATA(data_type_t.DTP_STRING, "last_selection", 0, "", "Last href selected"),
79
- SDATA_END()
80
- ];
81
-
82
- let PRIVATE_DATA = {
83
- groups: null
84
- };
85
-
86
- let __gclass__ = null;
87
-
88
-
89
-
90
-
91
- /******************************
92
- * Framework Methods
93
- ******************************/
94
-
95
-
96
-
97
-
98
- /***************************************************************
99
- * Framework Method: Create
100
- ***************************************************************/
101
- function mt_create(gobj)
102
- {
103
- build_ui(gobj);
104
-
105
- /*
106
- * CHILD subscription model
107
- */
108
- let subscriber = gobj_read_pointer_attr(gobj, "subscriber");
109
- if(!subscriber) {
110
- subscriber = gobj_parent(gobj);
111
- }
112
- gobj_subscribe_event(gobj, null, {}, subscriber);
113
- }
114
-
115
- /***************************************************************
116
- * Framework Method: Start
117
- ***************************************************************/
118
- function mt_start(gobj)
119
- {
120
- /*
121
- * Active the last_selection
122
- */
123
- // gobj_send_event(gobj, "EV_SHOW", {href: gobj_read_attr(gobj, "last_selection")}, gobj);
124
- }
125
-
126
- /***************************************************************
127
- * Framework Method: Stop
128
- ***************************************************************/
129
- function mt_stop(gobj)
130
- {
131
- gobj_stop_children(gobj);
132
- }
133
-
134
- /***************************************************************
135
- * Framework Method: Destroy
136
- ***************************************************************/
137
- function mt_destroy(gobj)
138
- {
139
- destroy_ui(gobj);
140
- }
141
-
142
- /***************************************************************
143
- * Framework Method: Child added
144
- ***************************************************************/
145
- function mt_child_added(gobj, child)
146
- {
147
- let href = "";
148
- if(gobj_has_attr(child, "href")) {
149
- href = gobj_read_str_attr(child, "href");
150
- }
151
- if(empty_string(href)) {
152
- href = `${gobj_name(gobj)}?${clean_name(gobj_name(child))}`;
153
- }
154
-
155
- add_tab(gobj, child, href);
156
- }
157
-
158
- /***************************************************************
159
- * Framework Method: Child removed
160
- ***************************************************************/
161
- function mt_child_removed(gobj, child)
162
- {
163
- remove_tab(gobj, child);
164
- }
165
-
166
-
167
-
168
- /***************************
169
- * Local Methods
170
- ***************************/
171
-
172
-
173
-
174
-
175
- /************************************************************
176
- * Build UI
177
- ************************************************************/
178
- function build_ui(gobj)
179
- {
180
- /*----------------------------------------------*
181
- * Layout Schema
182
- *----------------------------------------------*/
183
- let tabs_style = gobj_read_attr(gobj, "tabs_style");
184
- let $container = createElement2(
185
- // Don't use is-flex, don't work well with is-hidden
186
- ['div', {class: `C_YUI_TABS`, style: 'height:100%; display:flex; flex-direction:column;'}, [
187
- ['div', {class: 'is-flex-grow-0'}, [
188
- ['div', {class: `tabs ${tabs_style}`, style: ''}, [
189
- ['ul', {}]
190
- ]],
191
- ]],
192
- ['div', {class: 'is-flex-grow-1 sub-container', style: 'height:100%;min-height:0;'}, []
193
- ]
194
- ]]
195
- );
196
- gobj_write_attr(gobj, "$container", $container);
197
- }
198
-
199
- /************************************************************
200
- * Destroy UI
201
- ************************************************************/
202
- function destroy_ui(gobj)
203
- {
204
- let $container = gobj_read_attr(gobj, "$container");
205
- if($container) {
206
- if($container.parentNode) {
207
- $container.parentNode.removeChild($container);
208
- }
209
- gobj_write_attr(gobj, "$container", null);
210
- }
211
- }
212
-
213
- /************************************************************
214
- * Add tab
215
- ************************************************************/
216
- function add_tab(gobj, child, href)
217
- {
218
- let text = gobj_read_attr(child, "label");
219
- let icon = gobj_read_attr(child, "icon");
220
- let image = gobj_read_attr(child, "image");
221
-
222
- let $container = gobj_read_attr(gobj, "$container");
223
- let $tabs = $container.querySelector('ul');
224
-
225
- /*
226
- * Create li a
227
- */
228
- let $item = createElement2(
229
- ['li', {class: ''}, [ // is-active
230
- ['a', {href: href}]
231
- ]]
232
- );
233
- $tabs.appendChild($item);
234
- $item.gobj = child; // Cross-reference
235
-
236
- /*
237
- * TAB: Add icon/text to a
238
- */
239
- let $a = $item.querySelector('a');
240
-
241
- /*
242
- * Add image
243
- */
244
- if(!empty_string(image)) {
245
- let image_style = gobj_read_attr(gobj, "image_style");
246
- $a.appendChild(
247
- createElement2(
248
- ['span', {class: `${image_style}`},
249
- ['img', {src: `${image}`, alt: `${image}`}]
250
- ]
251
- )
252
- );
253
- } else if(!empty_string(icon)) {
254
- let icon_style = gobj_read_attr(gobj, "icon_style");
255
- $a.appendChild(
256
- createElement2(
257
- ['span', {class: `${icon_style}`},
258
- ['i', {class: `${icon}`}]
259
- ]
260
- )
261
- );
262
- }
263
-
264
- /*
265
- * TAB: Add text
266
- */
267
- $a.appendChild(
268
- createElement2(['span', {i18n: text, class: 'is-hidden-mobile'}, text])
269
- );
270
-
271
- /*
272
- * SUB-CONTAINER, add child content
273
- */
274
- let $sub_container = $container.querySelector('.sub-container');
275
-
276
- let $child_content = gobj_read_attr(child, "$container");
277
- $child_content.classList.add("is-hidden");
278
- $sub_container.appendChild($child_content);
279
- }
280
-
281
- /************************************************************
282
- * Destroy UI
283
- ************************************************************/
284
- function remove_tab(gobj, gobj2)
285
- {
286
- let id = gobj_name(gobj2);
287
- let $container = gobj_read_attr(gobj, "$container");
288
- let $a = $container.querySelector(`a[href="${id}"]`);
289
- if($a) {
290
- let $li = $a.parentNode;
291
- if($li) {
292
- $li.classList.remove('is-active');
293
- if($li.parentNode) {
294
- $li.parentNode.removeChild($li);
295
- }
296
- }
297
- }
298
-
299
- /*
300
- * SUB-CONTAINER, remove child content
301
- */
302
- // Se borra al destroy the child
303
- }
304
-
305
-
306
-
307
-
308
- /***************************
309
- * Actions
310
- ***************************/
311
-
312
-
313
-
314
-
315
- /************************************************************
316
- * Parent (routing) inform us that we go showing
317
- *
318
- * {
319
- * href: href
320
- * }
321
- *
322
- * WARNING href is the full path,
323
- * the path relative to this gobj is the right part of split href by '?'
324
- ************************************************************/
325
- function ac_show(gobj, event, kw, src)
326
- {
327
- let href = kw.href;
328
-
329
- let $container = gobj_read_attr(gobj, "$container");
330
- let $a = $container.querySelector(`a[href="${href}"]`);
331
- let $current_item = gobj_read_attr(gobj, "$current_item");
332
- if($a) {
333
- /*
334
- * href pointing to inside gobj (with ? right part)
335
- */
336
- if($current_item) {
337
- $current_item.classList.remove('is-active');
338
- }
339
- $current_item = $a.parentNode;
340
- gobj_write_attr(gobj, "$current_item", $current_item);
341
- $current_item.classList.add('is-active');
342
- } else {
343
- /*
344
- * href pointing without ? right part, select the first item
345
- */
346
- if(!$current_item) {
347
- // Get the first item
348
- $current_item = $container.querySelector(`li`);
349
- gobj_write_attr(gobj, "$current_item", $current_item);
350
- }
351
- if($current_item) {
352
- $current_item.classList.add('is-active');
353
- }
354
- }
355
-
356
- /*
357
- * Save last selection, the topics can be not arrived yet.
358
- */
359
- gobj_write_attr(gobj, "last_selection", href);
360
-
361
- /*
362
- * Show sub-container
363
- */
364
- if($current_item) {
365
- let gobj2 = $current_item.gobj;
366
- if(gobj2) {
367
- let $sub_container = gobj_read_attr(gobj2, "$container");
368
- if($sub_container) {
369
- $sub_container.classList.remove("is-hidden");
370
- }
371
- gobj_send_event(gobj2, "EV_SHOW", kw, gobj);
372
- }
373
- }
374
-
375
- return 0;
376
- }
377
-
378
- /************************************************************
379
- * Parent (routing) inform us that we go hidden
380
- ************************************************************/
381
- function ac_hide(gobj, event, kw, src)
382
- {
383
- /*
384
- * Deactivate tab
385
- */
386
- let $current_item = gobj_read_attr(gobj, "$current_item");
387
- if($current_item) {
388
- $current_item.classList.remove('is-active');
389
- }
390
-
391
- /*
392
- * Hide sub-container
393
- */
394
- if($current_item) {
395
- let gobj2 = $current_item.gobj;
396
- if(gobj2) {
397
- let $sub_container = gobj_read_attr(gobj2, "$container");
398
- if($sub_container) {
399
- $sub_container.classList.add("is-hidden");
400
- }
401
- gobj_send_event(gobj2, "EV_HIDE", {}, gobj);
402
- }
403
- }
404
- return 0;
405
- }
406
-
407
-
408
-
409
-
410
-
411
- /***************************
412
- * FSM
413
- ***************************/
414
-
415
-
416
-
417
-
418
- /*---------------------------------------------*
419
- * Global methods table
420
- *---------------------------------------------*/
421
- const gmt = {
422
- mt_create: mt_create,
423
- mt_start: mt_start,
424
- mt_stop: mt_stop,
425
- mt_destroy: mt_destroy,
426
- mt_child_removed: mt_child_removed,
427
- mt_child_added: mt_child_added,
428
- };
429
-
430
- /***************************************************************
431
- * Create the GClass
432
- ***************************************************************/
433
- function create_gclass(gclass_name)
434
- {
435
- if(__gclass__) {
436
- log_error(`GClass ALREADY created: ${gclass_name}`);
437
- return -1;
438
- }
439
-
440
- /*---------------------------------------------*
441
- * States
442
- *---------------------------------------------*/
443
- const states = [
444
- ["ST_IDLE", [
445
- ["EV_SHOW", ac_show, null],
446
- ["EV_HIDE", ac_hide, null]
447
- ]]
448
- ];
449
-
450
- /*---------------------------------------------*
451
- * Events
452
- *---------------------------------------------*/
453
- const event_types = [
454
- ["EV_SHOW", 0],
455
- ["EV_HIDE", 0]
456
- ];
457
-
458
- __gclass__ = gclass_create(
459
- gclass_name,
460
- event_types,
461
- states,
462
- gmt,
463
- 0, // lmt,
464
- attrs_table,
465
- PRIVATE_DATA,
466
- 0, // authz_table,
467
- 0, // command_table,
468
- 0, // s_user_trace_level
469
- 0 // gclass_flag
470
- );
471
-
472
- if(!__gclass__) {
473
- return -1;
474
- }
475
-
476
- return 0;
477
- }
478
-
479
- /***************************************************************
480
- * Register GClass
481
- ***************************************************************/
482
- function register_c_yui_tabs()
483
- {
484
- return create_gclass(GCLASS_NAME);
485
- }
486
-
487
- export { register_c_yui_tabs };
package/src/themes.js DELETED
@@ -1,215 +0,0 @@
1
- /*
2
- *
3
- * This file has sample functions copied from bulma documentation source code.
4
- *
5
- */
6
-
7
- function themes() {
8
- // MODALS
9
- // Functions to open and close a modal
10
- function openModal($el) {
11
- $el.classList.add("is-active");
12
- }
13
-
14
- function closeModal($el) {
15
- $el.classList.remove("is-active");
16
- }
17
-
18
- function closeAllModals() {
19
- (document.querySelectorAll(".modal") || []).forEach(($modal) => {
20
- closeModal($modal);
21
- });
22
- }
23
-
24
- (document.querySelectorAll(".js-modal-trigger") || []).forEach(($trigger) => {
25
- const modal = $trigger.dataset.target;
26
- const $target = document.getElementById(modal);
27
-
28
- $trigger.addEventListener("click", () => {
29
- openModal($target);
30
- });
31
- });
32
-
33
- (
34
- document.querySelectorAll(
35
- ".modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button"
36
- ) || []
37
- ).forEach(($close) => {
38
- const $target = $close.closest(".modal");
39
-
40
- $close.addEventListener("click", () => {
41
- closeModal($target);
42
- });
43
- });
44
-
45
- document.addEventListener("keydown", (event) => {
46
- if (event.key === "Escape") {
47
- closeAllModals();
48
- }
49
- });
50
-
51
- // DROPDOWNS
52
- const $clickableDropdowns = document.querySelectorAll(
53
- ".dropdown:not(.is-hoverable)"
54
- );
55
-
56
- if ($clickableDropdowns.length > 0) {
57
- $clickableDropdowns.forEach(($dropdown) => {
58
- $dropdown.querySelector("button").addEventListener("click", (event) => {
59
- event.stopPropagation();
60
- $dropdown.classList.toggle("is-active");
61
- });
62
- });
63
-
64
- document.addEventListener("click", () => {
65
- closeDropdowns();
66
- });
67
- }
68
-
69
- function closeDropdowns() {
70
- $clickableDropdowns.forEach(($el) => {
71
- $el.classList.remove("is-active");
72
- });
73
- }
74
-
75
- // THEMES
76
- const STORAGE_KEY = "bulma-theme";
77
- const SYSTEM_THEME = "system";
78
- const DEFAULT_THEME = "light";
79
-
80
- const state = {
81
- chosenTheme: SYSTEM_THEME, // light|dark|system
82
- appliedTheme: DEFAULT_THEME, // light|dark
83
- OSTheme: null, // light|dark|null
84
- };
85
-
86
- const $themeCycle = document.getElementById("js-cycle");
87
- const $themeSwitchers = document.querySelectorAll(".js-themes button");
88
- const $darkmodes = document.querySelectorAll(".js-darkmode");
89
-
90
- const updateThemeUI = () => {
91
- if (state.appliedTheme === "light") {
92
- $themeCycle.className = "bd-cycle js-burger is-sun";
93
- } else {
94
- $themeCycle.className = "bd-cycle js-burger is-moon";
95
- }
96
-
97
- $themeSwitchers.forEach((el) => {
98
- const swatchTheme = el.dataset.scheme;
99
-
100
- if (state.chosenTheme === swatchTheme) {
101
- el.classList.add("is-active");
102
- } else {
103
- el.classList.remove("is-active");
104
- }
105
- });
106
- };
107
-
108
- const setTheme = (theme, save = true) => {
109
- state.chosenTheme = theme;
110
- state.appliedTheme = theme;
111
-
112
- if (theme === SYSTEM_THEME) {
113
- state.appliedTheme = state.OSTheme;
114
- document.documentElement.removeAttribute("data-theme");
115
- window.localStorage.removeItem(STORAGE_KEY);
116
- } else {
117
- document.documentElement.setAttribute("data-theme", theme);
118
-
119
- if (save) {
120
- window.localStorage.setItem(STORAGE_KEY, theme);
121
- }
122
- }
123
-
124
- updateThemeUI();
125
- };
126
-
127
- const toggleTheme = () => {
128
- if (state.appliedTheme === "light") {
129
- setTheme("dark");
130
- } else {
131
- setTheme("light");
132
- }
133
- };
134
-
135
- const detectOSTheme = () => {
136
- if (!window.matchMedia) {
137
- // matchMedia method not supported
138
- return DEFAULT_THEME;
139
- }
140
-
141
- if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
142
- // OS theme setting detected as dark
143
- return "dark";
144
- } else if (window.matchMedia("(prefers-color-scheme: light)").matches) {
145
- return "light";
146
- }
147
-
148
- return DEFAULT_THEME;
149
- };
150
-
151
- // On load, check if any preference was saved
152
- const localTheme = window.localStorage.getItem(STORAGE_KEY);
153
- state.OSTheme = detectOSTheme();
154
-
155
- if (localTheme) {
156
- setTheme(localTheme, false);
157
- } else {
158
- setTheme(SYSTEM_THEME);
159
- }
160
-
161
- // Event listeners
162
- $themeSwitchers.forEach((el) => {
163
- el.addEventListener("click", () => {
164
- const theme = el.dataset.scheme;
165
- setTheme(theme);
166
- });
167
- });
168
-
169
- $darkmodes.forEach((el) => {
170
- el.addEventListener("click", (e) => {
171
- e.preventDefault();
172
- toggleTheme();
173
- });
174
- });
175
-
176
- window
177
- .matchMedia("(prefers-color-scheme: dark)")
178
- .addEventListener("change", (event) => {
179
- const theme = event.matches ? "dark" : "light";
180
- state.OSTheme = theme;
181
- setTheme(theme);
182
- });
183
-
184
- // BURGERS
185
- const $burgers = document.querySelectorAll(".js-burger");
186
-
187
- $burgers.forEach((el) => {
188
- el.addEventListener("click", (e) => {
189
- e.preventDefault();
190
- const targetID = el.dataset.target;
191
- const $target = document.getElementById(targetID);
192
- el.classList.toggle("is-active");
193
- $target.classList.toggle("is-active");
194
- e.stopPropagation();
195
- });
196
- });
197
-
198
- const onClickOutside = (menuSelector) => {
199
- document.addEventListener("click", (e) => {
200
- const menus = document.querySelectorAll(menuSelector);
201
-
202
- menus.forEach((el) => {
203
- if (!el.contains(e.target) && el.classList.contains("is-active")) {
204
- el.classList.remove("is-active");
205
- }
206
- });
207
- });
208
- };
209
-
210
- onClickOutside(".js-menu");
211
- }
212
-
213
- export {
214
- themes
215
- };