@yuneta/gobj-ui 7.23.55 → 7.23.57
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/gobj-ui.cjs.js +14 -9
- package/dist/gobj-ui.es.js +14 -9
- package/package.json +1 -1
- package/src/c_yui_form.css +22 -0
- package/src/c_yui_form.js +21 -4
- package/src/form_toolbar_plan.js +18 -6
- package/src/form_toolbar_plan.test.js +19 -10
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -5900,18 +5900,18 @@ function refresh_clear($input) {
|
|
|
5900
5900
|
* Copyright (c) 2026, ArtGins.
|
|
5901
5901
|
* All Rights Reserved.
|
|
5902
5902
|
***********************************************************************/
|
|
5903
|
-
var LEFT_BUTTONS = [
|
|
5904
|
-
|
|
5903
|
+
var LEFT_BUTTONS = ["copy", "paste"];
|
|
5904
|
+
var RIGHT_BUTTONS = [
|
|
5905
5905
|
"undo",
|
|
5906
|
-
"clear"
|
|
5906
|
+
"clear",
|
|
5907
|
+
"save"
|
|
5907
5908
|
];
|
|
5908
|
-
var RIGHT_BUTTONS = ["copy", "paste"];
|
|
5909
5909
|
var DEFAULT_TOOLBAR = [
|
|
5910
|
-
"
|
|
5910
|
+
"copy",
|
|
5911
|
+
"paste",
|
|
5911
5912
|
"undo",
|
|
5912
5913
|
"clear",
|
|
5913
|
-
"
|
|
5914
|
-
"paste"
|
|
5914
|
+
"save"
|
|
5915
5915
|
];
|
|
5916
5916
|
/***************************************************************
|
|
5917
5917
|
* plan_toolbar(wanted) -> {left, right, unknown}
|
|
@@ -7515,7 +7515,7 @@ function create_form_field(gobj, $form, prefix, field_desc, { tag, inputType, na
|
|
|
7515
7515
|
$extend.dataset.form_tag = tag;
|
|
7516
7516
|
$extend.dataset.form_input_type = inputType;
|
|
7517
7517
|
$extend.classList.add("yui-form-data-input");
|
|
7518
|
-
apply_readonly_to_control(readonly, tag, $extend);
|
|
7518
|
+
apply_readonly_to_control(readonly, tag, inputType, $extend);
|
|
7519
7519
|
}
|
|
7520
7520
|
return $element;
|
|
7521
7521
|
}
|
|
@@ -7536,7 +7536,7 @@ function create_form_field(gobj, $form, prefix, field_desc, { tag, inputType, na
|
|
|
7536
7536
|
* control is still read -- unlike in a native submit, where it would
|
|
7537
7537
|
* be dropped.
|
|
7538
7538
|
******************************************************************/
|
|
7539
|
-
function apply_readonly_to_control(readonly, tag, $extend) {
|
|
7539
|
+
function apply_readonly_to_control(readonly, tag, inputType, $extend) {
|
|
7540
7540
|
if (!readonly) return;
|
|
7541
7541
|
switch (tag) {
|
|
7542
7542
|
case "select":
|
|
@@ -7547,6 +7547,11 @@ function apply_readonly_to_control(readonly, tag, $extend) {
|
|
|
7547
7547
|
case "select2":
|
|
7548
7548
|
$extend.setAttribute("disabled", "disabled");
|
|
7549
7549
|
if ($extend.tom_select) $extend.tom_select.disable();
|
|
7550
|
+
break;
|
|
7551
|
+
case "jsoneditor":
|
|
7552
|
+
$extend.classList.add("yui-jse-readonly");
|
|
7553
|
+
break;
|
|
7554
|
+
case "input": if (inputType === "color") $extend.setAttribute("disabled", "disabled");
|
|
7550
7555
|
}
|
|
7551
7556
|
}
|
|
7552
7557
|
/******************************************************************
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -5895,18 +5895,18 @@ function refresh_clear($input) {
|
|
|
5895
5895
|
* Copyright (c) 2026, ArtGins.
|
|
5896
5896
|
* All Rights Reserved.
|
|
5897
5897
|
***********************************************************************/
|
|
5898
|
-
var LEFT_BUTTONS = [
|
|
5899
|
-
|
|
5898
|
+
var LEFT_BUTTONS = ["copy", "paste"];
|
|
5899
|
+
var RIGHT_BUTTONS = [
|
|
5900
5900
|
"undo",
|
|
5901
|
-
"clear"
|
|
5901
|
+
"clear",
|
|
5902
|
+
"save"
|
|
5902
5903
|
];
|
|
5903
|
-
var RIGHT_BUTTONS = ["copy", "paste"];
|
|
5904
5904
|
var DEFAULT_TOOLBAR = [
|
|
5905
|
-
"
|
|
5905
|
+
"copy",
|
|
5906
|
+
"paste",
|
|
5906
5907
|
"undo",
|
|
5907
5908
|
"clear",
|
|
5908
|
-
"
|
|
5909
|
-
"paste"
|
|
5909
|
+
"save"
|
|
5910
5910
|
];
|
|
5911
5911
|
/***************************************************************
|
|
5912
5912
|
* plan_toolbar(wanted) -> {left, right, unknown}
|
|
@@ -7510,7 +7510,7 @@ function create_form_field(gobj, $form, prefix, field_desc, { tag, inputType, na
|
|
|
7510
7510
|
$extend.dataset.form_tag = tag;
|
|
7511
7511
|
$extend.dataset.form_input_type = inputType;
|
|
7512
7512
|
$extend.classList.add("yui-form-data-input");
|
|
7513
|
-
apply_readonly_to_control(readonly, tag, $extend);
|
|
7513
|
+
apply_readonly_to_control(readonly, tag, inputType, $extend);
|
|
7514
7514
|
}
|
|
7515
7515
|
return $element;
|
|
7516
7516
|
}
|
|
@@ -7531,7 +7531,7 @@ function create_form_field(gobj, $form, prefix, field_desc, { tag, inputType, na
|
|
|
7531
7531
|
* control is still read -- unlike in a native submit, where it would
|
|
7532
7532
|
* be dropped.
|
|
7533
7533
|
******************************************************************/
|
|
7534
|
-
function apply_readonly_to_control(readonly, tag, $extend) {
|
|
7534
|
+
function apply_readonly_to_control(readonly, tag, inputType, $extend) {
|
|
7535
7535
|
if (!readonly) return;
|
|
7536
7536
|
switch (tag) {
|
|
7537
7537
|
case "select":
|
|
@@ -7542,6 +7542,11 @@ function apply_readonly_to_control(readonly, tag, $extend) {
|
|
|
7542
7542
|
case "select2":
|
|
7543
7543
|
$extend.setAttribute("disabled", "disabled");
|
|
7544
7544
|
if ($extend.tom_select) $extend.tom_select.disable();
|
|
7545
|
+
break;
|
|
7546
|
+
case "jsoneditor":
|
|
7547
|
+
$extend.classList.add("yui-jse-readonly");
|
|
7548
|
+
break;
|
|
7549
|
+
case "input": if (inputType === "color") $extend.setAttribute("disabled", "disabled");
|
|
7545
7550
|
}
|
|
7546
7551
|
}
|
|
7547
7552
|
/******************************************************************
|
package/package.json
CHANGED
package/src/c_yui_form.css
CHANGED
|
@@ -57,3 +57,25 @@
|
|
|
57
57
|
overscroll-behavior: contain;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
|
|
61
|
+
/* A colour that cannot be changed. `readonly` does not apply to a colour
|
|
62
|
+
* input (the spec lists the types it applies to and colour is not one),
|
|
63
|
+
* so it is `disabled` instead -- and a disabled swatch is drawn by the
|
|
64
|
+
* browser as a pale ghost of itself, which loses the one thing the field
|
|
65
|
+
* is for: seeing the colour. Keep the swatch, lose the affordance. */
|
|
66
|
+
.C_YUI_FORM input[type="color"][disabled] {
|
|
67
|
+
opacity: 1;
|
|
68
|
+
cursor: default;
|
|
69
|
+
border-color: var(--bulma-border, #dbdbdb);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* A json document that cannot be edited. The editor is read-only for
|
|
73
|
+
* real (`readOnly` at build time); this is what makes it LOOK it --
|
|
74
|
+
* the menu bar is the whole invitation, and it offers nothing that
|
|
75
|
+
* reading needs. */
|
|
76
|
+
.C_YUI_FORM .yui-jse-readonly .jse-menu {
|
|
77
|
+
display: none !important;
|
|
78
|
+
}
|
|
79
|
+
.C_YUI_FORM .yui-jse-readonly {
|
|
80
|
+
background-color: var(--bulma-background, #f5f5f5);
|
|
81
|
+
}
|
package/src/c_yui_form.js
CHANGED
|
@@ -1450,7 +1450,7 @@ function create_form_field(
|
|
|
1450
1450
|
$extend.dataset.form_input_type = inputType;
|
|
1451
1451
|
$extend.classList.add('yui-form-data-input');
|
|
1452
1452
|
|
|
1453
|
-
apply_readonly_to_control(readonly, tag, $extend);
|
|
1453
|
+
apply_readonly_to_control(readonly, tag, inputType, $extend);
|
|
1454
1454
|
}
|
|
1455
1455
|
|
|
1456
1456
|
return $element;
|
|
@@ -1473,7 +1473,7 @@ function create_form_field(
|
|
|
1473
1473
|
* control is still read -- unlike in a native submit, where it would
|
|
1474
1474
|
* be dropped.
|
|
1475
1475
|
******************************************************************/
|
|
1476
|
-
function apply_readonly_to_control(readonly, tag, $extend)
|
|
1476
|
+
function apply_readonly_to_control(readonly, tag, inputType, $extend)
|
|
1477
1477
|
{
|
|
1478
1478
|
if(!readonly) {
|
|
1479
1479
|
return;
|
|
@@ -1491,9 +1491,26 @@ function apply_readonly_to_control(readonly, tag, $extend)
|
|
|
1491
1491
|
$extend.tom_select.disable();
|
|
1492
1492
|
}
|
|
1493
1493
|
break;
|
|
1494
|
+
case 'jsoneditor':
|
|
1495
|
+
/* It IS read-only -- `readOnly` went to the editor when it was
|
|
1496
|
+
* built -- and it did not LOOK it: a json editor with its menu
|
|
1497
|
+
* bar on top invites an edit it will discard. The class mutes
|
|
1498
|
+
* it (c_yui_form.css), which is the same thing a readonly
|
|
1499
|
+
* `input` has done since it existed. */
|
|
1500
|
+
$extend.classList.add('yui-jse-readonly');
|
|
1501
|
+
break;
|
|
1502
|
+
case 'input':
|
|
1503
|
+
/* `readonly` does not apply to a colour input -- the spec lists
|
|
1504
|
+
* the types it applies to and colour is not one of them -- so
|
|
1505
|
+
* the swatch opens its picker and the value changes, and in a
|
|
1506
|
+
* form that only sends writable cols the change is then
|
|
1507
|
+
* silently dropped. Date and time DO honour it, and keep it:
|
|
1508
|
+
* readonly stays selectable and copyable, disabled does not. */
|
|
1509
|
+
if(inputType === 'color') {
|
|
1510
|
+
$extend.setAttribute("disabled", "disabled");
|
|
1511
|
+
}
|
|
1512
|
+
break;
|
|
1494
1513
|
default:
|
|
1495
|
-
/* A text control already carries `readonly`, which is the
|
|
1496
|
-
* better of the two: it stays selectable and copyable. */
|
|
1497
1514
|
break;
|
|
1498
1515
|
}
|
|
1499
1516
|
}
|
package/src/form_toolbar_plan.js
CHANGED
|
@@ -10,13 +10,25 @@
|
|
|
10
10
|
* All Rights Reserved.
|
|
11
11
|
***********************************************************************/
|
|
12
12
|
|
|
13
|
-
/*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
/* Two groups, and the split is a real one: `undo`, `clear` and `save`
|
|
14
|
+
* act on the RECORD being edited, `copy` and `paste` move it in and out
|
|
15
|
+
* of the clipboard. Keeping them apart means a caller who drops one
|
|
16
|
+
* group does not leave a hole in the middle.
|
|
17
|
+
*
|
|
18
|
+
* WHICH SIDE EACH ONE TAKES CHANGED (2026-09-04), and the reason is that
|
|
19
|
+
* the form changed shape: it was an embedded panel and it opens as a
|
|
20
|
+
* MODAL DIALOG now. In a dialog the primary action goes bottom-RIGHT --
|
|
21
|
+
* every platform puts it there, and it is where the eye ends after
|
|
22
|
+
* reading the fields. `save` sat hard against the left edge, which is
|
|
23
|
+
* where a person looks last.
|
|
24
|
+
*
|
|
25
|
+
* So: clipboard on the left, record actions on the right, and `save`
|
|
26
|
+
* LAST of all. The order inside a group is the order asked for, which
|
|
27
|
+
* is why DEFAULT_TOOLBAR is written in the order it is drawn. */
|
|
28
|
+
const LEFT_BUTTONS = ["copy", "paste"];
|
|
29
|
+
const RIGHT_BUTTONS = ["undo", "clear", "save"];
|
|
18
30
|
|
|
19
|
-
const DEFAULT_TOOLBAR = ["
|
|
31
|
+
const DEFAULT_TOOLBAR = ["copy", "paste", "undo", "clear", "save"];
|
|
20
32
|
|
|
21
33
|
|
|
22
34
|
/***************************************************************
|
|
@@ -5,17 +5,26 @@ describe("plan_toolbar", () => {
|
|
|
5
5
|
|
|
6
6
|
it("says nothing -> the five buttons this gclass always had", () => {
|
|
7
7
|
const p = plan_toolbar(undefined);
|
|
8
|
-
expect(p.left).toEqual(["
|
|
9
|
-
expect(p.right).toEqual(["
|
|
8
|
+
expect(p.left).toEqual(["copy", "paste"]);
|
|
9
|
+
expect(p.right).toEqual(["undo", "clear", "save"]);
|
|
10
10
|
expect(p.unknown).toEqual([]);
|
|
11
11
|
expect(DEFAULT_TOOLBAR.length).toBe(5);
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
+
it("save is the LAST button of the bar", () => {
|
|
15
|
+
/* The form opens as a modal dialog and a dialog's primary action
|
|
16
|
+
* goes bottom-right. Asserted on the plan and not on the CSS,
|
|
17
|
+
* because the plan is what decides the two groups. */
|
|
18
|
+
const p = plan_toolbar(undefined);
|
|
19
|
+
expect(p.right[p.right.length - 1]).toBe("save");
|
|
20
|
+
expect(p.left).not.toContain("save");
|
|
21
|
+
});
|
|
22
|
+
|
|
14
23
|
it("a non-array is not an empty toolbar: it is the default", () => {
|
|
15
24
|
/* Reading a JSON attr that was never set must not silently
|
|
16
25
|
* leave a form with no save button. */
|
|
17
26
|
for(const v of [null, "save", 0, {}]) {
|
|
18
|
-
expect(plan_toolbar(v).
|
|
27
|
+
expect(plan_toolbar(v).right).toContain("save");
|
|
19
28
|
}
|
|
20
29
|
});
|
|
21
30
|
|
|
@@ -28,21 +37,21 @@ describe("plan_toolbar", () => {
|
|
|
28
37
|
|
|
29
38
|
it("one action: a dialog asks for save only", () => {
|
|
30
39
|
const p = plan_toolbar(["save"]);
|
|
31
|
-
expect(p.
|
|
32
|
-
expect(p.
|
|
40
|
+
expect(p.right).toEqual(["save"]);
|
|
41
|
+
expect(p.left).toEqual([]);
|
|
33
42
|
});
|
|
34
43
|
|
|
35
44
|
it("keeps the order asked for inside each side", () => {
|
|
36
45
|
const p = plan_toolbar(["clear", "save", "paste", "copy"]);
|
|
37
|
-
expect(p.
|
|
38
|
-
expect(p.
|
|
46
|
+
expect(p.right).toEqual(["clear", "save"]);
|
|
47
|
+
expect(p.left).toEqual(["paste", "copy"]);
|
|
39
48
|
});
|
|
40
49
|
|
|
41
50
|
it("an unknown name is REPORTED, never silently dropped", () => {
|
|
42
51
|
/* A typo here would otherwise remove a button and leave no
|
|
43
52
|
* trace of why it is missing. */
|
|
44
53
|
const p = plan_toolbar(["save", "sav", "undo"]);
|
|
45
|
-
expect(p.
|
|
54
|
+
expect(p.right).toEqual(["save", "undo"]);
|
|
46
55
|
expect(p.unknown).toEqual(["sav"]);
|
|
47
56
|
});
|
|
48
57
|
|
|
@@ -59,7 +68,7 @@ describe("plan_toolbar", () => {
|
|
|
59
68
|
|
|
60
69
|
it("drops one whole side without disturbing the other", () => {
|
|
61
70
|
const p = plan_toolbar(["save", "undo", "clear"]);
|
|
62
|
-
expect(p.
|
|
63
|
-
expect(p.
|
|
71
|
+
expect(p.right).toEqual(["save", "undo", "clear"]);
|
|
72
|
+
expect(p.left).toEqual([]);
|
|
64
73
|
});
|
|
65
74
|
});
|