@juspay/svelte-ui-components 3.5.0 → 3.5.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.
Files changed (152) hide show
  1. package/README.md +1 -1
  2. package/dist/Accordion/Accordion.svelte +1 -5
  3. package/dist/Accordion/properties.d.ts +0 -1
  4. package/dist/AreaChart/AreaChart.svelte +2 -8
  5. package/dist/AreaChart/properties.d.ts +0 -10
  6. package/dist/AttachmentChipRow/AttachmentChipRow.svelte +30 -30
  7. package/dist/AttachmentChipRow/properties.d.ts +6 -6
  8. package/dist/Banner/Banner.svelte +1 -5
  9. package/dist/Banner/properties.d.ts +0 -1
  10. package/dist/BarChart/BarChart.svelte +7 -13
  11. package/dist/BarChart/properties.d.ts +1 -9
  12. package/dist/Book/Book.svelte +1 -5
  13. package/dist/Book/properties.d.ts +0 -1
  14. package/dist/Calendar/Calendar.svelte +3 -11
  15. package/dist/Calendar/properties.d.ts +0 -11
  16. package/dist/Chat/Chat.svelte +9 -29
  17. package/dist/Chat/properties.d.ts +0 -9
  18. package/dist/Chat/types.d.ts +7 -0
  19. package/dist/ChatBubble/ChatBubble.svelte +3 -11
  20. package/dist/ChatBubble/properties.d.ts +0 -3
  21. package/dist/ChatComposer/ChatComposer.svelte +18 -44
  22. package/dist/ChatComposer/properties.d.ts +0 -12
  23. package/dist/ChatHeader/ChatHeader.svelte +1 -5
  24. package/dist/ChatHeader/properties.d.ts +0 -1
  25. package/dist/ChatMessage/ChatMessage.svelte +87 -11
  26. package/dist/ChatMessage/properties.d.ts +18 -3
  27. package/dist/ChatMessageList/ChatMessageList.svelte +5 -11
  28. package/dist/ChatMessageList/properties.d.ts +0 -6
  29. package/dist/ChatSuggestions/ChatSuggestions.svelte +1 -5
  30. package/dist/ChatSuggestions/properties.d.ts +0 -1
  31. package/dist/CheckListItem/CheckListItem.svelte +1 -5
  32. package/dist/CheckListItem/properties.d.ts +0 -1
  33. package/dist/Checkbox/Checkbox.svelte +1 -5
  34. package/dist/Checkbox/properties.d.ts +0 -1
  35. package/dist/ChipInput/ChipInput.svelte +10 -20
  36. package/dist/ChipInput/properties.d.ts +0 -4
  37. package/dist/Choicebox/Choicebox.svelte +1 -5
  38. package/dist/Choicebox/properties.d.ts +0 -1
  39. package/dist/ColorPicker/ColorPicker.svelte +4 -10
  40. package/dist/ColorPicker/properties.d.ts +0 -2
  41. package/dist/Combobox/Combobox.svelte +15 -33
  42. package/dist/Combobox/properties.d.ts +0 -8
  43. package/dist/CommandMenu/CommandMenu.svelte +2 -8
  44. package/dist/CommandMenu/properties.d.ts +0 -2
  45. package/dist/ContextMenu/ContextMenu.svelte +3 -11
  46. package/dist/ContextMenu/properties.d.ts +0 -3
  47. package/dist/DateRangePicker/DateRangePicker.svelte +6 -20
  48. package/dist/DateRangePicker/properties.d.ts +0 -19
  49. package/dist/Draggable/Draggable.svelte +7 -7
  50. package/dist/Draggable/properties.d.ts +3 -3
  51. package/dist/DualAxisBarChart/DualAxisBarChart.svelte +1 -5
  52. package/dist/DualAxisBarChart/properties.d.ts +0 -4
  53. package/dist/FileDropzoneTrigger/FileDropzoneTrigger.svelte +1 -5
  54. package/dist/FileDropzoneTrigger/properties.d.ts +0 -1
  55. package/dist/FileInput/FileInput.svelte +2 -8
  56. package/dist/FileInput/properties.d.ts +0 -2
  57. package/dist/FunnelChart/FunnelChart.svelte +2 -8
  58. package/dist/FunnelChart/properties.d.ts +0 -8
  59. package/dist/Gallery/Gallery.svelte +15 -15
  60. package/dist/Gallery/properties.d.ts +6 -6
  61. package/dist/HITL/HITL.svelte +10 -8
  62. package/dist/HITL/properties.d.ts +2 -2
  63. package/dist/IframeViewer/IframeViewer.svelte +3 -2
  64. package/dist/IframeViewer/properties.d.ts +1 -1
  65. package/dist/Img/Img.svelte +119 -39
  66. package/dist/Img/properties.d.ts +0 -1
  67. package/dist/Input/Input.svelte +22 -37
  68. package/dist/Input/properties.d.ts +3 -10
  69. package/dist/InputButton/InputButton.svelte +2 -2
  70. package/dist/LineChart/LineChart.svelte +4 -10
  71. package/dist/LineChart/properties.d.ts +1 -11
  72. package/dist/ListItem/ListItem.svelte +10 -22
  73. package/dist/ListItem/properties.d.ts +5 -10
  74. package/dist/LottiePlayer/LottiePlayer.svelte +2 -8
  75. package/dist/LottiePlayer/properties.d.ts +0 -2
  76. package/dist/MediaPlayer/MediaPlayer.svelte +1 -5
  77. package/dist/MediaPlayer/properties.d.ts +0 -1
  78. package/dist/MediaUpload/MediaUpload.svelte +6 -6
  79. package/dist/MediaUpload/properties.d.ts +3 -3
  80. package/dist/Menu/Menu.svelte +3 -11
  81. package/dist/Menu/properties.d.ts +0 -3
  82. package/dist/Modal/Modal.svelte +15 -31
  83. package/dist/Modal/properties.d.ts +5 -11
  84. package/dist/Pagination/Pagination.svelte +3 -7
  85. package/dist/Pagination/properties.d.ts +1 -2
  86. package/dist/PieChart/PieChart.svelte +4 -10
  87. package/dist/PieChart/properties.d.ts +1 -9
  88. package/dist/Pill/Pill.svelte +1 -5
  89. package/dist/Pill/properties.d.ts +0 -1
  90. package/dist/Radio/Radio.svelte +1 -5
  91. package/dist/Radio/properties.d.ts +0 -1
  92. package/dist/Resizable/Resizable.svelte +3 -11
  93. package/dist/Resizable/properties.d.ts +0 -3
  94. package/dist/SankeyChart/SankeyChart.svelte +4 -14
  95. package/dist/SankeyChart/properties.d.ts +0 -12
  96. package/dist/Scroller/Scroller.svelte +1 -5
  97. package/dist/Scroller/properties.d.ts +0 -1
  98. package/dist/Select/Select.svelte +3 -11
  99. package/dist/Select/properties.d.ts +0 -3
  100. package/dist/Sheet/Sheet.svelte +3 -11
  101. package/dist/Sheet/properties.d.ts +0 -3
  102. package/dist/Slider/Slider.svelte +2 -8
  103. package/dist/Slider/properties.d.ts +0 -2
  104. package/dist/Snippet/Snippet.svelte +1 -5
  105. package/dist/Snippet/properties.d.ts +0 -1
  106. package/dist/SplitButton/SplitButton.svelte +1 -5
  107. package/dist/SplitButton/properties.d.ts +0 -1
  108. package/dist/SplitInput/SplitInput.svelte +6 -14
  109. package/dist/SplitInput/properties.d.ts +0 -3
  110. package/dist/StatCard/StatCard.svelte +2 -2
  111. package/dist/StatCard/properties.d.ts +1 -1
  112. package/dist/Status/Status.svelte +2 -6
  113. package/dist/Status/properties.d.ts +1 -2
  114. package/dist/Stepper/Stepper.svelte +2 -12
  115. package/dist/Stepper/properties.d.ts +1 -14
  116. package/dist/Table/BuiltinCell.svelte +1 -1
  117. package/dist/Table/Table.svelte +16 -17
  118. package/dist/Table/properties.d.ts +3 -35
  119. package/dist/Tabs/Tabs.svelte +2 -8
  120. package/dist/Tabs/properties.d.ts +0 -2
  121. package/dist/TaskList/TaskList.svelte +1 -4
  122. package/dist/TaskList/properties.d.ts +0 -1
  123. package/dist/ThemeSwitcher/ThemeSwitcher.svelte +1 -5
  124. package/dist/ThemeSwitcher/properties.d.ts +0 -1
  125. package/dist/ThinkingIndicator/ThinkingIndicator.svelte +4 -10
  126. package/dist/ThinkingIndicator/properties.d.ts +1 -3
  127. package/dist/Toast/Toast.svelte +2 -2
  128. package/dist/Toast/properties.d.ts +1 -1
  129. package/dist/Toggle/Toggle.svelte +1 -5
  130. package/dist/Toggle/properties.d.ts +0 -1
  131. package/dist/ToolCallLog/ToolCallLog.svelte +1 -10
  132. package/dist/ToolCallLog/properties.d.ts +0 -1
  133. package/dist/Toolbar/Toolbar.svelte +2 -6
  134. package/dist/Toolbar/properties.d.ts +1 -2
  135. package/dist/TypewriterText/TypewriterText.svelte +3 -3
  136. package/dist/TypewriterText/properties.d.ts +1 -1
  137. package/dist-codemod/bin.js +32 -0
  138. package/dist-codemod/cli.js +175 -0
  139. package/dist-codemod/legacy-pairs.js +228 -0
  140. package/dist-codemod/transform.js +278 -0
  141. package/dist-codemod/wc-children.js +66 -0
  142. package/dist-wc/index.js +4458 -5127
  143. package/package.json +9 -7
  144. package/scripts/postinstall.mjs +14 -12
  145. package/dist/deprecation.d.ts +0 -42
  146. package/dist/deprecation.js +0 -57
  147. package/scripts/codemod/README.md +0 -76
  148. package/scripts/codemod/cli.ts +0 -206
  149. package/scripts/codemod/map.ts +0 -118
  150. package/scripts/codemod/transform.ts +0 -549
  151. package/scripts/codemod/tsconfig.json +0 -15
  152. package/scripts/codemod/wc-children.ts +0 -75
