@wssto2/vue-core 0.9.0 → 0.9.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.1 — 2026-10-16
4
+
5
+ ### New
6
+ - **`EditorPage` `disabledWhileClean`** (default false): an editor of a saved record keeps Save off until something changes. A create page keeps Save on, so an untouched form can be submitted to learn what is missing.
7
+
8
+ ### Tests
9
+ - A 5 s default wait and a 15 s test limit (`vitest.setup.ts`), so a lazily loaded page no longer fails a test at random. Nothing in the package changes.
10
+
3
11
  ## 0.9.0 — 2026-10-15
4
12
 
5
13
  File downloads and streams on the client, keyboard shortcuts that work on every layout, amounts with an application's own currency symbol, and the client half of an installable web app. go-core is unchanged (`v1.12.0`).
@@ -26,6 +26,11 @@ type __VLS_Props = {
26
26
  canSave?: boolean;
27
27
  /** The name of a field for people, for errors whose field is not on screen. */
28
28
  fieldLabel?: (field: string) => string;
29
+ /**
30
+ * An edit of a saved record: Save stays off until something changes. Default false, a create page, where an untouched form
31
+ * is submitted to learn what is missing.
32
+ */
33
+ disabledWhileClean?: boolean;
29
34
  };
30
35
  type __VLS_Slots = {
31
36
  default?: () => unknown;
@@ -50,6 +55,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}
50
55
  fieldLabel: (field: string) => string;
51
56
  saveLabel: string;
52
57
  canSave: boolean;
58
+ disabledWhileClean: boolean;
53
59
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
54
60
  declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
55
61
  export default _default;
@@ -1,8 +1,8 @@
1
1
  import { _ as He, c as et, f as tt } from "../FormErrors.vue_vue_type_script_setup_true_lang-DJiK8iqo.js";
2
2
  import { E as $o, u as _o, a as Co } from "../FormErrors.vue_vue_type_script_setup_true_lang-DJiK8iqo.js";
3
3
  import { f as Te } from "../useCommand-C3QTZIIw.js";
4
- import { _ as Fo, a as Bo, u as Lo } from "../useCommand-C3QTZIIw.js";
5
- import { ref as A, computed as h, defineComponent as G, openBlock as u, createBlock as D, mergeProps as W, unref as l, createSlots as J, withCtx as f, createElementVNode as y, normalizeClass as I, createElementBlock as g, Fragment as ie, renderList as xe, createVNode as j, createCommentVNode as L, toDisplayString as _, renderSlot as F, mergeDefaults as ue, useModel as re, useId as qe, withKeys as Ce, withModifiers as pe, createTextVNode as H, mergeModels as le, useTemplateRef as U, shallowRef as Oe, watch as ye, normalizeProps as ze, guardReactiveProps as Ve, nextTick as he, provide as at, inject as Ue, onBeforeUnmount as Ye, getCurrentScope as lt, onScopeDispose as ot, toValue as nt, shallowReactive as Ee, normalizeStyle as st, resolveDynamicComponent as rt } from "vue";
4
+ import { _ as Bo, a as Fo, u as Lo } from "../useCommand-C3QTZIIw.js";
5
+ import { ref as A, computed as h, defineComponent as G, openBlock as u, createBlock as D, mergeProps as W, unref as l, createSlots as J, withCtx as f, createElementVNode as y, normalizeClass as I, createElementBlock as g, Fragment as ie, renderList as xe, createVNode as j, createCommentVNode as L, toDisplayString as _, renderSlot as B, mergeDefaults as ue, useModel as re, useId as qe, withKeys as Ce, withModifiers as pe, createTextVNode as H, mergeModels as le, useTemplateRef as U, shallowRef as Oe, watch as ye, normalizeProps as ze, guardReactiveProps as Ve, nextTick as he, provide as at, inject as Ue, onBeforeUnmount as Ye, getCurrentScope as lt, onScopeDispose as ot, toValue as nt, shallowReactive as Ee, normalizeStyle as st, resolveDynamicComponent as rt } from "vue";
6
6
  import { a as We } from "../leaveGuard-Cc8yeLxM.js";
7
7
  import { M as zo, c as Vo, i as qo, l as Do, u as Ro } from "../leaveGuard-Cc8yeLxM.js";
8
8
  import { _ as jo } from "../LeaveGuardRoot.vue_vue_type_script_setup_true_lang-ChIsmnts.js";
@@ -23,10 +23,10 @@ import { _ as Xe } from "../DateButton.vue_vue_type_script_setup_true_lang-CovKG
23
23
  import { u as St } from "../format-Dn-BOb-o.js";
24
24
  import { u as Re } from "../mediaQuery-CygcXmFW.js";
25
25
  import { _ as Me } from "../Popover.vue_vue_type_script_setup_true_lang-C70GrCP7.js";
26
- import { u as Ft } from "../TimeField.vue_vue_type_script_setup_true_lang-B140Gjqd.js";
26
+ import { u as Bt } from "../TimeField.vue_vue_type_script_setup_true_lang-B140Gjqd.js";
27
27
  import { _ as Zo } from "../TimeField.vue_vue_type_script_setup_true_lang-B140Gjqd.js";
28
28
  import { _ as be } from "../Button.vue_vue_type_script_setup_true_lang-Dn-cJcj3.js";
