@wildwinter/app-shell 0.52.0 → 0.54.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.
@@ -74,6 +74,9 @@ interface FieldRowOptions {
74
74
  disabled?: boolean;
75
75
  /** A message of the app's own about this value (a check the row cannot make), shown under the control. */
76
76
  problem?: string;
77
+ /** The app's own sentence INSTEAD of the row's (a renamed stage said better than "not one of the stages").
78
+ * Given, it is the whole message; `problem` is ignored. */
79
+ replaceProblem?: string;
77
80
  /** The caption; default the field's name. */
78
81
  label?: string | Node;
79
82
  /** Added to the row and its caption, so a row sits in its app's layout. */
@@ -74,6 +74,9 @@ interface FieldRowOptions {
74
74
  disabled?: boolean;
75
75
  /** A message of the app's own about this value (a check the row cannot make), shown under the control. */
76
76
  problem?: string;
77
+ /** The app's own sentence INSTEAD of the row's (a renamed stage said better than "not one of the stages").
78
+ * Given, it is the whole message; `problem` is ignored. */
79
+ replaceProblem?: string;
77
80
  /** The caption; default the field's name. */
78
81
  label?: string | Node;
79
82
  /** Added to the row and its caption, so a row sits in its app's layout. */
@@ -1,4 +1,4 @@
1
- export { defaultLabel, fallbackText, fieldRow, fieldRowFocus, fieldRows, fieldValueProblem, rungStrip, stageGateNote, valueHelpText } from './chunk-4QDD6GF3.js';
1
+ export { defaultLabel, fallbackText, fieldRow, fieldRowFocus, fieldRows, fieldValueProblem, rungStrip, stageGateNote, valueHelpText } from './chunk-XJM733E6.js';
2
2
  import './chunk-W4WC4FO5.js';
3
3
  //# sourceMappingURL=value-control.js.map
4
4
  //# sourceMappingURL=value-control.js.map
@@ -559,7 +559,7 @@ function fieldRow(initial) {
559
559
  const help = valueHelpText(opts.decl, opts.value);
560
560
  valueHelp.textContent = help;
561
561
  valueHelp.hidden = help === "";
562
- const words = [typing || fieldValueProblem(opts.decl, opts.value), opts.problem ?? ""].filter((w) => w !== "");
562
+ const words = opts.replaceProblem !== void 0 ? [opts.replaceProblem].filter((w) => w !== "") : [typing || fieldValueProblem(opts.decl, opts.value), opts.problem ?? ""].filter((w) => w !== "");
563
563
  problem.textContent = words.join(" ");
564
564
  problem.hidden = words.length === 0;
565
565
  row.classList.toggle("has-problem", words.length > 0);
@@ -837,13 +837,20 @@ var nameOf = (decl) => decl.label ?? decl.name;
837
837
  var asDecl = (d, name) => ({ ...d, name: d.name ?? name });
838
838
  function ownProblems(decl, value, adapter) {
839
839
  if (value === void 0) return "";
840
- const exists = adapter ? (kind, id) => nodeLabel(adapter, kind, id) !== void 0 : void 0;
841
- return extensions.valueProblems(decl, value, exists ? { exists } : {}).filter((p) => p.path === "" && p.severity === "error" && p.code !== "not-a-value" && p.code !== "not-a-stage").map((p) => `${p.message.replace(/^the value/, "The value")}.`).join(" ");
840
+ return extensions.valueProblems(decl, value, contextOf(adapter)).filter((p) => p.path === "" && (p.severity === "error" || p.code === "pick-ambiguous") && p.code !== "not-a-value" && p.code !== "not-a-stage").map((p) => `${p.message.replace(/^the value/, "The value")}.`).join(" ");
841
+ }
842
+ function contextOf(adapter) {
843
+ if (!adapter) return {};
844
+ return {
845
+ exists: (kind, id) => nodeLabel(adapter, kind, id) !== void 0,
846
+ ...adapter.list ? { list: (name) => adapter.list(name) } : {}
847
+ };
842
848
  }
843
849
  function valueRow(initial) {
844
850
  const decl = initial.decl;
845
851
  if (SCALARS.has(decl.type)) return scalarRow(initial);
846
852
  if (decl.type === "reference") return referenceRow(initial);
853
+ if (decl.type === "pick") return pickRow(initial);
847
854
  return structuredRow(initial);
848
855
  }
849
856
  function scalarRow(initial) {
@@ -856,6 +863,7 @@ function scalarRow(initial) {
856
863
  ...o.onCommit ? { onCommit: (v) => o.onCommit(v) } : {},
857
864
  ...o.disabled !== void 0 ? { disabled: o.disabled } : {},
858
865
  ...problem !== "" ? { problem } : {},
866
+ ...o.replaceProblem !== void 0 ? { replaceProblem: o.replaceProblem } : {},
859
867
  label: o.label ?? nameOf(o.decl),
860
868
  ...o.className !== void 0 ? { className: o.className } : {},
861
869
  ...o.labelClassName !== void 0 ? { labelClassName: o.labelClassName } : {},
@@ -914,7 +922,87 @@ function referenceRow(initial) {
914
922
  sel.disabled = o.onCommit === void 0 || o.disabled === true;
915
923
  help.textContent = o.decl.help ?? o.decl.purpose ?? "";
916
924
  help.hidden = help.textContent === "";
917
- const words = [ownProblems(o.decl, o.value, o.adapter), o.problem ?? ""].filter((w) => w !== "").join(" ");
925
+ const words = o.replaceProblem ?? [ownProblems(o.decl, o.value, o.adapter), o.problem ?? ""].filter((w) => w !== "").join(" ");
926
+ problem.textContent = words;
927
+ problem.hidden = words === "";
928
+ row.classList.toggle("has-problem", words !== "");
929
+ };
930
+ draw(initial);
931
+ return { el: row, update: draw };
932
+ }
933
+ function pickRow(initial) {
934
+ let opts = initial;
935
+ if (!opts.adapter && (opts.decl.from ?? []).some((s) => !("words" in s))) {
936
+ const inner = scalarRow({ ...opts, decl: { ...opts.decl, type: "text" } });
937
+ return { el: inner.el, update: (o) => {
938
+ opts = o;
939
+ inner.update({ ...o, decl: { ...o.decl, type: "text" } });
940
+ } };
941
+ }
942
+ const row = el("div", "shell-fieldrow shell-valuerow-pick");
943
+ const caption = el("span", "shell-fieldrow-label");
944
+ const body = el("div", "shell-fieldrow-body");
945
+ const sel = el("select", "field shell-fieldrow-select");
946
+ const help = el("p", "shell-fieldrow-purpose");
947
+ const problem = el("p", "shell-fieldrow-problem");
948
+ problem.setAttribute("role", "status");
949
+ body.append(sel, help, problem);
950
+ row.append(caption, body);
951
+ sel.addEventListener("change", () => {
952
+ const v = sel.value === "" ? void 0 : sel.value;
953
+ opts = { ...opts, value: v };
954
+ draw(opts);
955
+ opts.onCommit?.(v);
956
+ });
957
+ const groupName = (s) => "to" in s ? s.to === "cast" ? "Cast" : s.to.charAt(0).toUpperCase() + s.to.slice(1) : "list" in s ? s.list : void 0;
958
+ const draw = (o) => {
959
+ opts = o;
960
+ row.className = `shell-fieldrow shell-valuerow-pick${o.className ? ` ${o.className}` : ""}`;
961
+ const label = o.label ?? nameOf(o.decl);
962
+ if (typeof label === "string") caption.textContent = label;
963
+ else caption.replaceChildren(label);
964
+ if (o.controlClassName) sel.className = `shell-fieldrow-select ${o.controlClassName}`;
965
+ const adapter = o.adapter;
966
+ const choices = extensions.pickChoices(o.decl, {
967
+ ...adapter ? { nodes: (kind) => adapter.nodes(kind) } : {},
968
+ ...adapter?.list ? { list: (name) => adapter.list(name) } : {}
969
+ });
970
+ const held = typeof o.value === "string" ? o.value : "";
971
+ sel.replaceChildren();
972
+ const option = (v, text) => {
973
+ const opt = el("option", void 0, text);
974
+ opt.value = v;
975
+ return opt;
976
+ };
977
+ sel.append(option("", "auto"));
978
+ const offered = /* @__PURE__ */ new Set();
979
+ let group;
980
+ for (const c of choices) {
981
+ if (offered.has(c.value)) continue;
982
+ offered.add(c.value);
983
+ const name = groupName(c.source);
984
+ if (name === void 0) {
985
+ group = void 0;
986
+ sel.append(option(c.value, c.label));
987
+ continue;
988
+ }
989
+ if (group?.source !== c.source) {
990
+ const og = el("optgroup");
991
+ og.setAttribute("label", name);
992
+ sel.append(og);
993
+ group = { source: c.source, el: og };
994
+ }
995
+ group.el.append(option(c.value, c.label));
996
+ }
997
+ if (held !== "" && !offered.has(held)) {
998
+ const named = (o.decl.from ?? []).map((s) => "to" in s && adapter ? adapter.label?.(s.to, held) : void 0).find((n) => n !== void 0);
999
+ sel.append(option(held, named ?? `${held} (missing)`));
1000
+ }
1001
+ sel.value = held;
1002
+ sel.disabled = o.onCommit === void 0 || o.disabled === true;
1003
+ help.textContent = o.decl.help ?? o.decl.purpose ?? "";
1004
+ help.hidden = help.textContent === "";
1005
+ const words = o.replaceProblem ?? [ownProblems(o.decl, o.value, o.adapter), o.problem ?? ""].filter((w) => w !== "").join(" ");
918
1006
  problem.textContent = words;
919
1007
  problem.hidden = words === "";
920
1008
  row.classList.toggle("has-problem", words !== "");
@@ -1091,7 +1179,7 @@ function structuredRow(initial) {
1091
1179
  if (decl.type !== "record" && editable()) body.append(adder);
1092
1180
  help.textContent = decl.help ?? decl.purpose ?? "";
1093
1181
  if (help.textContent !== "") body.append(help);
1094
- const words = [ownProblems(decl, o.value, o.adapter), o.problem ?? ""].filter((w) => w !== "").join(" ");
1182
+ const words = o.replaceProblem ?? [ownProblems(decl, o.value, o.adapter), o.problem ?? ""].filter((w) => w !== "").join(" ");
1095
1183
  problem.textContent = words;
1096
1184
  problem.hidden = words === "";
1097
1185
  body.append(problem);