@@ -1,20 +1,8 @@
1
1
  <script lang="ts">
2
2
  import type { ImgProperties } from './properties';
3
3
 
4
- let {
5
- src,
6
- alt,
7
- fallback,
8
- onerror: onerrorLegacy,
9
- onError,
10
- classes,
11
- inlineSvg,
12
- transformSvg,
13
- testId
14
- }: ImgProperties = $props();
15
-
16
- // Event-casing phase 1: both spellings accepted, the correct one wins.
17
- const onerror = $derived(onError ?? onerrorLegacy);
4
+ let { src, alt, fallback, onerror, classes, inlineSvg, transformSvg, testId }: ImgProperties =
5
+ $props();
18
6
 
19
7
  let currentSrc = $derived(src);
20
8
  // Per-source failure marker: when inlining a given URL fails we fall back to
@@ -92,10 +80,83 @@
92
80
  'focusable'
93
81
  ]);
94
82
 
83
+ /**
84
+ * The host attributes this component writes itself. A fetched root may
85
+ * legitimately overwrite one (an icon set's own role/aria-label), and the
86
+ * src-change cleanup then has to put the component's value back rather than
87
+ * just remove it: Svelte only re-applies its own attribute when `alt` or
88
+ * `testId` changes, so a bare removal would leave the host with no role
89
+ * until the next re-render.
90
+ */
91
+ /**
92
+ * `alt` is a required `string` in `properties.ts`, which settles it for a
93
+ * Svelte consumer and settles nothing for a web-component one: `<sui-img>`
94
+ * takes its props from JavaScript, so an omitted `alt` arrives as undefined
95
+ * and every `alt.length` below would throw where the compiler cannot see it.
96
+ */
97
+ const label = $derived(alt ?? '');
98
+
99
+ function restoreHostOwnedAttribute(host: SVGSVGElement, name: string): boolean {
100
+ const named = label.length > 0;
101
+ switch (name.toLowerCase()) {
102
+ case 'role':
103
+ return setOrRemove(host, name, named ? 'img' : null);
104
+ case 'aria-label':
105
+ return setOrRemove(host, name, named ? label : null);
106
+ case 'aria-hidden':
107
+ return setOrRemove(host, name, named ? null : 'true');
108
+ case 'data-pw':
109
+ case 'testid':
110
+ return setOrRemove(host, name, testId ?? null);
111
+ default:
112
+ return false;
113
+ }
114
+ }
115
+
116
+ function setOrRemove(host: SVGSVGElement, name: string, value: string | null): boolean {
117
+ if (value === null) {
118
+ host.removeAttribute(name);
119
+ } else {
120
+ host.setAttribute(name, value);
121
+ }
122
+ return true;
123
+ }
124
+
95
125
  function isSafeInlineRootAttribute(lowerCaseName: string): boolean {
96
126
  return SAFE_INLINE_ROOT_ATTRIBUTES.has(lowerCaseName) || lowerCaseName.startsWith('aria-');
97
127
  }