29
- import { _ as Bt } from "../FormGroup.vue_vue_type_script_setup_true_lang-Bzm3yJy5.js";
29
+ import { _ as Ft } from "../FormGroup.vue_vue_type_script_setup_true_lang-Bzm3yJy5.js";
30
30
  import { a as Qo, c as en, p as tn, r as an, u as ln } from "../FormGroup.vue_vue_type_script_setup_true_lang-Bzm3yJy5.js";
31
31
  import { _ as nn } from "../FormView.vue_vue_type_script_setup_true_lang-Ncl9DmFB.js";
32
32
  import { i as Lt } from "../intlLocale-CeRU44qJ.js";
@@ -148,21 +148,21 @@ const Gt = ["id", "aria-label", "aria-describedby", "aria-invalid"], Kt = ["name
148
148
  i.$slots.trailing ? {
149
149
  name: "trailing",
150
150
  fn: f(() => [
151
- F(i.$slots, "trailing")
151
+ B(i.$slots, "trailing")
152
152
  ]),
153
153
  key: "0"
154
154
  } : void 0,
155
155
  i.$slots.labelTrailing ? {
156
156
  name: "labelTrailing",
157
157
  fn: f(() => [
158
- F(i.$slots, "labelTrailing")
158
+ B(i.$slots, "labelTrailing")
159
159
  ]),
160
160
  key: "1"
161
161
  } : void 0,
162
162
  i.$slots.readonly ? {
163
163
  name: "readonly",
164
164
  fn: f(() => [
165
- F(i.$slots, "readonly")
165
+ B(i.$slots, "readonly")
166
166
  ]),
167
167
  key: "2"
168
168
  } : void 0
@@ -227,10 +227,10 @@ const Gt = ["id", "aria-label", "aria-describedby", "aria-invalid"], Kt = ["name
227
227
  key: 0,
228
228
  class: I(["tabular-nums text-content-muted", a.variant === "row" ? "text-footnote" : "text-xs"])
229
229
  }, _(a.description), 3)) : L("", !0),
230
- F(c.$slots, "default")
230
+ B(c.$slots, "default")
231
231
  ]),
232
232
  c.$slots.trailing ? (u(), g("div", Zt, [
233
- F(c.$slots, "trailing")
233
+ B(c.$slots, "trailing")
234
234
  ])) : L("", !0)
235
235
  ], 2)
236
236
  ], 42, Wt),
