@yuneta/gobj-ui 1.0.1 → 2.2.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/README.md +40 -363
- package/dist/gobj-ui.cjs.js +11154 -5506
- package/dist/gobj-ui.es.js +11131 -5508
- package/index.js +41 -14
- package/package.json +11 -9
- package/src/c_g6_nodes_tree.js +6 -1
- package/src/c_yui_form.js +1 -1
- package/src/c_yui_gobj_tree_js.js +1 -1
- package/src/c_yui_json_graph.js +1 -1
- package/src/c_yui_main.js +3 -3
- package/src/c_yui_map.js +6 -1
- package/src/c_yui_nav.js +881 -0
- package/src/c_yui_pager.js +545 -0
- package/src/c_yui_routing.css +1 -1
- package/src/c_yui_routing.js +1 -1
- package/src/c_yui_shell.css +571 -0
- package/src/c_yui_shell.js +2474 -0
- package/src/c_yui_tabs.js +1 -1
- package/src/c_yui_treedb_graph.js +35 -9
- package/src/c_yui_treedb_topic_with_form.js +1 -1
- package/src/c_yui_treedb_topics.js +36 -8
- package/src/c_yui_uplot.js +1 -1
- package/src/c_yui_window.js +242 -21
- package/src/c_yui_window_manager.js +602 -0
- package/src/c_yui_wizard.js +612 -0
- package/src/pager_helpers.js +138 -0
- package/src/pager_helpers.test.js +140 -0
- package/src/route_resolver.js +53 -0
- package/src/route_resolver.test.js +82 -0
- package/src/shell_focus_trap.js +123 -0
- package/src/shell_focus_trap.test.js +299 -0
- package/src/shell_modals.js +445 -0
- package/src/shell_show_on.js +91 -0
- package/src/shell_show_on.test.js +86 -0
- package/src/shell_toolbar_helpers.js +221 -0
- package/src/shell_toolbar_helpers.test.js +207 -0
- package/src/tabulator.css +53 -0
- package/src/wizard_helpers.js +117 -0
- package/src/wizard_helpers.test.js +122 -0
- package/src/yui_dev.js +1257 -362
- package/src/yui_icons.css +5 -0
- package/src/yui_inputs.css +32 -0
- package/src/yui_inputs.js +71 -0
- package/vite-plugin-yuneta-html.js +2 -2
- package/skeleton/config.json +0 -20
- package/skeleton/index.html +0 -37
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/***********************************************************************
|
|
2
|
+
* wizard_helpers.test.mjs
|
|
3
|
+
*
|
|
4
|
+
* Unit tests for the pure step logic of C_YUI_WIZARD.
|
|
5
|
+
* Run with: node --test tests/
|
|
6
|
+
***********************************************************************/
|
|
7
|
+
import { test, expect } from "vitest";
|
|
8
|
+
import {
|
|
9
|
+
wizard_clamp_index,
|
|
10
|
+
wizard_next_index,
|
|
11
|
+
wizard_prev_index,
|
|
12
|
+
wizard_step_model,
|
|
13
|
+
wizard_accumulate,
|
|
14
|
+
wizard_should_validate,
|
|
15
|
+
} from "./wizard_helpers.js";
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/*============================================================
|
|
19
|
+
* clamp / next / prev
|
|
20
|
+
*============================================================*/
|
|
21
|
+
test("clamp: negative -> 0, overflow -> count-1, empty -> 0", () => {
|
|
22
|
+
expect(wizard_clamp_index(-3, 4)).toBe(0);
|
|
23
|
+
expect(wizard_clamp_index(9, 4)).toBe(3);
|
|
24
|
+
expect(wizard_clamp_index(2, 4)).toBe(2);
|
|
25
|
+
expect(wizard_clamp_index(0, 0)).toBe(0);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("next/prev never wrap", () => {
|
|
29
|
+
expect(wizard_next_index(0, 3)).toBe(1);
|
|
30
|
+
expect(wizard_next_index(2, 3)).toBe(2); // already last
|
|
31
|
+
expect(wizard_prev_index(0, 3)).toBe(0); // already first
|
|
32
|
+
expect(wizard_prev_index(2, 3)).toBe(1);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
/*============================================================
|
|
37
|
+
* wizard_step_model
|
|
38
|
+
*============================================================*/
|
|
39
|
+
const STEPS = [
|
|
40
|
+
{ id: "a", title: "Step A" },
|
|
41
|
+
{ id: "b", title: "Step B" },
|
|
42
|
+
{ id: "c", title: "Step C" },
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
test("first step: is_first, back hidden, primary='next'", () => {
|
|
46
|
+
const m = wizard_step_model(STEPS, 0, {
|
|
47
|
+
allow_back: true, confirm_label: "confirm", next_label: "next",
|
|
48
|
+
});
|
|
49
|
+
expect(m.idx).toBe(0);
|
|
50
|
+
expect(m.count).toBe(3);
|
|
51
|
+
expect(m.id).toBe("a");
|
|
52
|
+
expect(m.is_first).toBe(true);
|
|
53
|
+
expect(m.is_last).toBe(false);
|
|
54
|
+
expect(m.show_back).toBe(false); // first step, even if allow_back
|
|
55
|
+
expect(m.primary_label).toBe("next");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("middle step: back shown when allow_back", () => {
|
|
59
|
+
expect(wizard_step_model(STEPS, 1, { allow_back: true }).show_back).toBe(true);
|
|
60
|
+
expect(wizard_step_model(STEPS, 1, { allow_back: false }).show_back).toBe(false);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("last step: is_last, primary='confirm'", () => {
|
|
64
|
+
const m = wizard_step_model(STEPS, 2, {
|
|
65
|
+
allow_back: true, confirm_label: "confirm", next_label: "next",
|
|
66
|
+
});
|
|
67
|
+
expect(m.is_last).toBe(true);
|
|
68
|
+
expect(m.primary_label).toBe("confirm");
|
|
69
|
+
expect(m.title).toBe("Step C");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("out-of-range idx is clamped by the model", () => {
|
|
73
|
+
const m = wizard_step_model(STEPS, 99, {});
|
|
74
|
+
expect(m.idx).toBe(2);
|
|
75
|
+
expect(m.is_last).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("default labels when opts omitted", () => {
|
|
79
|
+
const m = wizard_step_model(STEPS, 0, {});
|
|
80
|
+
expect(m.primary_label).toBe("next");
|
|
81
|
+
const last = wizard_step_model(STEPS, 2, {});
|
|
82
|
+
expect(last.primary_label).toBe("confirm");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
/*============================================================
|
|
87
|
+
* wizard_accumulate (pure, immutable)
|
|
88
|
+
*============================================================*/
|
|
89
|
+
test("accumulate merges flat and keeps per-step, no mutation", () => {
|
|
90
|
+
const a1 = wizard_accumulate(null, "a", { x: 1 });
|
|
91
|
+
const a2 = wizard_accumulate(a1, "b", { y: 2 });
|
|
92
|
+
expect(a2.merged).toEqual({ x: 1, y: 2 });
|
|
93
|
+
expect(a2.by_step).toEqual({ a: { x: 1 }, b: { y: 2 } });
|
|
94
|
+
// a1 untouched
|
|
95
|
+
expect(a1.merged).toEqual({ x: 1 });
|
|
96
|
+
expect(a1.by_step).toEqual({ a: { x: 1 } });
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("accumulate: later step overrides merged key but keeps by_step", () => {
|
|
100
|
+
const a1 = wizard_accumulate(null, "a", { v: "first" });
|
|
101
|
+
const a2 = wizard_accumulate(a1, "b", { v: "second" });
|
|
102
|
+
expect(a2.merged.v).toBe("second");
|
|
103
|
+
expect(a2.by_step.a.v).toBe("first");
|
|
104
|
+
expect(a2.by_step.b.v).toBe("second");
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("accumulate tolerates missing kw", () => {
|
|
108
|
+
const a = wizard_accumulate(null, "a");
|
|
109
|
+
expect(a.merged).toEqual({});
|
|
110
|
+
expect(a.by_step).toEqual({ a: {} });
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
/*============================================================
|
|
115
|
+
* wizard_should_validate
|
|
116
|
+
*============================================================*/
|
|
117
|
+
test("validate only when linear AND step has a gobj", () => {
|
|
118
|
+
expect(wizard_should_validate(true, true)).toBe(true);
|
|
119
|
+
expect(wizard_should_validate(true, false)).toBe(false);
|
|
120
|
+
expect(wizard_should_validate(false, true)).toBe(false);
|
|
121
|
+
expect(wizard_should_validate(false, false)).toBe(false);
|
|
122
|
+
});
|