98
128
 
129
+ /**
130
+ * Descendants removed outright, because nothing static artwork needs is
131
+ * expressed with them.
132
+ *
133
+ * `script` and `foreignObject` are the obvious two. The SMIL animation
134
+ * elements are here because SMIL animates *any* attribute by name — `<set
135
+ * attributeName="onclick" to="…">` plants an event handler, and `<animate
136
+ * attributeName="xlink:href" values="javascript:…">` plants a URL — so a
137
+ * guard that strips `on*` and bad hrefs at adoption time but keeps SMIL
138
+ * only moves the same vector one element deeper, to be applied a frame
139
+ * later. `use` stays: it is how real icon sets reference their own `defs`,
140
+ * and where it points is handled by the URL rule below.
141
+ */
142
+ const REMOVED_ELEMENTS =
143
+ 'script, foreignObject, animate, animateMotion, animateTransform, set, mpath, discard';
144
+
145
+ const URL_ATTRIBUTES: ReadonlySet<string> = new Set(['href', 'xlink:href', 'src']);
146
+
147
+ /**
148
+ * Whether a URL attribute points inside this same document (`#gradient`).
149
+ *
150
+ * Only a fragment survives. A `javascript:` URL is the classic vector, but
151
+ * an ordinary remote URL is not safe either: on `<image href>` or `<use
152
+ * href>` it fetches on adoption, which is a request the consumer's page
153
+ * never asked to make, from markup the consumer did not write. A same
154
+ * document reference can do neither.
155
+ */
156
+ function isSameDocumentReference(value: string): boolean {
157
+ return value.trim().startsWith('#');
158
+ }
159
+
99
160
  /**
100
161
  * Strips executable content from a fetched SVG's descendants.
101
162
  *
@@ -110,11 +171,11 @@
110
171
  * legitimately carry the entire SVG geometry and paint vocabulary (`d`,
111
172
  * `transform`, `gradientUnits`, …), so enumerating what is permitted would
112
173
  * break real artwork. What is dangerous is narrow and well understood:
113
- * scripting elements, `on*` handlers, and URL attributes pointing at
114
- * `javascript:`.
174
+ * scripting elements, SMIL animation, `on*` handlers, and URL attributes
175
+ * that leave this document.
115
176
  */
