@juspay/svelte-ui-components 2.136.8 → 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.
@@ -9,9 +9,18 @@
9
9
  triggerClasses,
10
10
  classes,
11
11
  testId,
12
- disabled = false
12
+ disabled = false,
13
+ panelId
13
14
  }: AccordionProperties = $props();
14
15
 
16
+ /* The trigger and the panel are siblings, not ancestor/descendant, so nothing in the
17
+ markup tells assistive technology which region the trigger's aria-expanded refers to.
18
+ A generated id keeps that link automatic -- consumers pass no id and get correct
19
+ wiring -- while `panelId` lets a caller supply their own when they need to reference
20
+ the panel from elsewhere too. */
21
+ const uid = $props.id();
22
+ const effectivePanelId = $derived(panelId ?? `accordion-panel-${uid}`);
23
+
15
24
  function handleTriggerClick(): void {
16
25
  if (disabled) {
17
26
  return;
@@ -28,6 +37,7 @@
28
37
  role="button"
29
38
  tabindex={disabled ? -1 : 0}
30
39
  aria-expanded={expand}
40
+ aria-controls={effectivePanelId}
31
41
  aria-disabled={disabled}
32
42
  onclick={handleTriggerClick}
33
43
  onkeydown={(event) => {
@@ -42,6 +52,7 @@
42
52
  {/if}
43
53
 
44
54
  <div
55
+ id={effectivePanelId}
45
56
  class="accordion {classes ?? ''}"
46
57
  class:expanded={expand}
47
58
  data-pw={typeof testId === 'string' ? testId : null}
@@ -17,6 +17,13 @@ export type OptionalAccordionProperties = {
17
17
  * can be shown open or closed under external (controlled) state.
18
18
  */
19
19
  disabled?: boolean;
20
+ /**
21
+ * `id` for the collapsible panel, which the built-in trigger references via
22
+ * `aria-controls`. Defaults to a generated, per-instance id, so the trigger and
23
+ * panel are always linked without any caller involvement. Supply one only when
24
+ * something else needs to reference the panel by a known id.
25
+ */
26
+ panelId?: string;
20
27
  };
21
28
  export type AccordionEventProperties = {
22
29
  ontoggle?: (expanded: boolean) => void;
@@ -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: {},
@@ -11760,78 +11770,85 @@ var root$49 = /* @__PURE__ */ from_html("<div role=\"button\"><!></div>"), root_
11760
11770
  code: ".accordion-trigger.svelte-1p9ezsm {cursor:var(--accordion-trigger-cursor, pointer);}.accordion-trigger.disabled.svelte-1p9ezsm {cursor:var(--accordion-trigger-disabled-cursor, not-allowed);}.accordion.svelte-1p9ezsm {display:grid;grid-template-rows:0fr;overflow:hidden;transition:grid-template-rows var(--accordion-transition, 0.2s ease-out);}.accordion.expanded.svelte-1p9ezsm {grid-template-rows:1fr;}.accordion-content.svelte-1p9ezsm {min-height:0;}"
11761
11771
  };
11762
11772
  function Accordion(e, t) {
11773
+ let n = props_id();
11763
11774
  push(t, !0), append_styles$1(e, $$css$47);
11764
- let n = prop(t, "expand", 15, !1), i = prop(t, "children", 7), a = prop(t, "trigger", 7), o = prop(t, "ontoggle", 7), s = prop(t, "triggerClasses", 7), c = prop(t, "classes", 7), l = prop(t, "testId", 7), u = prop(t, "disabled", 7, !1);
11765
- function f() {
11766
- u() || (n(!n()), o()?.(n()));
11775
+ let i = prop(t, "expand", 15, !1), a = prop(t, "children", 7), o = prop(t, "trigger", 7), s = prop(t, "ontoggle", 7), c = prop(t, "triggerClasses", 7), l = prop(t, "classes", 7), u = prop(t, "testId", 7), f = prop(t, "disabled", 7, !1), p = prop(t, "panelId", 7), h = /* @__PURE__ */ user_derived(() => p() ?? `accordion-panel-${n}`);
11776
+ function S() {
11777
+ f() || (i(!i()), s()?.(i()));
11767
11778
  }
11768
- var p = {
11779
+ var C = {
11769
11780
  get expand() {
11770
- return n();
11781
+ return i();
11771
11782
  },
11772
11783
  set expand(e = !1) {
11773
- n(e), flushSync();
11784
+ i(e), flushSync();
11774
11785
  },
11775
11786
  get children() {
11776
- return i();
11787
+ return a();
11777
11788
  },
11778
11789
  set children(e) {
11779
- i(e), flushSync();
11790
+ a(e), flushSync();
11780
11791
  },
11781
11792
  get trigger() {
11782
- return a();
11793
+ return o();
11783
11794
  },
11784
11795
  set trigger(e) {
11785
- a(e), flushSync();
11796
+ o(e), flushSync();
11786
11797
  },
11787
11798
  get ontoggle() {
11788
- return o();
11799
+ return s();
11789
11800
  },
11790
11801
  set ontoggle(e) {
11791
- o(e), flushSync();
11802
+ s(e), flushSync();
11792
11803
  },
11793
11804
  get triggerClasses() {
11794
- return s();
11805
+ return c();
11795
11806
  },
11796
11807
  set triggerClasses(e) {
11797
- s(e), flushSync();
11808
+ c(e), flushSync();
11798
11809
  },
11799
11810
  get classes() {
11800
- return c();
11811
+ return l();
11801
11812
  },
11802
11813
  set classes(e) {
11803
- c(e), flushSync();
11814
+ l(e), flushSync();
11804
11815
  },
11805
11816
  get testId() {
11806
- return l();
11817
+ return u();
11807
11818
  },
11808
11819
  set testId(e) {
11809
- l(e), flushSync();
11820
+ u(e), flushSync();
11810
11821
  },
11811
11822
  get disabled() {
11812
- return u();
11823
+ return f();
11813
11824
  },
11814
11825
  set disabled(e = !1) {
11815
- u(e), flushSync();
11826
+ f(e), flushSync();
11827
+ },
11828
+ get panelId() {
11829
+ return p();
11830
+ },
11831
+ set panelId(e) {
11832
+ p(e), flushSync();
11816
11833
  }
11817
- }, h = root_1$42(), S = first_child(h), C = (e) => {
11834
+ }, k = root_1$42(), R = first_child(k), G = (e) => {
11818
11835
  var t = root$49();
11819
- let i;
11820
- snippet(child(t), a, () => ({ expanded: n() })), reset(t), template_effect(() => {
11821
- i = set_class(t, 1, `accordion-trigger ${s() ?? "" ?? ""}`, "svelte-1p9ezsm", i, { disabled: u() }), set_attribute(t, "tabindex", u() ? -1 : 0), set_attribute(t, "aria-expanded", n()), set_attribute(t, "aria-disabled", u());
11822
- }), delegated("click", t, f), delegated("keydown", t, (e) => {
11823
- (e.key === "Enter" || e.key === " ") && (e.preventDefault(), f());
11836
+ let n;
11837
+ snippet(child(t), o, () => ({ expanded: i() })), reset(t), template_effect(() => {
11838
+ n = set_class(t, 1, `accordion-trigger ${c() ?? "" ?? ""}`, "svelte-1p9ezsm", n, { disabled: f() }), set_attribute(t, "tabindex", f() ? -1 : 0), set_attribute(t, "aria-expanded", i()), set_attribute(t, "aria-controls", get(h)), set_attribute(t, "aria-disabled", f());
11839
+ }), delegated("click", t, S), delegated("keydown", t, (e) => {
11840
+ (e.key === "Enter" || e.key === " ") && (e.preventDefault(), S());
11824
11841
  }), append(e, t);
11825
11842
  };
11826
- if_block(S, (e) => {
11827
- a() && e(C);
11843
+ if_block(R, (e) => {
11844
+ o() && e(G);
11828
11845
  });
11829
- var k = sibling(S, 2);
11830
- let R;
11831
- var G = child(k);
11832
- return snippet(child(G), () => i() ?? noop), reset(G), reset(k), template_effect(() => {
11833
- R = set_class(k, 1, `accordion ${c() ?? "" ?? ""}`, "svelte-1p9ezsm", R, { expanded: n() }), set_attribute(k, "data-pw", typeof l() == "string" ? l() : null), set_attribute(k, "testid", typeof l() == "string" ? l() : null);
11834
- }), append(e, h), pop(p);
11846
+ var te = sibling(R, 2);
11847
+ let ne;
11848
+ var re = child(te);
11849
+ return snippet(child(re), () => a() ?? noop), reset(re), reset(te), template_effect(() => {
11850
+ set_attribute(te, "id", get(h)), ne = set_class(te, 1, `accordion ${l() ?? "" ?? ""}`, "svelte-1p9ezsm", ne, { expanded: i() }), set_attribute(te, "data-pw", typeof u() == "string" ? u() : null), set_attribute(te, "testid", typeof u() == "string" ? u() : null);
11851
+ }), append(e, k), pop(C);
11835
11852
  }
11836
11853
  delegate(["click", "keydown"]), create_custom_element(Accordion, {
11837
11854
  expand: {},
@@ -11841,7 +11858,8 @@ delegate(["click", "keydown"]), create_custom_element(Accordion, {
11841
11858
  triggerClasses: {},
11842
11859
  classes: {},
11843
11860
  testId: {},
11844
- disabled: {}
11861
+ disabled: {},
11862
+ panelId: {}
11845
11863
  }, [], [], { mode: "open" });
11846
11864
  //#endregion
11847
11865
  //#region src/wc/components/Accordion.wc.svelte
@@ -11874,6 +11892,10 @@ customElements.define("sui-accordion", create_custom_element(Accordion_wc, {
11874
11892
  testId: {
11875
11893
  attribute: "test-id",
11876
11894
  type: "String"
11895
+ },
11896
+ panelId: {
11897
+ attribute: "panel-id",
11898
+ type: "String"
11877
11899
  }
11878
11900
  }, ["default"], [], { mode: "open" }));
11879
11901
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/svelte-ui-components",
3
- "version": "2.136.8",
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",