@wildwinter/app-shell 0.54.0 → 0.56.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 +79 -0
- package/dist/controls.css +29 -0
- package/dist/controls.css.map +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/live-link.cjs +150 -0
- package/dist/live-link.cjs.map +1 -0
- package/dist/live-link.d.cts +71 -0
- package/dist/live-link.d.ts +71 -0
- package/dist/live-link.js +134 -0
- package/dist/live-link.js.map +1 -0
- package/dist/tokens.css +1 -1
- package/dist/tokens.css.map +1 -1
- package/dist/value-rows.cjs +89 -10
- package/dist/value-rows.cjs.map +1 -1
- package/dist/value-rows.d.cts +50 -1
- package/dist/value-rows.d.ts +50 -1
- package/dist/value-rows.js +91 -13
- package/dist/value-rows.js.map +1 -1
- package/package.json +14 -3
package/dist/value-rows.cjs
CHANGED
|
@@ -826,13 +826,89 @@ var fieldRowFocus = {
|
|
|
826
826
|
settle: (row) => keeper.settle(row),
|
|
827
827
|
restore: (row) => keeper.restore(row)
|
|
828
828
|
};
|
|
829
|
+
var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
830
|
+
function isSet(decl, value) {
|
|
831
|
+
if (value === void 0) return false;
|
|
832
|
+
if (decl.type === "record" && decl.default === void 0 && isObject(value)) {
|
|
833
|
+
const fields = decl.fields ?? [];
|
|
834
|
+
const declared = new Set(fields.map((f) => f.name));
|
|
835
|
+
if (Object.entries(value).some(([k, v]) => !declared.has(k) && v !== void 0)) return true;
|
|
836
|
+
return fields.some((f) => isSet(f, value[f.name]));
|
|
837
|
+
}
|
|
838
|
+
return extensions.stableStringify(value) !== extensions.stableStringify(extensions.defaultOf(decl));
|
|
839
|
+
}
|
|
840
|
+
function foldCaption(name, set) {
|
|
841
|
+
return set > 0 ? `${name} (${set} set)` : name;
|
|
842
|
+
}
|
|
843
|
+
function extensionFold() {
|
|
844
|
+
const open = /* @__PURE__ */ new Set();
|
|
845
|
+
const shown = /* @__PURE__ */ new Map();
|
|
846
|
+
const keyOf = (o) => `${o.extension}\0${o.node}`;
|
|
847
|
+
const visible = (o, setNames) => {
|
|
848
|
+
const was = shown.get(keyOf(o));
|
|
849
|
+
const fields = was ? /* @__PURE__ */ new Set([...was.fields, ...setNames]) : new Set(setNames);
|
|
850
|
+
shown.set(keyOf(o), { fields, used: true });
|
|
851
|
+
return fields;
|
|
852
|
+
};
|
|
853
|
+
const fold = {
|
|
854
|
+
isOpen: (extension) => open.has(extension),
|
|
855
|
+
setOpen(extension, on) {
|
|
856
|
+
if (on) open.add(extension);
|
|
857
|
+
else open.delete(extension);
|
|
858
|
+
for (const key of shown.keys()) if (key.startsWith(`${extension}\0`)) shown.delete(key);
|
|
859
|
+
},
|
|
860
|
+
sweep() {
|
|
861
|
+
for (const [key, entry] of shown) {
|
|
862
|
+
if (!entry.used) shown.delete(key);
|
|
863
|
+
else entry.used = false;
|
|
864
|
+
}
|
|
865
|
+
},
|
|
866
|
+
section(o) {
|
|
867
|
+
const sec = el("div", `shell-fold${o.className ? ` ${o.className}` : ""}`);
|
|
868
|
+
sec.dataset["extension"] = o.extension;
|
|
869
|
+
const cap = el("button", `shell-fold-cap${o.captionClassName ? ` ${o.captionClassName}` : ""}`);
|
|
870
|
+
cap.type = "button";
|
|
871
|
+
const body = el("div", "shell-fold-body");
|
|
872
|
+
sec.append(cap, body);
|
|
873
|
+
const draw = () => {
|
|
874
|
+
const isOpen = open.has(o.extension);
|
|
875
|
+
const setNames = new Set(o.fields.filter((f) => isSet(f, o.entry?.[f.name])).map((f) => f.name));
|
|
876
|
+
const show2 = isOpen ? void 0 : visible(o, setNames);
|
|
877
|
+
cap.replaceChildren(iconNode(isOpen ? "expanded" : "collapsed"), el("span", "shell-fold-name", foldCaption(o.caption, setNames.size)));
|
|
878
|
+
cap.setAttribute("aria-expanded", String(isOpen));
|
|
879
|
+
cap.dataset["tip"] = isOpen ? `Show only the fields set here` : `Show every ${o.caption} field`;
|
|
880
|
+
sec.classList.toggle("shell-fold-open", isOpen);
|
|
881
|
+
const rows = [...o.lead ?? []];
|
|
882
|
+
let group;
|
|
883
|
+
for (const decl of o.fields) {
|
|
884
|
+
if (show2 && !show2.has(decl.name)) continue;
|
|
885
|
+
const g = decl.group;
|
|
886
|
+
if (g !== void 0 && g !== group) {
|
|
887
|
+
group = g;
|
|
888
|
+
rows.push(o.group(g));
|
|
889
|
+
}
|
|
890
|
+
rows.push(o.row(decl));
|
|
891
|
+
}
|
|
892
|
+
rows.push(...o.tail ?? []);
|
|
893
|
+
body.replaceChildren(...rows);
|
|
894
|
+
};
|
|
895
|
+
cap.addEventListener("click", () => {
|
|
896
|
+
fold.setOpen(o.extension, !open.has(o.extension));
|
|
897
|
+
draw();
|
|
898
|
+
});
|
|
899
|
+
draw();
|
|
900
|
+
return sec;
|
|
901
|
+
}
|
|
902
|
+
};
|
|
903
|
+
return fold;
|
|
904
|
+
}
|
|
829
905
|
|
|
830
906
|
// src/value-rows.ts
|
|
831
907
|
function nodeLabel(adapter, kind, id) {
|
|
832
908
|
return adapter.nodes(kind).find((n) => n.id === id)?.label ?? adapter.label?.(kind, id);
|
|
833
909
|
}
|
|
834
910
|
var SCALARS = /* @__PURE__ */ new Set(["text", "multiline", "number", "boolean", "enum", "flags", "quality", "string"]);
|
|
835
|
-
var
|
|
911
|
+
var isObject2 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
836
912
|
var nameOf = (decl) => decl.label ?? decl.name;
|
|
837
913
|
var asDecl = (d, name) => ({ ...d, name: d.name ?? name });
|
|
838
914
|
function ownProblems(decl, value, adapter) {
|
|
@@ -1071,31 +1147,31 @@ function structuredRow(initial) {
|
|
|
1071
1147
|
}, controls));
|
|
1072
1148
|
};
|
|
1073
1149
|
if (decl.type === "record") {
|
|
1074
|
-
const value =
|
|
1150
|
+
const value = isObject2(o.value) ? o.value : void 0;
|
|
1075
1151
|
const required = value === void 0 ? [] : extensions.valueProblems(decl, value).filter((p) => p.code === "required");
|
|
1076
1152
|
for (const f of decl.fields ?? []) {
|
|
1077
1153
|
const missing = required.find((p) => p.path === f.name);
|
|
1078
1154
|
child(`f:${f.name}`, f, value?.[f.name], (v) => {
|
|
1079
|
-
const next = { ...
|
|
1155
|
+
const next = { ...isObject2(opts.value) ? opts.value : {} };
|
|
1080
1156
|
if (v === void 0) delete next[f.name];
|
|
1081
1157
|
else next[f.name] = v;
|
|
1082
1158
|
commit(Object.keys(next).length > 0 ? next : void 0);
|
|
1083
1159
|
}, void 0, void 0, missing ? "Required." : void 0);
|
|
1084
1160
|
}
|
|
1085
1161
|
} else if (decl.type === "map" && decl.of) {
|
|
1086
|
-
const value =
|
|
1162
|
+
const value = isObject2(o.value) ? o.value : {};
|
|
1087
1163
|
const keyNodes = decl.key?.type === "reference" && o.adapter ? o.adapter.nodes(decl.key.to ?? "") : void 0;
|
|
1088
1164
|
const keyKind = decl.key?.to ?? "";
|
|
1089
1165
|
const keyLabel = (k) => (o.adapter && keyNodes !== void 0 ? nodeLabel(o.adapter, keyKind, k) : void 0) ?? k;
|
|
1090
1166
|
for (const k of Object.keys(value)) {
|
|
1091
1167
|
const remove = editable() ? [iconBtn("close", `Remove ${keyLabel(k)}`, () => {
|
|
1092
|
-
const next = { ...
|
|
1168
|
+
const next = { ...isObject2(opts.value) ? opts.value : {} };
|
|
1093
1169
|
delete next[k];
|
|
1094
1170
|
commit(Object.keys(next).length > 0 ? next : void 0);
|
|
1095
1171
|
})] : [];
|
|
1096
1172
|
const gone = keyNodes !== void 0 && o.adapter && nodeLabel(o.adapter, keyKind, k) === void 0 ? `${k} is not here any more.` : void 0;
|
|
1097
1173
|
child(`k:${k}`, asDecl(decl.of, k), value[k], (v) => {
|
|
1098
|
-
const next = { ...
|
|
1174
|
+
const next = { ...isObject2(opts.value) ? opts.value : {} };
|
|
1099
1175
|
next[k] = v === void 0 ? extensions.defaultOf(decl.of) : v;
|
|
1100
1176
|
commit(next);
|
|
1101
1177
|
}, remove, keyLabel(k), gone);
|
|
@@ -1139,7 +1215,7 @@ function structuredRow(initial) {
|
|
|
1139
1215
|
}
|
|
1140
1216
|
} else if (decl.type === "list" && decl.of) {
|
|
1141
1217
|
const value = Array.isArray(o.value) ? o.value : [];
|
|
1142
|
-
const idOf = (item, i) => decl.id !== void 0 &&
|
|
1218
|
+
const idOf = (item, i) => decl.id !== void 0 && isObject2(item) && typeof item[decl.id] === "string" ? `id:${item[decl.id]}` : `i:${i}`;
|
|
1143
1219
|
value.forEach((item, i) => {
|
|
1144
1220
|
const set = (next) => commit(next.length > 0 ? next : void 0);
|
|
1145
1221
|
const controls = editable() ? [
|
|
@@ -1153,7 +1229,7 @@ function structuredRow(initial) {
|
|
|
1153
1229
|
}, i === value.length - 1),
|
|
1154
1230
|
iconBtn("close", "Remove", () => set(value.filter((_, j) => j !== i)), false, true)
|
|
1155
1231
|
] : [];
|
|
1156
|
-
const itemLabel = decl.id !== void 0 &&
|
|
1232
|
+
const itemLabel = decl.id !== void 0 && isObject2(item) && typeof item[decl.id] === "string" ? item[decl.id] : `${i + 1}`;
|
|
1157
1233
|
child(idOf(item, i), asDecl(decl.of, itemLabel), item, (v) => {
|
|
1158
1234
|
const next = [...Array.isArray(opts.value) ? opts.value : []];
|
|
1159
1235
|
next[i] = v === void 0 ? extensions.defaultOf(decl.of) : v;
|
|
@@ -1164,8 +1240,8 @@ function structuredRow(initial) {
|
|
|
1164
1240
|
if (editable()) {
|
|
1165
1241
|
adder.append(iconBtn("add", "Add", () => {
|
|
1166
1242
|
const fresh = extensions.defaultOf(decl.of);
|
|
1167
|
-
if (decl.id !== void 0 &&
|
|
1168
|
-
const taken = new Set(value.map((x) =>
|
|
1243
|
+
if (decl.id !== void 0 && isObject2(fresh)) {
|
|
1244
|
+
const taken = new Set(value.map((x) => isObject2(x) ? x[decl.id] : void 0));
|
|
1169
1245
|
let n = value.length + 1;
|
|
1170
1246
|
while (taken.has(`item-${n}`)) n++;
|
|
1171
1247
|
fresh[decl.id] = `item-${n}`;
|
|
@@ -1214,6 +1290,9 @@ function valueRows() {
|
|
|
1214
1290
|
};
|
|
1215
1291
|
}
|
|
1216
1292
|
|
|
1293
|
+
exports.extensionFold = extensionFold;
|
|
1294
|
+
exports.foldCaption = foldCaption;
|
|
1295
|
+
exports.isSet = isSet;
|
|
1217
1296
|
exports.valueRow = valueRow;
|
|
1218
1297
|
exports.valueRows = valueRows;
|
|
1219
1298
|
//# sourceMappingURL=value-rows.cjs.map
|