116
177
  function sanitizeInlinedSubtree(root: SVGSVGElement): void {
117
- for (const element of Array.from(root.querySelectorAll('script, foreignObject'))) {
178
+ for (const element of Array.from(root.querySelectorAll(REMOVED_ELEMENTS))) {
118
179
  element.remove();
119
180
  }
120
181
  for (const element of Array.from(root.querySelectorAll('*'))) {
@@ -124,10 +185,7 @@
124
185
  element.removeAttribute(attribute.name);
125
186
  continue;
126
187
  }
127
- // `href`, `xlink:href` and `src` accept a javascript: URL, which runs
128
- // on activation of an <a> wrapper or on load of a nested resource.
129
- const isUrlAttribute = name === 'href' || name === 'xlink:href' || name === 'src';
130
- if (isUrlAttribute && /^\s*javascript:/i.test(attribute.value)) {
188
+ if (URL_ATTRIBUTES.has(name) && !isSameDocumentReference(attribute.value)) {
131
189
  element.removeAttribute(attribute.name);
132
190
  }
133
191
  }
@@ -150,17 +208,25 @@
150
208
  return new Set(Array.from(root.attributes, (attribute) => attribute.name.toLowerCase()));
151
209
  }
152
210
 
211
+ /**
212
+ * Resolves to the root attribute names this load copied onto the host, so
213
+ * the next load can remove them first. Without that, an attribute the
214
+ * previous file supplied (say `fill`) outlives a `src` change to a file that
215
+ * does not, and the two icons blend. Early exits hand back `previouslyCopied`
216
+ * untouched: nothing was painted, so nothing is owed.
217
+ */
153
218
  async function loadInlineSvg(
154
219
  host: SVGSVGElement,
155
220
  url: string,
156
221
  transform: ((svg: string) => string) | null,
157
- signal: AbortSignal
158
- ): Promise<void> {
222
+ signal: AbortSignal,
223
+ previouslyCopied: readonly string[]
224
+ ): Promise<readonly string[]> {
159
225
  try {
160
226
  const response = await fetch(url, { signal });
161
227
  if (!response.ok) {
162
228
  failedInlineSrc = url;
163
- return;
229
+ return previouslyCopied;
164
230
  }
165
231
  const rawSvg = await response.text();
166
232
  const hasTransform = typeof transform === 'function';
@@ -168,22 +234,27 @@
168
234
  const parsed = new DOMParser().parseFromString(markup, 'image/svg+xml');
169
235
  if (parsed.querySelector('parsererror') !== null) {
170
236
  failedInlineSrc = url;
171
- return;
237
+ return previouslyCopied;
172
238
  }
173
239
  const sourceSvg = parsed.querySelector('svg');
174
240
  if (sourceSvg === null) {
175
241
  failedInlineSrc = url;
176
- return;
242
+ return previouslyCopied;
177
243
  }
178
244
  // The action may have been torn down (or re-run) while awaiting the
179
245
  // body — bail before mutating so a stale fetch never paints over the
180
246
  // latest one.
181
247
  if (signal.aborted) {
182
- return;
248
+ return previouslyCopied;
183
249
  }
184
250
  while (host.firstChild !== null) {
185
251
  host.removeChild(host.firstChild);
186
252
  }
253
+ for (const name of previouslyCopied) {
254
+ if (!restoreHostOwnedAttribute(host, name)) {
255
+ host.removeAttribute(name);
256
+ }
257
+ }
187
258
  // With no transform the parsed root IS the fetched root, so every name
188
259
  // is network-supplied and only the allowlist applies. With a transform,
189
260
  // names absent from the raw payload were added by the caller's own hook
@@ -191,36 +262,45 @@
191
262
  // nothing can be attributed to the caller and the allowlist applies to
192
263
  // everything.
193
264
  const fetchedRootNames = hasTransform ? collectRootAttributeNames(rawSvg) : null;
194
- for (const attribute of Array.from(sourceSvg.attributes)) {
265
+ const accepted = Array.from(sourceSvg.attributes).filter((attribute) => {
195
266
  const name = attribute.name.toLowerCase();
196
- if (name === 'class') {
197
- continue;
198
- }
199
267
  const addedByTransform = fetchedRootNames !== null && !fetchedRootNames.has(name);
200
- if (isSafeInlineRootAttribute(name) || addedByTransform) {
201
- host.setAttribute(attribute.name, attribute.value);
202
- }
268
+ return name !== 'class' && (isSafeInlineRootAttribute(name) || addedByTransform);
269
+ });
270
+ for (const attribute of accepted) {
271
+ host.setAttribute(attribute.name, attribute.value);
203
272
  }
273
+ const copied = accepted.map((attribute) => attribute.name);
204
274
  // Before adoption, not after: an event-handler attribute becomes a live
205
275
  // handler as soon as its element enters the document.
206
276
  sanitizeInlinedSubtree(sourceSvg);
207
277
  while (sourceSvg.firstChild !== null) {
208
278
  host.appendChild(sourceSvg.firstChild);
209
279
  }
280
+ return copied;
210
281
  } catch {
211
282
  if (!signal.aborted) {
212
283
  failedInlineSrc = url;
213
284
  }
285
+ return previouslyCopied;
214
286
  }
215
287
  }
216
288
 
217
289
  function inlineSvgInto(host: SVGSVGElement, params: InlineParams) {
218
290
  let controller = new AbortController();
291
+ let copied: readonly string[] = [];
219
292
 
220
293
  function load(current: InlineParams): void {
221
294
  controller.abort();
222
295
  controller = new AbortController();
223
- void loadInlineSvg(host, current.url, current.transform, controller.signal);
296
+ const { signal } = controller;
297
+ void loadInlineSvg(host, current.url, current.transform, signal, copied).then((names) => {
298
+ // A superseded load resolves after the one that replaced it may
299
+ // already have recorded its own names; only the live load may write.
300
+ if (!signal.aborted) {
301
+ copied = names;
302
+ }
303
+ });
224
304
  }
225
305
 
226
306
  load(params);
@@ -240,9 +320,9 @@
240
320
  <svg
241
321
  use:inlineSvgInto={{ url: currentSrc, transform: transformSvg ?? null }}
242
322
  class={classes ?? ''}
243
- role={alt.length > 0 ? 'img' : null}
244
- aria-label={alt.length > 0 ? alt : null}
245
- aria-hidden={alt.length === 0 ? 'true' : null}
323
+ role={label.length > 0 ? 'img' : null}
324
+ aria-label={label.length > 0 ? label : null}
325
+ aria-hidden={label.length === 0 ? 'true' : null}
246
326
  data-pw={testId}
247
327
  testID={testId}
248
328
  ></svg>
@@ -250,7 +330,7 @@
250
330
  <img
251
331
  class={classes ?? ''}
252
332
  src={currentSrc}
253
- {alt}
333
+ alt={label}
254
334
  onerror={handleFallback}
255
335
  data-pw={testId}
256
336
  testID={testId}
@@ -26,5 +26,4 @@ export type OptionalImgProperties = {
26
26
  };
27
27
  export type ImgEventProperties = {
28
28
  onerror?: () => void;
29
- onError?: () => void;
30
29
  };
@@ -30,20 +30,14 @@
30
30
  testId = '',
31
31
  textTransformers = [],
32
32
  textViewPresentation = [],
33
- onFocus: onFocusLegacy = () => {},
34
33
  onfocus,
35
- onFocusout: onFocusoutLegacy = () => {},
36
34
  onfocusout,
37
- onBlur: onBlurLegacy = () => {},
38
35
  onblur,
39
- onInput: onInputLegacy = () => {},
40
36
  oninput,
41
- onPaste: onPasteLegacy = () => {},
42
37
  onpaste,
43
- onStateChange = () => {},
44
- onClick: onClickLegacy = () => {},
38
+ // Called unguarded below, so it keeps the no-op default the resolver gave it.
39
+ onstatechange = () => {},
45
40
  onclick,
46
- onKeyDown: onKeyDownLegacy = () => {},
47
41
  onkeydown,
48
42
  classes,
49
43
  role,
@@ -54,8 +48,8 @@
54
48
  ariaActivedescendant,
55
49
  leftIcon,
56
50
  rightIcon,
57
- onLeftIconClick,
58
- onRightIconClick,
51
+ onlefticonclick,
52
+ onrighticonclick,
59
53
  leftIconLabel = 'Leading action',
60
54
  rightIconLabel = 'Trailing action',
61
55
  mandatory = false,
@@ -68,15 +62,6 @@
68
62
  showCount = false
69
63
  }: InputProperties = $props();
70
64
 
71
- // Event-casing phase 1: both spellings accepted, the correct one wins.
72
- const onBlur = $derived(onblur ?? onBlurLegacy);
73
- const onClick = $derived(onclick ?? onClickLegacy);
74
- const onFocus = $derived(onfocus ?? onFocusLegacy);
75
- const onFocusout = $derived(onfocusout ?? onFocusoutLegacy);
76
- const onInput = $derived(oninput ?? onInputLegacy);
77
- const onKeyDown = $derived(onkeydown ?? onKeyDownLegacy);
78
- const onPaste = $derived(onpaste ?? onPasteLegacy);
79
-
80
65
  /* `for` on a <label> resolves against an element's id, never its name. The label
81
66
  was emitted with for={name} while the field itself carried only name={name},
82
67
  so the association never completed for any caller. Derive the id from name so
@@ -131,7 +116,7 @@
131
116
 
132
117
  // eslint-disable-next-line no-restricted-syntax
133
118
  $effect(() => {
134
- onStateChange(validationState);
119
+ onstatechange(validationState);
135
120
  });
136
121
 
137
122
  const showErrorMessage = $derived(validationState === 'Invalid');
@@ -236,7 +221,7 @@
236
221
  inputElement.value = currentValue;
237
222
  }
238
223
  value = inputElement.value;
239
- onInput(inputElement.value, event);
224
+ oninput?.(inputElement.value, event);
240
225
  }
241
226
 
242
227
  /**
@@ -250,11 +235,11 @@
250
235
  }
251
236
 
252
237
  // Everything below the tel branch is tel-specific digit normalisation, and
253
- // onPaste was only ever invoked from inside it — so a non-tel field (notably
238
+ // onpaste was only ever invoked from inside it — so a non-tel field (notably
254
239
  // useTextArea) had no way to observe a paste at all. Hand the event over
255
240
  // before that branch and return, leaving tel's behaviour byte-identical.
256
241
  if (dataType !== 'tel') {
257
- onPaste(event);
242
+ onpaste?.(event);
258
243
  return;
259
244
  }
260
245
 
@@ -288,11 +273,11 @@
288
273
  );
289
274
  // Adding reactivity
290
275
  value = finalValue;
291
- onPaste(event);
276
+ onpaste?.(event);
292
277
  event.preventDefault(); // prevent bubble and let finalValue be entered
293
278
  }
294
279
  /**
295
- * if numeric pasted text has length less than max length, bubble to onInput.
280
+ * if numeric pasted text has length less than max length, bubble to oninput.
296
281
  */
297
282
  }
298
283
  }
