bitboss-ui 3.0.0-beta.49 → 3.0.0-beta.50

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.
@@ -246,6 +246,11 @@ const config = useConfig();
246
246
  export type { BbNumberInputProps, BbNumberInputEvents, BbNumberInputSlots };
247
247
 
248
248
  const active = ref(false);
249
+ /**
250
+ * Read-only (the prop or a BbForm save in flight) or disabled: no input path
251
+ * may change the text or the value (readonly-fix, beta.49).
252
+ */
253
+ const locked = computed(() => !!fieldReadonly.value || !!props.disabled);
249
254
  const showHint = computed(() => props.persistentHint || active.value);
250
255
  const hasValue = computed(() => isNotNil(props.modelValue));
251
256
  // Mirrors BbTextInput/BbTextarea: the container reserves clear-icon space and
@@ -553,6 +558,12 @@ const replacementEdit = (text: string, start: number, end: number): Edit =>
553
558
  const onBeforeinput = (event: InputEvent) => {
554
559
  const el = input.value;
555
560
  if (legacy.value || busy || !el) return;
561
+ // Read-only, disabled or form-locked: every edit is cancelled here, as the
562
+ // native `readonly` would (the edit paths below write through execCommand).
563
+ if (locked.value) {
564
+ if (event.cancelable) event.preventDefault();
565
+ return;
566
+ }
556
567
  if (composing || event.isComposing || !event.cancelable) return;
557
568
  // A keyboard that announces no text (Android, empty `data`): the browser
558
569
  // applies it and the fallback reads it on `input` (GROK-INGEST 3).
@@ -787,6 +798,9 @@ const onFormattedInput = (event: Event) => {
787
798
  return;
788
799
  }
789
800
  if (composing) return;
801
+ // A browser-applied edit to a locked field (Android, a script): our text
802
+ // comes back, nothing is read.
803
+ if (locked.value) return paint();
790
804
  const type = (event as InputEvent).inputType ?? '';
791
805
  if (REREAD_TYPES.has(type) || !(event instanceof InputEvent)) {
792
806
  rereadAll();
@@ -802,8 +816,11 @@ const onCompositionstart = () => {
802
816
  };
803
817
 
804
818
  const onCompositionend = (event: CompositionEvent) => {
819
+ if (legacy.value && locked.value && input.value)
820
+ input.value.value = props.modelValue?.toString() || '';
805
821
  if (legacy.value || !composing) return;
806
822
  composing = false;
823
+ if (locked.value) return paint();
807
824
  applyBrowserEdit(event);
808
825
  };
809
826
 
@@ -813,6 +830,7 @@ const posted = ref<HTMLInputElement | null>(null);
813
830
  /** The text differs from what we wrote (a restore, autofill): read it again. */
814
831
  const reconcile = () => {
815
832
  if (legacy.value || !input.value) return;
833
+ if (input.value.value !== lastWritten && locked.value) return paint();
816
834
  if (input.value.value !== lastWritten) {
817
835
  rereadAll();
818
836
  commitTyped();
@@ -899,6 +917,8 @@ const normalizeNumericValue = (value: number, withMin = true): number => {
899
917
  * "15" with min 10 could not be typed through its "1".
900
918
  */
901
919
  const applyMin = () => {
920
+ // A locked field never moves its value, not even up to `min`.
921
+ if (locked.value) return;
902
922
  if (!legacy.value) {
903
923
  // Enter re-reads an outside text first, as blur does (PANEL § 2.7).
904
924
  reconcile();
@@ -929,7 +949,7 @@ const nextStep = (value: number) => {
929
949
  * Decrements value by `step` and emits both semantic and model events.
930
950
  */
931
951
  const decrease = () => {
932
- if (props.disabled || props.readonly) return;
952
+ if (locked.value) return;
933
953
  const valueToEmit = nextStep(props.step * -1);
934
954
  emit('decrease', valueToEmit);
935
955
  emit('update:modelValue', valueToEmit);
@@ -939,7 +959,7 @@ const decrease = () => {
939
959
  * Increments value by `step` and emits both semantic and model events.
940
960
  */
941
961
  const increase = () => {
942
- if (props.disabled || props.readonly) return;
962
+ if (locked.value) return;
943
963
  const valueToEmit = nextStep(props.step);
944
964
  emit('increase', valueToEmit);
945
965
  emit('update:modelValue', valueToEmit);
@@ -960,6 +980,10 @@ const increase = () => {
960
980
  const onInput = (event: Event) => {
961
981
  if (!legacy.value) return onFormattedInput(event);
962
982
  if (!input.value) return;
983
+ if (locked.value) {
984
+ input.value.value = props.modelValue?.toString() || '';
985
+ return;
986
+ }
963
987
  if (event.target instanceof HTMLInputElement) {
964
988
  const value = event.target.value;
965
989
  const selectionStart = event.target.selectionStart;
@@ -124,7 +124,7 @@ var P = {
124
124
  }, G = g(() => {
125
125
  let { onClick: e, class: t, ...n } = H;
126
126
  return n;
127
- }), K = E(0), q = S(l, null), J = g(() => I.loading || !!K.value && !I.disableAutoLoading || I.type === "submit" && !!q?.locked()), Y = n(J), X = t({
127
+ }), K = E(0), q = S(l, null), J = g(() => I.loading || !!K.value && !I.disableAutoLoading || I.type === "submit" && !!q?.saving()), Y = n(J), X = t({
128
128
  component: "BbButton",
129
129
  attrs: H,
130
130
  props: I,
@@ -72,10 +72,10 @@ declare const __VLS_export: <S extends BbFormSchema = BbFormSchema>(__VLS_props:
72
72
  /**
73
73
  * Keep the fields editable while a save runs. By default, while a
74
74
  * `@submit` that returned a promise is pending, every field joined to the
75
- * form is read-only (never disabled: values stay readable and focusable)
76
- * and every `type="submit"` BbButton inside the form shows its spinner;
77
- * both end when the promise settles. A `@submit` that returns nothing
78
- * never locks.
75
+ * form is read-only (never disabled: values stay readable and focusable);
76
+ * it ends when the promise settles. A `@submit` that returns nothing never
77
+ * locks. The `type="submit"` BbButtons inside the form show their spinner
78
+ * while the save is pending either way: this prop does not stop that.
79
79
  */
80
80
  disableSubmitLock?: boolean;
81
81
  } & {
@@ -191,7 +191,10 @@ var _e = ["id"], ve = /*@__PURE__*/ u({
191
191
  let i = document.activeElement;
192
192
  i !== r && i && i !== document.body || Fe(n.errors);
193
193
  }, I = ce(), L = h(0), Le = () => L.value > 0 && !_.disableSubmitLock;
194
- p(e, { locked: Le });
194
+ p(e, {
195
+ locked: Le,
196
+ saving: () => L.value > 0
197
+ });
195
198
  let Re = !1, ze = (e) => {
196
199
  let t = I?.appContext.config.errorHandler;
197
200
  t ? t(e, I?.proxy ?? null, "component event handler") : console.error(e);