@@ -310,21 +310,21 @@ const Gt = ["id", "aria-label", "aria-describedby", "aria-invalid"], Kt = ["name
310
310
  n.$slots.trailing ? {
311
311
  name: "trailing",
312
312
  fn: f(() => [
313
- F(n.$slots, "trailing")
313
+ B(n.$slots, "trailing")
314
314
  ]),
315
315
  key: "0"
316
316
  } : void 0,
317
317
  n.$slots.labelTrailing ? {
318
318
  name: "labelTrailing",
319
319
  fn: f(() => [
320
- F(n.$slots, "labelTrailing")
320
+ B(n.$slots, "labelTrailing")
321
321
  ]),
322
322
  key: "1"
323
323
  } : void 0,
324
324
  n.$slots.readonly ? {
325
325
  name: "readonly",
326
326
  fn: f(() => [
327
- F(n.$slots, "readonly")
327
+ B(n.$slots, "readonly")
328
328
  ]),
329
329
  key: "2"
330
330
  } : void 0
@@ -401,7 +401,7 @@ const Gt = ["id", "aria-label", "aria-describedby", "aria-invalid"], Kt = ["name
401
401
  class: I(["flex items-center gap-1.5", [l(p), w.value]])
402
402
  }, [
403
403
  T.$slots.value && M.value ? (u(), g("span", aa, [
404
- F(T.$slots, "value", {
404
+ B(T.$slots, "value", {
405
405
  option: M.value
406
406
  })
407
407
  ])) : L("", !0),
@@ -454,7 +454,7 @@ const Gt = ["id", "aria-label", "aria-describedby", "aria-invalid"], Kt = ["name
454
454
  T.$slots.option ? {
455
455
  name: "option",
456
456
  fn: f((ee) => [
457
- F(T.$slots, "option", ze(Ve(ee)))
457
+ B(T.$slots, "option", ze(Ve(ee)))
458
458
  ]),
459
459
  key: "0"
460
460
  } : void 0
@@ -465,28 +465,28 @@ const Gt = ["id", "aria-label", "aria-describedby", "aria-invalid"], Kt = ["name
465
465
  T.$slots.trailing ? {
466
466
  name: "trailing",
467
467
  fn: f(() => [
468
- F(T.$slots, "trailing")
468
+ B(T.$slots, "trailing")
469
469
  ]),
470
470
  key: "0"
471
471
  } : void 0,
472
472
  T.$slots.labelTrailing ? {
473
473
  name: "labelTrailing",
474
474
  fn: f(() => [
475
- F(T.$slots, "labelTrailing")
475
+ B(T.$slots, "labelTrailing")
476
476
  ]),
477
477
  key: "1"
478
478
  } : void 0,
479
479
  T.$slots.readonly ? {
480
480
  name: "readonly",
481
481
  fn: f(() => [
482
- F(T.$slots, "readonly")
482
+ B(T.$slots, "readonly")
483
483
  ]),
484
484
  key: "2"
485
485
  } : T.$slots.value && M.value ? {
486
486
  name: "readonly",
487
487
  fn: f(() => [
488
488
  y("span", oa, [
489
- F(T.$slots, "value", {
489
+ B(T.$slots, "value", {
490
490
  option: M.value
491
491
  })
492
492
  ])
@@ -529,9 +529,9 @@ const Gt = ["id", "aria-label", "aria-describedby", "aria-invalid"], Kt = ["name
529
529
  }),
530
530
  emits: /* @__PURE__ */ le(["focus", "blur"], ["update:modelValue"]),
531
531
  setup(r, { expose: a, emit: e }) {
532
- const t = r, n = re(r, "modelValue"), o = e, { t: c } = oe(), i = St(), p = Re(), k = U("input"), w = U("popover"), $ = U("calendar"), s = U("sheet"), m = h(() => ({ min: t.min?.slice(0, 10), max: t.max?.slice(0, 10), disabled: t.disabledDates })), b = h(() => t.min && t.min.length === 10 ? `${t.min}T00:00` : t.min), C = h(() => t.max && t.max.length === 10 ? `${t.max}T23:59` : t.max), q = (B, d) => !xt(d, { disabled: t.disabledDates }) && (!b.value || B >= b.value) && (!C.value || B <= C.value), x = $t(() => m.value), O = Ft(() => t.minuteStep), R = h(() => $e(n.value));
533
- function X(B) {
534
- const { date: d, time: z } = Ct(B), v = d === null ? R.value.day ?? Se() : x.parse(d);
532
+ const t = r, n = re(r, "modelValue"), o = e, { t: c } = oe(), i = St(), p = Re(), k = U("input"), w = U("popover"), $ = U("calendar"), s = U("sheet"), m = h(() => ({ min: t.min?.slice(0, 10), max: t.max?.slice(0, 10), disabled: t.disabledDates })), b = h(() => t.min && t.min.length === 10 ? `${t.min}T00:00` : t.min), C = h(() => t.max && t.max.length === 10 ? `${t.max}T23:59` : t.max), q = (F, d) => !xt(d, { disabled: t.disabledDates }) && (!b.value || F >= b.value) && (!C.value || F <= C.value), x = $t(() => m.value), O = Bt(() => t.minuteStep), R = h(() => $e(n.value));
533
+ function X(F) {
534
+ const { date: d, time: z } = Ct(F), v = d === null ? R.value.day ?? Se() : x.parse(d);
535
535
  if (!v) return { error: x.invalidMessage() };
536
536
  let V = R.value.time ?? Le(t.minuteStep);
537
537
  if (z !== null) {
@@ -542,32 +542,32 @@ const Gt = ["id", "aria-label", "aria-describedby", "aria-invalid"], Kt = ["name
542
542
  const S = _e(v, V);
543
543
  return q(S, v) ? { value: S } : { error: x.unavailableMessage() };
544
544
  }
545
- const M = Ne({ model: n, display: (B) => `${i.date($e(B).day)} ${$e(B).time ?? ""}`.trim(), parse: X }), ne = h({
545
+ const M = Ne({ model: n, display: (F) => `${i.date($e(F).day)} ${$e(F).time ?? ""}`.trim(), parse: X }), ne = h({
546
546
  get: () => R.value.time,
547
- set: (B) => {
548
- B && pt(B) && (n.value = _e(R.value.day ?? Se(), B));
547
+ set: (F) => {
548
+ F && pt(F) && (n.value = _e(R.value.day ?? Se(), F));
549
549
  }
550
- }), Q = Ne({ model: ne, display: (B) => B, parse: O.parse }), te = _t(() => t.quickPicks ?? (p.value ? void 0 : []), () => p.value, () => m.value), fe = h(() => t.error || M.message.value || Q.message.value), me = h(() => n.value ? i.dateTime(n.value) : null), T = De("date", () => fe.value ? "error" : t.disabled ? "locked" : "rest"), K = h(() => {
551
- const B = M.typed.value;
552
- return B ? $e(B).day ?? null : null;
550
+ }), Q = Ne({ model: ne, display: (F) => F, parse: O.parse }), te = _t(() => t.quickPicks ?? (p.value ? void 0 : []), () => p.value, () => m.value), fe = h(() => t.error || M.message.value || Q.message.value), me = h(() => n.value ? i.dateTime(n.value) : null), T = De("date", () => fe.value ? "error" : t.disabled ? "locked" : "rest"), K = h(() => {
551
+ const F = M.typed.value;
552
+ return F ? $e(F).day ?? null : null;
553
553
  }), E = h(() => K.value ?? (bt(R.value.day) ? R.value.day : null)), ae = h(() => M.typed.value ? $e(M.typed.value).time : R.value.time);
554
- function se(B) {
555
- B && M.set(_e(B, R.value.time ?? Le(t.minuteStep)));
554
+ function se(F) {
555
+ F && M.set(_e(F, R.value.time ?? Le(t.minuteStep)));
556
556
  }
557
- function ee(B) {
558
- B && M.set(_e(R.value.day ?? Se(), B));
557
+ function ee(F) {
558
+ F && M.set(_e(R.value.day ?? Se(), F));
559
559
  }
560
- function ke(B) {
561
- M.set(_e(Se(), Le(t.minuteStep))), B();
560
+ function ke(F) {
561
+ M.set(_e(Se(), Le(t.minuteStep))), F();
562
562
  }
563
563
  const we = qe();
564
- async function Y(B) {
565
- t.disabled || (w.value?.present(), B && (await he(), await he(), $.value?.focus()));
564
+ async function Y(F) {
565
+ t.disabled || (w.value?.present(), F && (await he(), await he(), $.value?.focus()));
566
566
  }
567
- function ve(B) {
568
- B.key === "Enter" ? (M.commit(), w.value?.dismiss()) : B.key === "ArrowDown" && (B.preventDefault(), Y(!0));
567
+ function ve(F) {
568
+ F.key === "Enter" ? (M.commit(), w.value?.dismiss()) : F.key === "ArrowDown" && (F.preventDefault(), Y(!0));
569
569
  }
570
- return a({ focus: () => k.value?.focus() }), (B, d) => (u(), D(ge, W({ ...l(de)(t), error: fe.value }, {
570
+ return a({ focus: () => k.value?.focus() }), (F, d) => (u(), D(ge, W({ ...l(de)(t), error: fe.value }, {
571
571
  value: me.value,
572
572
  "value-style": "numeric"
573
573
  }), J({
@@ -715,24 +715,24 @@ const Gt = ["id", "aria-label", "aria-describedby", "aria-invalid"], Kt = ["name
715
715
  ]),
716
716
  _: 2
717
717
  }, [
718
- B.$slots.trailing ? {
718
+ F.$slots.trailing ? {
719
719
  name: "trailing",
720
720
  fn: f(() => [
721
- F(B.$slots, "trailing")
721
+ B(F.$slots, "trailing")
722
722
  ]),
723
723
  key: "0"
724
724
  } : void 0,
725
- B.$slots.labelTrailing ? {
725
+ F.$slots.labelTrailing ? {
726
726
  name: "labelTrailing",
727
727
  fn: f(() => [
728
- F(B.$slots, "labelTrailing")
728
+ B(F.$slots, "labelTrailing")
729
729
  ]),
730
730
  key: "1"
731
731
  } : void 0,
732
- B.$slots.readonly ? {
732
+ F.$slots.readonly ? {
733
733
  name: "readonly",
734
734
  fn: f(() => [
735
- F(B.$slots, "readonly")
735
+ B(F.$slots, "readonly")
736
736
  ]),
737
737
  key: "2"
738
738
  } : void 0
@@ -750,7 +750,7 @@ function Qe(r, a = {}) {
750
750
  }
751
751
  return (a.maxSize ?? 0) > 0 && r.size > (a.maxSize ?? 0) ? "too_large" : null;
752
752
  }
753
- function Fe(r) {
753
+ function Be(r) {
754
754
  return r < 1024 ? `${r} B` : r < 1024 * 1024 ? `${Math.round(r / 1024)} KB` : `${(r / (1024 * 1024)).toFixed(r % (1024 * 1024) === 0 ? 0 : 1)} MB`;
755
755
  }
756
756
  const ya = { class: "w-full" }, ga = ["id", "accept", "disabled", "aria-describedby", "aria-invalid"], ha = {
@@ -782,12 +782,12 @@ const ya = { class: "w-full" }, ga = ["id", "accept", "disabled", "aria-describe
782
782
  const e = r, t = re(r, "modelValue"), { t: n } = oe(), o = U("chooser"), c = A(!1), i = A(null), p = h(() => {
783
783
  if (e.hint) return e.hint;
784
784
  const $ = [];
785
- return e.accept.length && $.push(n("core.form.file.allowed", { formats: e.accept.map((s) => s.replace(/^\./, "").toUpperCase()).join(", ") })), e.maxSize > 0 && $.push(n("core.form.file.max_size", { size: Fe(e.maxSize) })), $.join(" · ") || void 0;
785
+ return e.accept.length && $.push(n("core.form.file.allowed", { formats: e.accept.map((s) => s.replace(/^\./, "").toUpperCase()).join(", ") })), e.maxSize > 0 && $.push(n("core.form.file.max_size", { size: Be(e.maxSize) })), $.join(" · ") || void 0;
786
786
  });
787
787
  function k($) {
788
788
  if (!$) return;
789
789
  const s = Qe($, { accept: e.accept, maxSize: e.maxSize });
790
- s ? (i.value = s === "invalid_type" ? n("core.form.file.invalid_type") : n("core.form.file.too_large", { size: Fe(e.maxSize) }), t.value = null) : (i.value = null, t.value = $);
790
+ s ? (i.value = s === "invalid_type" ? n("core.form.file.invalid_type") : n("core.form.file.too_large", { size: Be(e.maxSize) }), t.value = null) : (i.value = null, t.value = $);
791
791
  }
792
792
  function w() {
793
793
  t.value = null, i.value = null;
@@ -816,7 +816,7 @@ const ya = { class: "w-full" }, ga = ["id", "accept", "disabled", "aria-describe
816
816
  t.value ? (u(), g("div", ha, [
817
817
  y("div", ka, [
818
818
  y("p", xa, _(t.value.name), 1),
819
- y("p", wa, _(l(Fe)(t.value.size)), 1)
819
+ y("p", wa, _(l(Be)(t.value.size)), 1)
820
820
  ]),
821
821
  y("button", {
822
822
  type: "button",
@@ -868,27 +868,27 @@ const ya = { class: "w-full" }, ga = ["id", "accept", "disabled", "aria-describe
868
868
  $.$slots.trailing ? {
869
869
  name: "trailing",
870
870
  fn: f(() => [
871
- F($.$slots, "trailing")
871
+ B($.$slots, "trailing")
872
872
  ]),
873
873
  key: "0"
874
874
  } : void 0,
875
875
  $.$slots.labelTrailing ? {
876
876
  name: "labelTrailing",
877
877
  fn: f(() => [
878
- F($.$slots, "labelTrailing")
878
+ B($.$slots, "labelTrailing")
879
879
  ]),
880
880
  key: "1"
881
881
  } : void 0,
882
882
  $.$slots.readonly ? {
883
883
  name: "readonly",
884
884
  fn: f(() => [
885
- F($.$slots, "readonly")
885
+ B($.$slots, "readonly")
886
886
  ]),
887
887
  key: "2"
888
888
  } : void 0
889
889
  ]), 1040, ["value"]));
890
890
  }
891
- }), Fa = ["disabled"], uo = /* @__PURE__ */ G({
891
+ }), Ba = ["disabled"], uo = /* @__PURE__ */ G({
892
892
  __name: "FormGroupButton",
893
893
  props: {
894
894
  label: {},
@@ -898,7 +898,7 @@ const ya = { class: "w-full" }, ga = ["id", "accept", "disabled", "aria-describe
898
898
  emits: ["click"],
899
899
  setup(r, { emit: a }) {
900
900
  const e = r, t = a;
901
- return (n, o) => (u(), D(Bt, null, {
901
+ return (n, o) => (u(), D(Ft, null, {
902
902
  default: f(() => [
903
903
  j(it, { layout: "stacked" }, {
904
904
  default: f(() => [
@@ -907,7 +907,7 @@ const ya = { class: "w-full" }, ga = ["id", "accept", "disabled", "aria-describe
907
907
  disabled: e.disabled,
908
908
  class: I(["w-full py-1 text-center text-body focus-visible:outline-2 focus-visible:outline-border-focus disabled:text-content-disabled", e.tone === "critical" ? "text-content-destructive" : "text-content-link"]),
909
909
  onClick: o[0] || (o[0] = (c) => t("click"))
910
- }, _(e.label), 11, Fa)
910
+ }, _(e.label), 11, Ba)
911
911
  ]),
912
912
  _: 1
913
913
  })
@@ -918,10 +918,10 @@ const ya = { class: "w-full" }, ga = ["id", "accept", "disabled", "aria-describe
918
918
  }), co = /* @__PURE__ */ G({
919
919
  __name: "FormIndent",
920
920
  setup(r) {
921
- return at(ut, dt() + 1), (a, e) => F(a.$slots, "default");
921
+ return at(ut, dt() + 1), (a, e) => B(a.$slots, "default");
922
922
  }
923
923
  });
924
- function Ba(r, a) {
924
+ function Fa(r, a) {
925
925
  return a.filter((e) => (r?.[e] ?? "").trim() === "");
926
926
  }
927
927
  const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows", "placeholder", "maxlength", "disabled", "aria-required", "aria-invalid", "aria-describedby"], za = ["id", "value", "lang", "name", "placeholder", "maxlength", "disabled", "aria-required", "aria-invalid", "aria-describedby"], Va = {
@@ -990,12 +990,12 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
990
990
  function K(v) {
991
991
  w.value?.contains(v.relatedTarget) || (T.value = !0);
992
992
  }
993
- const E = h(() => Ba(t.value, e.requiredLocales)), ae = h(() => T.value && E.value.length > 0 ? n("core.form.i18n.required", { languages: ne(E.value) }) : void 0), se = h(() => e.requiredLocales.length > 0 ? E.value.length === 0 : C.value.some(R)), ee = h(() => C.value.filter((v) => !R(v) && !(ae.value && E.value.includes(v)))), ke = h(() => R(b.value) && C.value.some((v) => v !== b.value && !R(v)));
993
+ const E = h(() => Fa(t.value, e.requiredLocales)), ae = h(() => T.value && E.value.length > 0 ? n("core.form.i18n.required", { languages: ne(E.value) }) : void 0), se = h(() => e.requiredLocales.length > 0 ? E.value.length === 0 : C.value.some(R)), ee = h(() => C.value.filter((v) => !R(v) && !(ae.value && E.value.includes(v)))), ke = h(() => R(b.value) && C.value.some((v) => v !== b.value && !R(v)));
994
994
  function we() {
995
995
  const v = O(b.value);
996
996
  t.value = { ...t.value, ...Object.fromEntries(C.value.filter((V) => !R(V)).map((V) => [V, v])) };
997
997
  }
998
- const Y = h(() => [o.value, b.value, ...C.value].find((v) => C.value.includes(v) && R(v))), ve = h(() => C.value.filter((v) => v !== Y.value)), B = h(() => ve.value.filter(R).length), d = A(!1), z = h(() => e.label && !$.value && Y.value ? `${e.label} · ${X(Y.value)}` : e.label);
998
+ const Y = h(() => [o.value, b.value, ...C.value].find((v) => C.value.includes(v) && R(v))), ve = h(() => C.value.filter((v) => v !== Y.value)), F = h(() => ve.value.filter(R).length), d = A(!1), z = h(() => e.label && !$.value && Y.value ? `${e.label} · ${X(Y.value)}` : e.label);
999
999
  return a({ focus: () => k.value?.focus() }), (v, V) => (u(), D(ge, W({ ...l(de)(e), label: z.value, error: e.error ?? ae.value, required: e.required || e.requiredLocales.length > 0 }, {
1000
1000
  value: l($) ? se.value ? "written" : null : Y.value ? O(Y.value) : null,
1001
1001
  "row-layout": "stacked"
@@ -1032,7 +1032,7 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
1032
1032
  "aria-describedby": N,
1033
1033
  "data-test": "i18n-input",
1034
1034
  class: "block w-full resize-y border-0 bg-transparent px-0 py-1 text-body text-content-strong placeholder:text-content-disabled focus:outline-none focus:ring-0 disabled:cursor-not-allowed",
1035
- onInput: V[0] || (V[0] = (Be) => Q(x.value, Be.target.value))
1035
+ onInput: V[0] || (V[0] = (Fe) => Q(x.value, Fe.target.value))
1036
1036
  }, null, 40, Ta)) : (u(), g("input", {
1037
1037
  key: 1,
1038
1038
  id: S,
@@ -1050,7 +1050,7 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
1050
1050
  "aria-describedby": N,
1051
1051
  "data-test": "i18n-input",
1052
1052
  class: "block w-full min-w-0 border-0 bg-transparent px-0 py-1 text-body text-content-strong placeholder:text-content-disabled focus:outline-none focus:ring-0 disabled:cursor-not-allowed",
1053
- onInput: V[1] || (V[1] = (Be) => Q(x.value, Be.target.value))
1053
+ onInput: V[1] || (V[1] = (Fe) => Q(x.value, Fe.target.value))
1054
1054
  }, null, 40, za))
1055
1055
  ], 2)
1056
1056
  ], 8, La),
@@ -1111,7 +1111,7 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
1111
1111
  class: "mt-1.5 flex w-full cursor-pointer items-center gap-2 text-left text-footnote text-content-muted focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-border-focus",
1112
1112
  onClick: V[2] || (V[2] = (S) => d.value = !d.value)
1113
1113
  }, [
1114
- y("span", Na, _(l(n)("core.form.i18n.more", { count: ve.value.length, filled: B.value })), 1),
1114
+ y("span", Na, _(l(n)("core.form.i18n.more", { count: ve.value.length, filled: F.value })), 1),
1115
1115
  j(l(Z), {
1116
1116
  name: "arrowRightSLine",
1117
1117
  size: 16,
@@ -1140,7 +1140,7 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
1140
1140
  v.$slots.trailing ? {
1141
1141
  name: "trailing",
1142
1142
  fn: f(() => [
1143
- F(v.$slots, "trailing")
1143
+ B(v.$slots, "trailing")
1144
1144
  ]),
1145
1145
  key: "1"
1146
1146
  } : void 0
@@ -1186,21 +1186,21 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
1186
1186
  c.$slots.trailing ? {
1187
1187
  name: "trailing",
1188
1188
  fn: f(() => [
1189
- F(c.$slots, "trailing")
1189
+ B(c.$slots, "trailing")
1190
1190
  ]),
1191
1191
  key: "0"
1192
1192
  } : void 0,
1193
1193
  c.$slots.labelTrailing ? {
1194
1194
  name: "labelTrailing",
1195
1195
  fn: f(() => [
1196
- F(c.$slots, "labelTrailing")
1196
+ B(c.$slots, "labelTrailing")
1197
1197
  ]),
1198
1198
  key: "1"
1199
1199
  } : void 0,
1200
1200
  c.$slots.readonly ? {
1201
1201
  name: "readonly",
1202
1202
  fn: f(() => [
1203
- F(c.$slots, "readonly")
1203
+ B(c.$slots, "readonly")
1204
1204
  ]),
1205
1205
  key: "2"
1206
1206
  } : void 0
@@ -1293,21 +1293,21 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
1293
1293
  w.$slots.trailing ? {
1294
1294
  name: "trailing",
1295
1295
  fn: f(() => [
1296
- F(w.$slots, "trailing")
1296
+ B(w.$slots, "trailing")
1297
1297
  ]),
1298
1298
  key: "0"
1299
1299
  } : void 0,
1300
1300
  w.$slots.labelTrailing ? {
1301
1301
  name: "labelTrailing",
1302
1302
  fn: f(() => [
1303
- F(w.$slots, "labelTrailing")
1303
+ B(w.$slots, "labelTrailing")
1304
1304
  ]),
1305
1305
  key: "1"
1306
1306
  } : void 0,
1307
1307
  w.$slots.readonly ? {
1308
1308
  name: "readonly",
1309
1309
  fn: f(() => [
1310
- F(w.$slots, "readonly")
1310
+ B(w.$slots, "readonly")
1311
1311
  ]),
1312
1312
  key: "2"
1313
1313
  } : void 0
@@ -1437,7 +1437,7 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
1437
1437
  s.$slots.option ? {
1438
1438
  name: "option",
1439
1439
  fn: f((x) => [
1440
- F(s.$slots, "option", ze(Ve(x)))
1440
+ B(s.$slots, "option", ze(Ve(x)))
1441
1441
  ]),
1442
1442
  key: "0"
1443
1443
  } : void 0
@@ -1492,7 +1492,7 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
1492
1492
  s.$slots.option ? {
1493
1493
  name: "option",
1494
1494
  fn: f((x) => [
1495
- F(s.$slots, "option", ze(Ve(x)))
1495
+ B(s.$slots, "option", ze(Ve(x)))
1496
1496
  ]),
1497
1497
  key: "0"
1498
1498
  } : void 0
@@ -1506,21 +1506,21 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
1506
1506
  s.$slots.trailing ? {
1507
1507
  name: "trailing",
1508
1508
  fn: f(() => [
1509
- F(s.$slots, "trailing")
1509
+ B(s.$slots, "trailing")
1510
1510
  ]),
1511
1511
  key: "0"
1512
1512
  } : void 0,
1513
1513
  s.$slots.labelTrailing ? {
1514
1514
  name: "labelTrailing",
1515
1515
  fn: f(() => [
1516
- F(s.$slots, "labelTrailing")
1516
+ B(s.$slots, "labelTrailing")
1517
1517
  ]),
1518
1518
  key: "1"
1519
1519
  } : void 0,
1520
1520
  s.$slots.readonly ? {
1521
1521
  name: "readonly",
1522
1522
  fn: f(() => [
1523
- F(s.$slots, "readonly")
1523
+ B(s.$slots, "readonly")
1524
1524
  ]),
1525
1525
  key: "2"
1526
1526
  } : void 0
@@ -1562,7 +1562,7 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
1562
1562
  function $(s) {
1563
1563
  if (!s) return;
1564
1564
  const m = Qe(s, { accept: a.accept, maxSize: a.maxSize });
1565
- m ? o.value = m === "invalid_type" ? t("core.form.file.invalid_type") : t("core.form.file.too_large", { size: Fe(a.maxSize) }) : (o.value = null, e.value = s);
1565
+ m ? o.value = m === "invalid_type" ? t("core.form.file.invalid_type") : t("core.form.file.too_large", { size: Be(a.maxSize) }) : (o.value = null, e.value = s);
1566
1566
  }
1567
1567
  return (s, m) => (u(), D(ge, W({ ...l(de)(a), error: o.value ?? a.error }, {
1568
1568
  value: p.value ? l(t)("core.form.file.choose") : null,
@@ -1656,14 +1656,14 @@ const La = ["id", "aria-labelledby"], Ta = ["id", "value", "lang", "name", "rows
1656
1656
  s.$slots.trailing ? {
1657
1657
  name: "trailing",
1658
1658
  fn: f(() => [
1659
- F(s.$slots, "trailing")
1659
+ B(s.$slots, "trailing")
1660
1660
  ]),
1661
1661
  key: "0"
1662
1662
  } : void 0,
1663
1663
  s.$slots.labelTrailing ? {
1664
1664
  name: "labelTrailing",
1665
1665
  fn: f(() => [
1666
- F(s.$slots, "labelTrailing")
1666
+ B(s.$slots, "labelTrailing")
1667
1667
  ]),
1668
1668
  key: "1"
1669
1669
  } : void 0
@@ -1723,7 +1723,8 @@ const il = {
1723
1723
  form: { default: void 0 },
1724
1724
  saveLabel: { default: void 0 },
1725
1725
  canSave: { type: Boolean, default: !0 },
1726
- fieldLabel: { type: Function, default: void 0 }
1726
+ fieldLabel: { type: Function, default: void 0 },
1727
+ disabledWhileClean: { type: Boolean, default: !1 }
1727
1728
  },
1728
1729
  emits: ["save", "cancel"],
1729
1730
  setup(r, { emit: a }) {
@@ -1732,8 +1733,7 @@ const il = {
1732
1733
  form: e.form,
1733
1734
  label: () => e.saveLabel ?? n("core.actions.save"),
1734
1735
  allowed: () => e.canSave,
1735
- disabledWhileClean: !1,
1736
- // a create page: an untouched form is submitted to learn what is missing
1736
+ disabledWhileClean: () => e.disabledWhileClean,
1737
1737
  save: () => {
1738
1738
  e.form?.submitting.value || t("save");
1739
1739
  },
@@ -1770,7 +1770,7 @@ const il = {
1770
1770
  progress: l(p),
1771
1771
  onSelect: $
1772
1772
  }, null, 8, ["states", "progress"]),
1773
- F(s.$slots, "aside")
1773
+ B(s.$slots, "aside")
1774
1774
  ])),
1775
1775
  y("div", {
1776
1776
  ref_key: "content",
@@ -1783,7 +1783,7 @@ const il = {
1783
1783
  label: e.fieldLabel,
1784
1784
  scope: k.value
1785
1785
  }, null, 8, ["form", "label", "scope"])) : L("", !0),
1786
- F(s.$slots, "default")
1786
+ B(s.$slots, "default")
1787
1787
  ], 512)
1788
1788
  ]),
1789
1789
  l(o) ? (u(), D(Mt, {
@@ -1796,28 +1796,28 @@ const il = {
1796
1796
  s.$slots.header ? {
1797
1797
  name: "header",
1798
1798
  fn: f(() => [
1799
- F(s.$slots, "header")
1799
+ B(s.$slots, "header")
1800
1800
  ]),
1801
1801
  key: "0"
1802
1802
  } : void 0,
1803
1803
  s.$slots.pager ? {
1804
1804
  name: "pager",
1805
1805
  fn: f(() => [
1806
- F(s.$slots, "pager")
1806
+ B(s.$slots, "pager")
1807
1807
  ]),
1808
1808
  key: "1"
1809
1809
  } : void 0,
1810
1810
  s.$slots.notices ? {
1811
1811
  name: "notices",
1812
1812
  fn: f(() => [
1813
- F(s.$slots, "notices")
1813
+ B(s.$slots, "notices")
1814
1814
  ]),
1815
1815
  key: "2"
1816
1816
  } : void 0,
1817
1817
  s.$slots.bottom ? {
1818
1818
  name: "bottom",
1819
1819
  fn: f(() => [
1820
- F(s.$slots, "bottom")
1820
+ B(s.$slots, "bottom")
1821
1821
  ]),
1822
1822
  key: "3"
1823
1823
  } : void 0
@@ -2024,7 +2024,7 @@ function ho(r, a) {
2024
2024
  }), ve = h(() => {
2025
2025
  const d = t.value[b.value];
2026
2026
  return d.nextLabel ? d.nextLabel : X.value ? a.submitLabel ?? e("core.actions.save") : e("core.steps.next_named", { step: t.value[b.value + 1].label });
2027
- }), B = h(() => R.value ? null : t.value[b.value - 1].label);
2027
+ }), F = h(() => R.value ? null : t.value[b.value - 1].label);
2028
2028
  return {
2029
2029
  steps: q,
2030
2030
  current: x,
@@ -2036,7 +2036,7 @@ function ho(r, a) {
2036
2036
  direction: i,
2037
2037
  subtitle: Y,
2038
2038
  nextLabel: ve,
2039
- backLabel: B,
2039
+ backLabel: F,
2040
2040
  restored: w,
2041
2041
  refusals: k,
2042
2042
  errors: r.errors,
@@ -2239,7 +2239,7 @@ const vl = {
2239
2239
  class: I(["flex min-w-0 flex-col gap-group-gap outline-none", a.flow.direction.value === "back" ? "animate-step-back" : a.flow.direction.value === "forward" ? "animate-step-in" : ""]),
2240
2240
  onSubmit: i[1] || (i[1] = pe((p) => a.flow.next(), ["prevent"]))
2241
2241
  }, [
2242
- F(c.$slots, a.flow.current.value.name),
2242
+ B(c.$slots, a.flow.current.value.name),
2243
2243
  i[3] || (i[3] = y("button", {
2244
2244
  type: "submit",
2245
2245
  class: "sr-only",
@@ -2261,7 +2261,7 @@ export {
2261
2261
  oo as CheckboxField,
2262
2262
  no as ChoiceChips,
2263
2263
  so as ComboField,
2264
- Fo as CommandDialog,
2264
+ Bo as CommandDialog,
2265
2265
  Wo as DateField,
2266
2266
  ro as DateTimeField,
2267
2267
  yo as EditorPage,
@@ -2269,7 +2269,7 @@ export {
2269
2269
  ge as Field,
2270
2270
  io as FileField,
2271
2271
  He as FormErrors,
2272
- Bt as FormGroup,
2272
+ Ft as FormGroup,
2273
2273
  uo as FormGroupButton,
2274
2274
  co as FormIndent,
2275
2275
  it as FormRow,
@@ -2301,16 +2301,16 @@ export {
2301
2301
  en as createFieldGroups,
2302
2302
  Vo as createLeaveGuard,
2303
2303
  ce as fieldDefaults,
2304
- Bo as fieldKey,
2304
+ Fo as fieldKey,
2305
2305
  de as fieldProps,
2306
2306
  Te as focusFirstError,
2307
2307
  No as formEditableKey,
2308
- Fe as formatBytes,
2308
+ Be as formatBytes,
2309
2309
  Go as groupOptions,
2310
2310
  qo as installLeaveGuard,
2311
2311
  Do as leaveGuardKey,
2312
2312
  Ko as matchOptions,
2313
- Ba as missingLocales,
2313
+ Fa as missingLocales,
2314
2314
  tn as provideRecordGroups,
2315
2315
  Uo as recentChoicesKey,
2316
2316
  an as recordGroupsKey,
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** The version of @wssto2/vue-core (kept equal to package.json by index.test.ts). */
2
- export declare const version = "0.9.0";
2
+ export declare const version = "0.9.1";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const o = "0.9.0";
1
+ const o = "0.9.1";
2
2
  export {
3
3
  o as version
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wssto2/vue-core",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "goCore": "v1.12.0",
5
5
  "description": "Shared Vue 3 library for go-core applications: app shell, list / record / form pages and their controls.",
6
6
  "keywords": [