@@ -309,8 +294,8 @@
309
294
  if (validationState === 'InProgress' && value.length > 0) {
310
295
  validationState = 'Invalid';
311
296
  }
312
- onFocusout(event);
313
- onBlur(event);
297
+ onfocusout?.(event);
298
+ onblur?.(event);
314
299
  }
315
300
  </script>
316
301
 
@@ -340,12 +325,12 @@
340
325
  aria-invalid={showError && !actionInput ? 'true' : null}
341
326
  aria-describedby={describedBy || null}
342
327
  required={mandatory || null}
343
- onfocus={onFocus}
328
+ {onfocus}
344
329
  onfocusout={_onFocusOut}
345
330
  oninput={handleOnInput}
346
331
  onpaste={handleOnPaste}
347
- onclick={onClick}
348
- onkeydown={onKeyDown}
332
+ {onclick}
333
+ {onkeydown}
349
334
  data-pw={testId}
350
335
  testID={testId}
351
336
  class:action-input={actionInput}
@@ -378,12 +363,12 @@
378
363
  aria-invalid={showError && !actionInput ? 'true' : null}
379
364
  aria-describedby={describedBy || null}
380
365
  required={mandatory || null}
381
- onfocus={onFocus}
366
+ {onfocus}
382
367
  onfocusout={_onFocusOut}
