@juspay/svelte-ui-components 2.136.9 → 2.136.10

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.
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { tick } from 'svelte';
2
3
  import Input from '../Input/Input.svelte';
3
4
  import type { FieldConfig, SplitInputProperties } from './properties';
4
5
 
@@ -37,6 +38,31 @@
37
38
  return values.at(index) ?? '';
38
39
  }
39
40
 
41
+ /**
42
+ * Writes the resolved state back onto the DOM element.
43
+ *
44
+ * Needed because the element can hold a value the state never had. Typing
45
+ * into a filled field produces a two-character string in the DOM, and when
46
+ * the character we resolve out of it happens to equal what was already
47
+ * stored -- overtyping 2 with another 2 -- the assignment is a no-op, Svelte
48
+ * sees no change, and nothing re-renders. The field is then left displaying
49
+ * "22" indefinitely while the state says "2".
50
+ */
51
+ async function syncFieldElement(index: number) {
52
+ // After the pending render, not before it: writing during the input handler
53
+ // is undone when Svelte flushes, and when the resolved value is unchanged
54
+ // there is no flush to piggyback on -- so the correction has to come last.
55
+ await tick();
56
+ const element = inputRefs.at(index)?.getInputRef();
57
+ if (element === null || typeof element === 'undefined') {
58
+ return;
59
+ }
60
+ const resolved = getFieldValue(index);
61
+ if (element.value !== resolved) {
62
+ element.value = resolved;
63
+ }
64
+ }
65
+
40
66
  function commitValues() {
41
67
  const filled = values.filter((v) => v.length > 0);
42
68
  oninput?.([...values]);
@@ -104,7 +130,19 @@
104
130
  } else {
105
131
  // Overtyping an already-filled field: keep the newest character and
106
132
  // advance, mirroring single-char entry.
107
- values[index] = chars.slice(-1);
133
+ //
134
+ // Which character is "newest" cannot be assumed to be the last one.
135
+ // The browser inserts at the caret, and where the caret sits after a
136
+ // click on a filled single-character field is platform-dependent:
137
+ // Chromium on macOS puts it after the character, Chromium on Linux
138
+ // before it. So typing 7 into a field holding 2 yields "27" on one and
139
+ // "72" on the other, and slice(-1) silently picks the *old* digit on
140
+ // Linux. Removing one occurrence of the previous value identifies the
141
+ // newly typed character wherever it landed.
142
+ const previous = getFieldValue(index);
143
+ const remainder = previous.length === 1 ? chars.replace(previous, '') : '';
144
+ values[index] = remainder.length > 0 ? remainder.slice(-1) : chars.slice(-1);
145
+ void syncFieldElement(index);
108
146
  if (index < fieldCount - 1) {
109
147
  focusField(index + 1);
110
148
  }
package/dist-wc/index.js CHANGED
@@ -7050,62 +7050,72 @@ function SplitInput(e, t) {
7050
7050
  function R(e) {
7051
7051
  return n().at(e) ?? "";
7052
7052
  }
7053
- function G() {
7053
+ async function G(e) {
7054
+ await tick();
7055
+ let t = get(k).at(e)?.getInputRef();
7056
+ if (t == null) return;
7057
+ let n = R(e);
7058
+ t.value !== n && (t.value = n);
7059
+ }
7060
+ function te() {
7054
7061
  let e = n().filter((e) => e.length > 0);
7055
7062
  p()?.([...n()]), f()?.([...n()]), e.length === get(S) && h()?.([...n()]);
7056
7063
  }
7057
- function te(e) {
7064
+ function ne(e) {
7058
7065
  e >= 0 && e < get(S) && get(k).at(e)?.focus();
7059
7066
  }
7060
- function ne(e, t) {
7067
+ function re(e, t) {
7061
7068
  return (e.dataType ?? "text") === "tel" ? t.replace(/\D/g, "") : t.replace(/\s/g, "");
7062
7069
  }
7063
- function re(e) {
7070
+ function be(e) {
7064
7071
  let t = e.maxLength ?? 1e3;
7065
7072
  return s() && t === 1 ? get(S) : t;
7066
7073
  }
7067
- function be(e, t) {
7074
+ function Me(e, t) {
7068
7075
  let i = get(C).at(e);
7069
7076
  if (i === void 0) return;
7070
7077
  let a = i.maxLength ?? 1e3;
7071
7078
  if (s() && a === 1 && t.length > 1) {
7072
- let a = ne(i, t);
7079
+ let a = re(i, t);
7073
7080
  if (a.length === 0) n(n()[e] = "", !0);
7074
7081
  else if (e === 0 || a.length >= get(S)) {
7075
7082
  for (let e = 0; e < Math.min(a.length, get(S)); e++) n(n()[e] = a.charAt(e), !0);
7076
- te(Math.min(a.length, get(S)) - 1);
7077
- } else n(n()[e] = a.slice(-1), !0), e < get(S) - 1 && te(e + 1);
7078
- } else n(n()[e] = t, !0), s() && a === 1 && t.length > 0 && e < get(S) - 1 && te(e + 1);
7079
- G();
7080
- }
7081
- function Me(e, t) {
7082
- e.key === "Backspace" ? R(t).length === 0 && t > 0 && (n(n()[t - 1] = "", !0), te(t - 1), G()) : e.key === "ArrowLeft" && t > 0 ? te(t - 1) : e.key === "ArrowRight" && t < get(S) - 1 ? te(t + 1) : e.key === "Tab" && (e.shiftKey && t > 0 ? (e.preventDefault(), te(t - 1)) : e.shiftKey === !1 && t < get(S) - 1 && (e.preventDefault(), te(t + 1)));
7083
+ ne(Math.min(a.length, get(S)) - 1);
7084
+ } else {
7085
+ let t = R(e), i = t.length === 1 ? a.replace(t, "") : "";
7086
+ n(n()[e] = i.length > 0 ? i.slice(-1) : a.slice(-1), !0), G(e), e < get(S) - 1 && ne(e + 1);
7087
+ }
7088
+ } else n(n()[e] = t, !0), s() && a === 1 && t.length > 0 && e < get(S) - 1 && ne(e + 1);
7089
+ te();
7083
7090
  }
7084
7091
  function Re(e, t) {
7092
+ e.key === "Backspace" ? R(t).length === 0 && t > 0 && (n(n()[t - 1] = "", !0), ne(t - 1), te()) : e.key === "ArrowLeft" && t > 0 ? ne(t - 1) : e.key === "ArrowRight" && t < get(S) - 1 ? ne(t + 1) : e.key === "Tab" && (e.shiftKey && t > 0 ? (e.preventDefault(), ne(t - 1)) : e.shiftKey === !1 && t < get(S) - 1 && (e.preventDefault(), ne(t + 1)));
7093
+ }
7094
+ function Ue(e, t) {
7085
7095
  if (e.clipboardData === null) return;
7086
7096
  e.preventDefault();
7087
7097
  let i = e.clipboardData.getData("text").trim(), a = get(C).at(t);
7088
7098
  if (s() && a !== void 0) {
7089
- let e = ne(a, i);
7099
+ let e = re(a, i);
7090
7100
  for (let i = t; i < get(S); i++) {
7091
7101
  let a = i - t;
7092
7102
  if (a >= e.length) break;
7093
7103
  n(n()[i] = e.charAt(a), !0);
7094
7104
  }
7095
- te(Math.min(t + e.length, get(S)) - 1);
7105
+ ne(Math.min(t + e.length, get(S)) - 1);
7096
7106
  } else n(n()[t] = i, !0);
7097
- G();
7107
+ te();
7098
7108
  }
7099
- function Ue() {
7109
+ function it() {
7100
7110
  for (let e = 0; e < get(S); e++) n(n()[e] = "", !0);
7101
- p()?.([...n()]), f()?.([...n()]), te(0);
7111
+ p()?.([...n()]), f()?.([...n()]), ne(0);
7102
7112
  }
7103
- function it() {
7104
- te(0);
7113
+ function at() {
7114
+ ne(0);
7105
7115
  }
7106
- var at = {
7107
- clear: Ue,
7108
- focus: it,
7116
+ var ot = {
7117
+ clear: it,
7118
+ focus: at,
7109
7119
  get values() {
7110
7120
  return n();
7111
7121
  },
@@ -7172,8 +7182,8 @@ function SplitInput(e, t) {
7172
7182
  set oncomplete(e) {
7173
7183
  h(e), flushSync();
7174
7184
  }
7175
- }, ot = root_3$41();
7176
- return each(ot, 21, () => get(C), index, (e, t, n) => {
7185
+ }, ct = root_3$41();
7186
+ return each(ct, 21, () => get(C), index, (e, t, n) => {
7177
7187
  var i = root_2$46(), a = first_child(i), s = (e) => {
7178
7188
  var t = root$72(), n = child(t, !0);
7179
7189
  reset(t), template_effect(() => set_text(n, c())), append(e, t);
@@ -7183,7 +7193,7 @@ function SplitInput(e, t) {
7183
7193
  });
7184
7194
  var l = sibling(a, 2), u = child(l);
7185
7195
  {
7186
- let e = /* @__PURE__ */ user_derived(() => R(n)), i = /* @__PURE__ */ user_derived(() => get(t).dataType ?? "text"), a = /* @__PURE__ */ user_derived(() => re(get(t))), s = /* @__PURE__ */ user_derived(() => get(t).validationPattern ?? null), c = /* @__PURE__ */ user_derived(() => get(t).validators ?? []), l = /* @__PURE__ */ user_derived(() => get(t).autoComplete ?? "on");
7196
+ let e = /* @__PURE__ */ user_derived(() => R(n)), i = /* @__PURE__ */ user_derived(() => get(t).dataType ?? "text"), a = /* @__PURE__ */ user_derived(() => be(get(t))), s = /* @__PURE__ */ user_derived(() => get(t).validationPattern ?? null), c = /* @__PURE__ */ user_derived(() => get(t).validators ?? []), l = /* @__PURE__ */ user_derived(() => get(t).autoComplete ?? "on");
7187
7197
  bind_this(Input(u, {
7188
7198
  get value() {
7189
7199
  return get(e);
@@ -7223,9 +7233,9 @@ function SplitInput(e, t) {
7223
7233
  },
7224
7234
  actionInput: !0,
7225
7235
  classes: "field-group-input",
7226
- onInput: (e) => be(n, e),
7227
- onKeyDown: (e) => Me(e, n),
7228
- onPaste: (e) => Re(e, n)
7236
+ onInput: (e) => Me(n, e),
7237
+ onKeyDown: (e) => Re(e, n),
7238
+ onPaste: (e) => Ue(e, n)
7229
7239
  }), (e, t) => get(k)[t] = e, (e) => get(k)?.[e], () => [n]);
7230
7240
  }
7231
7241
  var f = sibling(u, 2), p = (e) => {
@@ -7235,9 +7245,9 @@ function SplitInput(e, t) {
7235
7245
  if_block(f, (e) => {
7236
7246
  typeof get(t).label == "string" && e(p);
7237
7247
  }), reset(l), append(e, i);
7238
- }), reset(ot), template_effect(() => {
7239
- set_class(ot, 1, `field-group ${u() ?? "" ?? ""}`, "svelte-1gcz5cs"), set_attribute(ot, "data-pw", l()), set_attribute(ot, "testid", l());
7240
- }), append(e, ot), pop(at);
7248
+ }), reset(ct), template_effect(() => {
7249
+ set_class(ct, 1, `field-group ${u() ?? "" ?? ""}`, "svelte-1gcz5cs"), set_attribute(ct, "data-pw", l()), set_attribute(ct, "testid", l());
7250
+ }), append(e, ct), pop(ot);
7241
7251
  }
7242
7252
  create_custom_element(SplitInput, {
7243
7253
  values: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/svelte-ui-components",
3
- "version": "2.136.9",
3
+ "version": "2.136.10",
4
4
  "description": "A themeable Svelte 5 UI component library with CSS custom property driven styling",
5
5
  "keywords": [
6
6
  "svelte",