383
368
  oninput={handleOnInput}
384
369
  onpaste={handleOnPaste}
385
- onclick={onClick}
386
- onkeydown={onKeyDown}
370
+ {onclick}
371
+ {onkeydown}
387
372
  data-pw={testId}
388
373
  testID={testId}
389
374
  class:action-input={actionInput}
@@ -406,12 +391,12 @@
406
391
  class:has-right-icon={hasRightIcon}
407
392
  >
408
393
  {#if hasLeftIcon}
409
- {#if onLeftIconClick}
394
+ {#if onlefticonclick}
410
395
  <button
411
396
  type="button"
412
397
  class="input-icon input-icon-left input-icon-button"
413
398
  aria-label={leftIconLabel}
414
- onclick={onLeftIconClick}
399
+ onclick={onlefticonclick}
415
400
  >
416
401
  {@render leftIcon?.()}
417
402
  </button>
@@ -421,12 +406,12 @@
421
406
  {/if}
422
407
  {@render fieldElement()}
423
408
  {#if hasRightIcon}
424
- {#if onRightIconClick}
409
+ {#if onrighticonclick}
425
410
  <button
426
411
  type="button"
427
412
  class="input-icon input-icon-right input-icon-button"
428
413
  aria-label={rightIconLabel}
429
- onclick={onRightIconClick}
414
+ onclick={onrighticonclick}
430
415
  >
431
416
  {@render rightIcon?.()}
432
417
  </button>
@@ -87,9 +87,9 @@ export type OptionalInputProperties = {
87
87
  /** Passive/clickable icon rendered inside the field on the trailing edge (e.g. a clear button). */
88
88
  rightIcon?: Snippet;
89
89
  /** When set, the leftIcon becomes a focusable button invoking this handler. */
90
- onLeftIconClick?: () => void;
90
+ onlefticonclick?: () => void;
91
91
  /** When set, the rightIcon becomes a focusable button invoking this handler. */
92
- onRightIconClick?: () => void;
92
+ onrighticonclick?: () => void;
93
93
  /** Accessible label for the clickable leftIcon button (defaults to a generic label). */
94
94
  leftIconLabel?: string;
95
95
  /** Accessible label for the clickable rightIcon button (defaults to a generic label). */
@@ -100,19 +100,12 @@ export type OptionalInputProperties = {
100
100
  forceError?: boolean;
101
101
  };
102
102
  export type InputEventProperties = {
103
- onInput?: (value: string, event: Event) => void;
104
103
  oninput?: (value: string, event: Event) => void;
105
- onFocus?: (event: FocusEvent) => void;
106
104
  onfocus?: (event: FocusEvent) => void;
107
- onFocusout?: (event: FocusEvent) => void;
108
105
  onfocusout?: (event: FocusEvent) => void;
109
- onBlur?: (event: FocusEvent) => void;
110
106
  onblur?: (event: FocusEvent) => void;
111
- onPaste?: (event: ClipboardEvent) => void;
112
107
  onpaste?: (event: ClipboardEvent) => void;
113
- onClick?: (event: MouseEvent) => void;
114
108
  onclick?: (event: MouseEvent) => void;
115
- onStateChange?: (state: ValidationState) => void;
116
- onKeyDown?: (event: KeyboardEvent) => void;
109
+ onstatechange?: (state: ValidationState) => void;
117
110
  onkeydown?: (event: KeyboardEvent) => void;
118
111
  };
@@ -50,7 +50,7 @@
50
50
 
51
51
  function handleStateChange(state: ValidationState): void {
52
52
  validationState = state;
53
- inputEventProperties?.onStateChange?.(state);
53
+ inputEventProperties?.onstatechange?.(state);
54
54
  }
55
55
 
56
56
  export function focus() {
@@ -89,7 +89,7 @@
89
89
  {...inputEventProperties}
90
90
  bind:value
91
91
  bind:this={inputRef}
92
- onStateChange={handleStateChange}
92
+ onstatechange={handleStateChange}
93
93
  actionInput={true}
94
94
  />
95
95
  </div>
@@ -59,19 +59,13 @@
59
59
  hideLegendBelow = 360,
60
60
  tooltipPortal = false,
61
61
  highlightedIndex = null,
62
- onChartReady,
63
- onpointclick: onpointclickLegacy,
64
- onPointClick,
65
- onpointhover: onpointhoverLegacy,
66
- onPointHover,
62
+ onchartready,
63
+ onpointclick,
64
+ onpointhover,
67
65
  testId,
68
66
  classes
69
67
  }: LineChartProperties = $props();
70
68
 
71
- // Event-casing phase 1: both spellings accepted, the correct one wins.
72
- const onpointclick = $derived(onPointClick ?? onpointclickLegacy);
73
- const onpointhover = $derived(onPointHover ?? onpointhoverLegacy);
74
-
75
69
  // ── State ──────────────────────────────────────────────────────
76
70
 
77
71
  let containerEl: HTMLDivElement | null = $state(null);
@@ -127,7 +121,7 @@
127
121
  }
128
122
  };
129
123
 
130
- onChartReady?.(api);
124
+ onchartready?.(api);
131
125
  });
132
126
 
133
127
  // ── Layout ─────────────────────────────────────────────────────
@@ -142,25 +142,15 @@ export type LineChartEventProperties = {
142
142
  pointIndex: number;
143
143
  point: LineChartDataPoint;
144
144
  }) => void;
145
- onPointClick?: (event: {
146
- seriesIndex: number;
147
- pointIndex: number;
148
- point: LineChartDataPoint;
149
- }) => void;
150
145
  onpointhover?: (event: {
151
146
  seriesIndex: number;
152
147
  pointIndex: number;
153
148
  point: LineChartDataPoint;
154
149
  } | null) => void;
155
- onPointHover?: (event: {
156
- seriesIndex: number;
157
- pointIndex: number;
158
- point: LineChartDataPoint;
159
- } | null) => void;
160
150
  /**
161
151
  * Called once after the chart mounts, handing back a `ChartHighlightAPI`
162
152
  * so an external orchestrator (e.g. voice narration sync) can drive point
163
153
  * highlighting without knowledge of the chart's internal state.
164
154
  */
165
- onChartReady?: (api: ChartHighlightAPI) => void;
155
+ onchartready?: (api: ChartHighlightAPI) => void;
166
156
  };
@@ -25,16 +25,11 @@
25
25
  centerContent,
26
26
  rightContent,
27
27
  bottomContent,
28
- onleftImageClick: onleftImageClickLegacy,
29
- onLeftImageClick,
30
- onrightImageClick: onrightImageClickLegacy,
31
- onRightImageClick,
32
- oncenterTextClick: oncenterTextClickLegacy,
33
- onCenterTextClick,
34
- onitemClick: onitemClickLegacy,
35
- onItemClick,
36
- ontopSectionClick: ontopSectionClickLegacy,
37
- onTopSectionClick,
28
+ onleftimageclick,
29
+ onrightimageclick,
30
+ oncentertextclick,
31
+ onitemclick,
32
+ ontopsectionclick,
38
33
  onkeydown,
39
34
  classes,
40
35
  transformSvg,
@@ -43,31 +38,24 @@
43
38
  id
44
39
  }: ListItemProperties = $props();
45
40
 
46
- // Event-casing phase 1: both spellings accepted, the correct one wins.
47
- const oncenterTextClick = $derived(onCenterTextClick ?? oncenterTextClickLegacy);
48
- const onitemClick = $derived(onItemClick ?? onitemClickLegacy);
49
- const onleftImageClick = $derived(onLeftImageClick ?? onleftImageClickLegacy);
50
- const onrightImageClick = $derived(onRightImageClick ?? onrightImageClickLegacy);
51
- const ontopSectionClick = $derived(onTopSectionClick ?? ontopSectionClickLegacy);
52
-
53
41
  function handleLeftImageClick(event: MouseEvent): void {
54
- onleftImageClick?.(event);
42
+ onleftimageclick?.(event);
55
43
  }
56
44
 
57
45
  function handleRightImageClick(event: MouseEvent): void {
58
- onrightImageClick?.(event);
46
+ onrightimageclick?.(event);
59
47
  }
60
48
 
61
49
  function handleCenterTextClick(event: MouseEvent): void {
62
- oncenterTextClick?.(event);
50
+ oncentertextclick?.(event);
63
51
  }
64
52
 
65
53
  function handleItemClick(event: MouseEvent): void {
66
- onitemClick?.(event);
54
+ onitemclick?.(event);
67
55
  }
68
56
 
69
57
  function handleTopSectionClick(event: MouseEvent): void {
70
- ontopSectionClick?.(event);
58
+ ontopsectionclick?.(event);
71
59
  }
72
60
  </script>
73
61
 
@@ -32,15 +32,10 @@ export type ListItemProperties = ListItemEventProperties & {
32
32
  id?: string;
33
33
  };
34
34
  export type ListItemEventProperties = {
35
- onleftImageClick?: (event: MouseEvent) => void;
36
- onLeftImageClick?: (event: MouseEvent) => void;
37
- onrightImageClick?: (event: MouseEvent) => void;
38
- onRightImageClick?: (event: MouseEvent) => void;
39
- oncenterTextClick?: (event: MouseEvent) => void;
40
- onCenterTextClick?: (event: MouseEvent) => void;
41
- onitemClick?: (event: MouseEvent) => void;
42
- onItemClick?: (event: MouseEvent) => void;
43
- ontopSectionClick?: (event: MouseEvent) => void;
44
- onTopSectionClick?: (event: MouseEvent) => void;
35
+ onleftimageclick?: (event: MouseEvent) => void;
36
+ onrightimageclick?: (event: MouseEvent) => void;
37
+ oncentertextclick?: (event: MouseEvent) => void;
38
+ onitemclick?: (event: MouseEvent) => void;
39
+ ontopsectionclick?: (event: MouseEvent) => void;
45
40
  onkeydown?: (event: KeyboardEvent) => void;
46
41
  };
@@ -18,16 +18,10 @@
18
18
  ariaHidden = true,
19
19
  testId,
20
20
  classes,
21
- oncomplete: oncompleteLegacy,
22
- onComplete,
23
- onerror: onerrorLegacy,
24
- onError
21
+ oncomplete,
22
+ onerror
25
23
  }: LottiePlayerProperties = $props();
26
24
 
27
- // Event-casing phase 1: both spellings accepted, the correct one wins.
28
- const oncomplete = $derived(onComplete ?? oncompleteLegacy);
29
- const onerror = $derived(onError ?? onerrorLegacy);
30
-
31
25
  let containerEl: HTMLDivElement | null = $state(null);
32
26
  let animationItem: LocalAnimationItem | null = $state(null);
33
27
 
@@ -31,8 +31,6 @@ export type OptionalLottiePlayerProperties = {
31
31
  export type LottiePlayerEventProperties = {
32
32
  /** Fired when the animation completes (non-looping). */
33
33
  oncomplete?: () => void;
34
- onComplete?: () => void;
35
34
  /** Fired when the animation fails to load. */
36
35
  onerror?: () => void;
37
- onError?: () => void;
38
36
  };
@@ -26,15 +26,11 @@
26
26
  captionsSrcLang,
27
27
  onplay,
28
28
  onpause,
29
- onvolumechange: onvolumechangeLegacy,
30
- onVolumeChange,
29
+ onvolumechange,
31
30
  testId,
32
31
  classes
33
32
  }: MediaPlayerProperties = $props();
34
33
 
35
- // Event-casing phase 1: both spellings accepted, the correct one wins.
36
- const onvolumechange = $derived(onVolumeChange ?? onvolumechangeLegacy);
37
-
38
34
  let videoPlayer: HTMLVideoElement | null = $state(null);
39
35
 
40
36
  function togglePlayback(): void {