@juspay/svelte-ui-components 2.111.0 → 2.111.2

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 (83) hide show
  1. package/dist/Accordion/Accordion.svelte +1 -0
  2. package/dist/Animations/ModalAnimation.svelte +4 -0
  3. package/dist/Animations/OverlayAnimation.svelte +5 -1
  4. package/dist/AreaChart/AreaChart.svelte +1 -0
  5. package/dist/Avatar/Avatar.svelte +8 -1
  6. package/dist/Badge/Badge.svelte +6 -1
  7. package/dist/Banner/Banner.svelte +1 -0
  8. package/dist/BarChart/BarChart.svelte +4 -0
  9. package/dist/Book/Book.svelte +1 -0
  10. package/dist/BrandLoader/BrandLoader.svelte +5 -1
  11. package/dist/Breadcrumb/Breadcrumb.svelte +1 -0
  12. package/dist/Browser/Browser.svelte +7 -1
  13. package/dist/Button/Button.svelte +1 -0
  14. package/dist/Calendar/Calendar.svelte +7 -1
  15. package/dist/Card/Card.svelte +1 -0
  16. package/dist/Carousel/Carousel.svelte +3 -0
  17. package/dist/CheckListItem/CheckListItem.svelte +1 -1
  18. package/dist/Checkbox/Checkbox.svelte +3 -0
  19. package/dist/Choicebox/Choicebox.svelte +1 -0
  20. package/dist/ColorPicker/ColorPicker.svelte +1 -0
  21. package/dist/Combobox/Combobox.svelte +10 -1
  22. package/dist/CommandMenu/CommandMenu.svelte +3 -0
  23. package/dist/ContextMenu/ContextMenu.svelte +2 -0
  24. package/dist/DateRangePicker/DateRangePicker.svelte +299 -17
  25. package/dist/DateRangePicker/properties.d.ts +7 -2
  26. package/dist/DateRangePicker/timeUtils.d.ts +6 -0
  27. package/dist/DateRangePicker/timeUtils.js +71 -0
  28. package/dist/DeltaIndicator/DeltaIndicator.svelte +1 -0
  29. package/dist/DualAxisBarChart/DualAxisBarChart.svelte +2 -0
  30. package/dist/EmptyState/EmptyState.svelte +5 -1
  31. package/dist/FileInput/FileInput.svelte +2 -0
  32. package/dist/FunnelChart/FunnelChart.svelte +2 -0
  33. package/dist/Gauge/Gauge.svelte +1 -0
  34. package/dist/GridItem/GridItem.svelte +1 -0
  35. package/dist/Icon/Icon.svelte +1 -0
  36. package/dist/IconStack/IconStack.svelte +5 -1
  37. package/dist/IframeViewer/IframeViewer.svelte +1 -1
  38. package/dist/Img/Img.svelte +9 -1
  39. package/dist/Input/Input.svelte +3 -0
  40. package/dist/InputButton/InputButton.svelte +5 -1
  41. package/dist/KeyValue/KeyValue.svelte +2 -1
  42. package/dist/KeyboardInput/KeyboardInput.svelte +1 -0
  43. package/dist/LineChart/LineChart.svelte +3 -0
  44. package/dist/ListItem/ListItem.svelte +5 -0
  45. package/dist/Loader/Loader.svelte +5 -1
  46. package/dist/LoadingDots/LoadingDots.svelte +2 -0
  47. package/dist/LottiePlayer/LottiePlayer.svelte +1 -0
  48. package/dist/Menu/Menu.svelte +2 -0
  49. package/dist/Modal/Modal.svelte +4 -1
  50. package/dist/Pagination/Pagination.svelte +4 -0
  51. package/dist/Phone/Phone.svelte +5 -1
  52. package/dist/PieChart/PieChart.svelte +1 -0
  53. package/dist/Pill/Pill.svelte +1 -0
  54. package/dist/Progress/Progress.svelte +5 -1
  55. package/dist/ProportionBar/ProportionBar.svelte +4 -0
  56. package/dist/Radio/Radio.svelte +1 -0
  57. package/dist/RelativeTime/RelativeTime.svelte +2 -0
  58. package/dist/SankeyChart/SankeyChart.svelte +1 -0
  59. package/dist/Scroller/Scroller.svelte +1 -0
  60. package/dist/Select/Select.svelte +18 -5
  61. package/dist/Sheet/Sheet.svelte +2 -0
  62. package/dist/Shimmer/Shimmer.svelte +5 -1
  63. package/dist/Slider/Slider.svelte +1 -0
  64. package/dist/Snippet/Snippet.svelte +5 -1
  65. package/dist/SplitButton/SplitButton.svelte +1 -0
  66. package/dist/SplitInput/SplitInput.svelte +1 -1
  67. package/dist/StatCard/StatCard.svelte +31 -4
  68. package/dist/Status/Status.svelte +5 -1
  69. package/dist/Stepper/Stepper.svelte +6 -1
  70. package/dist/Table/BuiltinCell.svelte +13 -2
  71. package/dist/Table/Table.svelte +24 -1
  72. package/dist/Tabs/Tabs.svelte +2 -1
  73. package/dist/ThemeSwitcher/ThemeSwitcher.svelte +6 -1
  74. package/dist/Toast/Toast.svelte +4 -2
  75. package/dist/Toggle/Toggle.svelte +7 -1
  76. package/dist/Toolbar/Toolbar.svelte +7 -3
  77. package/dist/Tooltip/Tooltip.svelte +5 -4
  78. package/dist/_chart/Axis.svelte +8 -1
  79. package/dist/_chart/ChartContainer.svelte +1 -0
  80. package/dist/_chart/ChartTooltip.svelte +3 -1
  81. package/dist/_chart/Legend.svelte +1 -0
  82. package/dist/testing-attributes.d.ts +36 -0
  83. package/package.json +1 -1
@@ -85,13 +85,18 @@
85
85
  class="statcard {classes ?? ''}"
86
86
  class:statcard-interactive={isInteractive}
87
87
  data-pw={typeof testId === 'string' ? testId : null}
88
+ testID={typeof testId === 'string' ? testId : null}
88
89
  role={isInteractive ? 'button' : null}
89
90
  tabindex={isInteractive ? 0 : null}
90
91
  onclick={isInteractive ? onclick : null}
91
92
  onkeydown={isInteractive ? handleKeydown : null}
92
93
  >
93
94
  {#if hasHeaderContent}
94
- <div class="statcard-header" data-pw={typeof testId === 'string' ? `${testId}-header` : null}>
95
+ <div
96
+ class="statcard-header"
97
+ data-pw={typeof testId === 'string' ? `${testId}-header` : null}
98
+ testID={typeof testId === 'string' ? `${testId}-header` : null}
99
+ >
95
100
  <div class="statcard-header-left">
96
101
  {#if hasTitle}
97
102
  {#if tooltip}
@@ -115,6 +120,7 @@
115
120
  <div
116
121
  class="statcard-title"
117
122
  data-pw={typeof testId === 'string' ? `${testId}-title` : null}
123
+ testID={typeof testId === 'string' ? `${testId}-title` : null}
118
124
  >
119
125
  {title}
120
126
  </div>
@@ -146,15 +152,21 @@
146
152
  class="statcard-rows"
147
153
  class:statcard-rows-horizontal={rowsDirection === 'row'}
148
154
  data-pw={typeof testId === 'string' ? `${testId}-rows` : null}
155
+ testID={typeof testId === 'string' ? `${testId}-rows` : null}
149
156
  >
150
157
  {#each rows as row, rowIndex (rowIndex)}
151
158
  {#if rowIndex > 0}
152
159
  <div
153
160
  class="statcard-row-divider"
154
161
  data-pw={typeof testId === 'string' ? `${testId}-row-divider-${rowIndex}` : null}
162
+ testID={typeof testId === 'string' ? `${testId}-row-divider-${rowIndex}` : null}
155
163
  ></div>
156
164
  {/if}
157
- <div class="statcard-row" data-pw={typeof row.testId === 'string' ? row.testId : null}>
165
+ <div
166
+ class="statcard-row"
167
+ data-pw={typeof row.testId === 'string' ? row.testId : null}
168
+ testID={typeof row.testId === 'string' ? row.testId : null}
169
+ >
158
170
  {#if typeof row.heading === 'string' && row.heading.length > 0}
159
171
  <div class="statcard-row-heading-wrap">
160
172
  {#if row.tooltip}
@@ -174,6 +186,7 @@
174
186
  <div
175
187
  class="statcard-value"
176
188
  data-pw={typeof testId === 'string' ? `${testId}-value-${rowIndex}` : null}
189
+ testID={typeof testId === 'string' ? `${testId}-value-${rowIndex}` : null}
177
190
  >
178
191
  {row.value}
179
192
  </div>
@@ -181,6 +194,7 @@
181
194
  <div
182
195
  class="statcard-comparison-value"
183
196
  data-pw={typeof testId === 'string' ? `${testId}-comparison-${rowIndex}` : null}
197
+ testID={typeof testId === 'string' ? `${testId}-comparison-${rowIndex}` : null}
184
198
  >
185
199
  / {row.comparisonValue}
186
200
  </div>
@@ -197,6 +211,7 @@
197
211
  <div
198
212
  class="statcard-delta statcard-delta-na"
199
213
  data-pw={typeof testId === 'string' ? `${testId}-delta-na-${rowIndex}` : null}
214
+ testID={typeof testId === 'string' ? `${testId}-delta-na-${rowIndex}` : null}
200
215
  >
201
216
  N/A
202
217
  </div>
@@ -216,6 +231,9 @@
216
231
  data-pw={typeof testId === 'string'
217
232
  ? `${testId}-breakdown-item-${rowIndex}-${breakdownIndex}`
218
233
  : null}
234
+ testID={typeof testId === 'string'
235
+ ? `${testId}-breakdown-item-${rowIndex}-${breakdownIndex}`
236
+ : null}
219
237
  >
220
238
  <div class="statcard-breakdown-label">{breakdownItem.label}</div>
221
239
  <div class="statcard-breakdown-value-line">
@@ -237,11 +255,19 @@
237
255
  {:else}
238
256
  <div class="statcard-value-row">
239
257
  {#if typeof valueSnippet === 'function'}
240
- <div class="statcard-value" data-pw={typeof testId === 'string' ? `${testId}-value` : null}>
258
+ <div
259
+ class="statcard-value"
260
+ data-pw={typeof testId === 'string' ? `${testId}-value` : null}
261
+ testID={typeof testId === 'string' ? `${testId}-value` : null}
262
+ >
241
263
  {@render valueSnippet()}
242
264
  </div>
243
265
  {:else if typeof value === 'string' && value.length > 0}
244
- <div class="statcard-value" data-pw={typeof testId === 'string' ? `${testId}-value` : null}>
266
+ <div
267
+ class="statcard-value"
268
+ data-pw={typeof testId === 'string' ? `${testId}-value` : null}
269
+ testID={typeof testId === 'string' ? `${testId}-value` : null}
270
+ >
245
271
  {value}
246
272
  </div>
247
273
  {/if}
@@ -262,6 +288,7 @@
262
288
  <div
263
289
  class="statcard-subtitle"
264
290
  data-pw={typeof testId === 'string' ? `${testId}-subtitle` : null}
291
+ testID={typeof testId === 'string' ? `${testId}-subtitle` : null}
265
292
  >
266
293
  {subtitle}
267
294
  </div>
@@ -15,7 +15,11 @@
15
15
  }: StatusProperties = $props();
16
16
  </script>
17
17
 
18
- <div class="background {classes ?? ''}" data-pw={typeof testId === 'string' ? testId : null}>
18
+ <div
19
+ class="background {classes ?? ''}"
20
+ data-pw={typeof testId === 'string' ? testId : null}
21
+ testID={typeof testId === 'string' ? testId : null}
22
+ >
19
23
  <div class="order-status">
20
24
  <div class="status-image">
21
25
  {#if icon}
@@ -35,7 +35,12 @@
35
35
  );
36
36
  </script>
37
37
 
38
- <div class={containerClass} data-pw={typeof testId === 'string' ? testId : null} role="list">
38
+ <div
39
+ class={containerClass}
40
+ data-pw={typeof testId === 'string' ? testId : null}
41
+ testID={typeof testId === 'string' ? testId : null}
42
+ role="list"
43
+ >
39
44
  {#each steps as currentStep, stepIndex (stepIndex)}
40
45
  {@const effectiveStatus = resolveStatus(stepIndex, currentStep.status ?? null)}
41
46
  <div
@@ -144,6 +144,7 @@
144
144
  <span
145
145
  class="builtin-icon-label-icon"
146
146
  data-pw={column.testId ? `${column.testId}-icon-${iconIndex}` : null}
147
+ testID={column.testId ? `${column.testId}-icon-${iconIndex}` : null}
147
148
  >
148
149
  <Img src={String(iconSrc)} alt="" fallback="" />
149
150
  </span>
@@ -154,7 +155,11 @@
154
155
  {@const data = asJsonObject(value) ?? {}}
155
156
  <div class="builtin-image-two-line {alignmentClass}">
156
157
  {#if typeof data.imageUrl === 'string' && data.imageUrl}
157
- <span class="builtin-thumb" data-pw={column.testId ? `${column.testId}-thumb` : null}>
158
+ <span
159
+ class="builtin-thumb"
160
+ data-pw={column.testId ? `${column.testId}-thumb` : null}
161
+ testID={column.testId ? `${column.testId}-thumb` : null}
162
+ >
158
163
  <Img
159
164
  src={data.imageUrl}
160
165
  alt={typeof data.text1 === 'string' ? data.text1 : ''}
@@ -165,6 +170,7 @@
165
170
  <span
166
171
  class="builtin-thumb builtin-thumb-placeholder"
167
172
  data-pw={column.testId ? `${column.testId}-thumb-placeholder` : null}
173
+ testID={column.testId ? `${column.testId}-thumb-placeholder` : null}
168
174
  >{typeof data.text1 === 'string' && data.text1
169
175
  ? data.text1.charAt(0).toUpperCase()
170
176
  : ''}</span
@@ -222,6 +228,7 @@
222
228
  <span
223
229
  class="builtin-trend builtin-trend-up"
224
230
  data-pw={column.testId ? `${column.testId}-trend-up` : null}
231
+ testID={column.testId ? `${column.testId}-trend-up` : null}
225
232
  >
226
233
  <!-- eslint-disable svelte/no-at-html-tags -->
227
234
  <span class="builtin-trend-icon">{@html trendUpSvg}</span>
@@ -231,6 +238,7 @@
231
238
  <span
232
239
  class="builtin-trend builtin-trend-down"
233
240
  data-pw={column.testId ? `${column.testId}-trend-down` : null}
241
+ testID={column.testId ? `${column.testId}-trend-down` : null}
234
242
  >
235
243
  <!-- eslint-disable svelte/no-at-html-tags -->
236
244
  <span class="builtin-trend-icon">{@html trendDownSvg}</span>
@@ -256,6 +264,7 @@
256
264
  aria-checked={isChecked ? 'true' : 'false'}
257
265
  aria-label={typeof data.ariaLabel === 'string' ? data.ariaLabel : null}
258
266
  data-pw={typeof data.testId === 'string' ? data.testId : null}
267
+ testID={typeof data.testId === 'string' ? data.testId : null}
259
268
  onclick={stopClickPropagation}
260
269
  onkeydown={stopKeydownPropagation}
261
270
  tabindex={-1}
@@ -482,6 +491,7 @@
482
491
  rel="noopener noreferrer"
483
492
  class="builtin-link-anchor"
484
493
  data-pw={column.testId ? `${column.testId}-link-${rowIndex}` : null}
494
+ testID={column.testId ? `${column.testId}-link-${rowIndex}` : null}
485
495
  >
486
496
  {link.label ?? link.url}
487
497
  </a>
@@ -501,7 +511,8 @@
501
511
  {#if copied}
502
512
  <span
503
513
  class="builtin-link-copied"
504
- data-pw={column.testId ? `${column.testId}-link-copied` : null}>Copied</span
514
+ data-pw={column.testId ? `${column.testId}-link-copied` : null}
515
+ testID={column.testId ? `${column.testId}-link-copied` : null}>Copied</span
505
516
  >
506
517
  {/if}
507
518
  {/if}
@@ -575,6 +575,7 @@
575
575
  value={searchTerm}
576
576
  oninput={handleSearchInput}
577
577
  data-pw={searchConfig?.testId ?? null}
578
+ testID={searchConfig?.testId ?? null}
578
579
  aria-label={searchConfig?.placeholder ?? 'Search'}
579
580
  autocomplete="off"
580
581
  />
@@ -602,6 +603,7 @@
602
603
  <div
603
604
  class="table-container {isTableScrollable ? 'scrollable-table' : ''} {classes ?? ''}"
604
605
  data-pw={testId}
606
+ testID={testId}
605
607
  >
606
608
  <div
607
609
  class="table-scroll-shell"
@@ -632,6 +634,7 @@
632
634
  : headerCheckboxState === 'all'}
633
635
  aria-label="Select all rows"
634
636
  data-pw={typeof testId === 'string' ? `${testId}-select-all` : null}
637
+ testID={typeof testId === 'string' ? `${testId}-select-all` : null}
635
638
  {...checkboxSelection?.getRowAttributes
636
639
  ? checkboxSelection.getRowAttributes('__header__', -1)
637
640
  : {}}
@@ -672,6 +675,7 @@
672
675
  class:table-header-sticky={isStickyHeader}
673
676
  class:table-col-highlighted={headerColumn?.highlighted === true}
674
677
  data-pw={headerColumn?.testId ?? null}
678
+ testID={headerColumn?.testId ?? null}
675
679
  style:text-align={headerColumn?.align ?? null}
676
680
  style:max-width={headerColumn?.maxWidth ?? null}
677
681
  >
@@ -800,6 +804,7 @@
800
804
  class:table-summary-row={summaryRowIndex !== null &&
801
805
  originalIndex === summaryRowIndex}
802
806
  data-pw={typeof getRowTestId === 'function' ? getRowTestId(row, rowIndex) : null}
807
+ testID={typeof getRowTestId === 'function' ? getRowTestId(row, rowIndex) : null}
803
808
  onclick={isRowClickable
804
809
  ? () => handleRowClick(rowIndex, row, originalIndex)
805
810
  : null}
@@ -824,6 +829,9 @@
824
829
  data-pw={typeof testId === 'string'
825
830
  ? `${testId}-row-checkbox-${rowId}`
826
831
  : null}
832
+ testID={typeof testId === 'string'
833
+ ? `${testId}-row-checkbox-${rowId}`
834
+ : null}
827
835
  {...checkboxSelection?.getRowAttributes
828
836
  ? checkboxSelection.getRowAttributes(rowId, rowIndex)
829
837
  : {}}
@@ -859,6 +867,9 @@
859
867
  data-pw={typeof getCellTestId === 'function'
860
868
  ? getCellTestId(row, cellValue, rowIndex)
861
869
  : null}
870
+ testID={typeof getCellTestId === 'function'
871
+ ? getCellTestId(row, cellValue, rowIndex)
872
+ : null}
862
873
  style:text-align={keyedColumn?.align ?? null}
863
874
  style:max-width={keyedColumn?.maxWidth ?? null}
864
875
  title={keyedColumn?.maxWidth && isScalarCell ? String(cellValue) : null}
@@ -869,6 +880,9 @@
869
880
  data-pw={keyedColumn?.testId
870
881
  ? `${keyedColumn.testId}-cell-${rowIndex}`
871
882
  : null}
883
+ testID={keyedColumn?.testId
884
+ ? `${keyedColumn.testId}-cell-${rowIndex}`
885
+ : null}
872
886
  >
873
887
  {#if keyedColumn && typeof keyedColumn.cell === 'function' && keyedRow}
874
888
  {@render keyedColumn.cell(keyedRow, rowIndex, originalIndex)}
@@ -903,10 +917,19 @@
903
917
  <!-- DataGrid parity: pagination chrome only renders when the data spans
904
918
  more than one page (or the server reports more chunks); a
905
919
  single-page table shows no footer. -->
906
- <div class="table-footer table-paginator" data-pw={pagination.testId ?? null}>
920
+ <div
921
+ class="table-footer table-paginator"
922
+ data-pw={pagination.testId ?? null}
923
+ testID={pagination.testId ?? null}
924
+ >
907
925
  <span
908
926
  class="table-paginator-range"
909
927
  data-pw={typeof testId === 'string'
928
+ ? `${testId}-paginator-range`
929
+ : pagination?.testId
930
+ ? `${pagination.testId}-range`
931
+ : null}
932
+ testID={typeof testId === 'string'
910
933
  ? `${testId}-paginator-range`
911
934
  : pagination?.testId
912
935
  ? `${pagination.testId}-range`
@@ -187,7 +187,7 @@
187
187
  );
188
188
  </script>
189
189
 
190
- <div class={rootClass} class:disabled class:vertical={isVertical} data-pw={testId}>
190
+ <div class={rootClass} class:disabled class:vertical={isVertical} data-pw={testId} testID={testId}>
191
191
  {#if showStartArrow}
192
192
  <button
193
193
  class="tabs-arrow tabs-arrow-start"
@@ -226,6 +226,7 @@
226
226
  aria-disabled={disabled ? true : null}
227
227
  tabindex={isActiveItem(index) ? 0 : -1}
228
228
  data-pw={tabItem?.testId}
229
+ testID={tabItem?.testId}
229
230
  onclick={() => handleTabClick(index)}
230
231
  onkeydown={(event) => handleKeydown(event, index)}
231
232
  >
@@ -113,6 +113,7 @@
113
113
  onclick={handleToggle}
114
114
  aria-label="Switch theme"
115
115
  data-pw={typeof testId === 'string' ? testId : null}
116
+ testID={typeof testId === 'string' ? testId : null}
116
117
  >
117
118
  {#each options as option, i (option.value)}
118
119
  <span class="icon" class:active={i === currentIndex}>
@@ -126,7 +127,11 @@
126
127
  {/each}
127
128
  </button>
128
129
  {:else}
129
- <div class="segment-control {classes ?? ''}" data-pw={typeof testId === 'string' ? testId : null}>
130
+ <div
131
+ class="segment-control {classes ?? ''}"
132
+ data-pw={typeof testId === 'string' ? testId : null}
133
+ testID={typeof testId === 'string' ? testId : null}
134
+ >
130
135
  <div
131
136
  class="segment-indicator"
132
137
  style="left: {indicatorLeft}px; width: {indicatorWidth}px;"
@@ -117,6 +117,7 @@
117
117
  out:fly={animationConfig.out}
118
118
  onoutroend={handleAnimationEnd}
119
119
  data-pw={testId}
120
+ testID={testId}
120
121
  >
121
122
  {#if typeof leftIcon === 'string' && leftIcon.length > 0}
122
123
  <div class="toast-icon-wrapper">
@@ -124,10 +125,10 @@
124
125
  </div>
125
126
  {/if}
126
127
 
127
- <div class="toast-message" data-pw={messageTestId}>
128
+ <div class="toast-message" data-pw={messageTestId} testID={messageTestId}>
128
129
  {message}
129
130
  {#if typeof subtext === 'string' && subtext.length > 0}
130
- <div class="toast-subtext" data-pw={subTextTestId}>{subtext}</div>
131
+ <div class="toast-subtext" data-pw={subTextTestId} testID={subTextTestId}>{subtext}</div>
131
132
  {/if}
132
133
 
133
134
  {#if typeof bottomContent === 'function'}
@@ -148,6 +149,7 @@
148
149
  }
149
150
  }}
150
151
  data-pw={closeIconTestId}
152
+ testID={closeIconTestId}
151
153
  >
152
154
  <Img inlineSvg src={rightIcon} alt="Close" fallback="" />
153
155
  </div>
@@ -18,7 +18,13 @@
18
18
  };
19
19
  </script>
20
20
 
21
- <div class="container {classes ?? ''}" class:disabled aria-disabled={disabled} data-pw={testId}>
21
+ <div
22
+ class="container {classes ?? ''}"
23
+ class:disabled
24
+ aria-disabled={disabled}
25
+ data-pw={testId}
26
+ testID={testId}
27
+ >
22
28
  <div class="text" hidden={text.length === 0}>{text}</div>
23
29
  <label class="switch">
24
30
  <input
@@ -17,8 +17,12 @@
17
17
  }: ToolbarProperties = $props();
18
18
  </script>
19
19
 
20
- <div class="toolbar {classes ?? ''}" data-pw={testId}>
21
- <div class="content" data-pw={typeof testId === 'string' ? `${testId}-content` : null}>
20
+ <div class="toolbar {classes ?? ''}" data-pw={testId} testID={testId}>
21
+ <div
22
+ class="content"
23
+ data-pw={typeof testId === 'string' ? `${testId}-content` : null}
24
+ testID={typeof testId === 'string' ? `${testId}-content` : null}
25
+ >
22
26
  {#if typeof leftContent === 'function'}
23
27
  {@render leftContent()}
24
28
  {:else if showBackButton && typeof backIcon === 'string' && backIcon.length > 0}
@@ -31,7 +35,7 @@
31
35
  {@render centerContent()}
32
36
  </div>
33
37
  {:else if typeof text === 'string' && text.length > 0}
34
- <div class="text" data-pw={headingTestId}>
38
+ <div class="text" data-pw={headingTestId} testID={headingTestId}>
35
39
  {text}
36
40
  </div>
37
41
  {/if}
@@ -234,10 +234,9 @@
234
234
  }
235
235
  const bubble = document.createElement('div');
236
236
  bubble.setAttribute('role', 'tooltip');
237
- bubble.setAttribute(
238
- 'data-pw',
239
- typeof testId === 'string' ? `${testId}-bubble` : 'tooltip-bubble'
240
- );
237
+ const bubbleTestId = typeof testId === 'string' ? `${testId}-bubble` : 'tooltip-bubble';
238
+ bubble.setAttribute('data-pw', bubbleTestId);
239
+ bubble.setAttribute('testID', bubbleTestId);
241
240
 
242
241
  const coords = computePortalCoords(rect, pos);
243
242
  bubble.style.cssText = [
@@ -359,6 +358,7 @@
359
358
  onfocusin={showTooltip}
360
359
  onfocusout={hideTooltip}
361
360
  data-pw={testId}
361
+ testID={testId}
362
362
  >
363
363
  {#if typeof icon === 'function' && iconPosition === 'leading'}
364
364
  <span class="tooltip-icon" aria-hidden="true">{@render icon()}</span>
@@ -374,6 +374,7 @@
374
374
  role="tooltip"
375
375
  style:--tooltip-shift="{bubbleShift}px"
376
376
  data-pw={typeof testId === 'string' ? `${testId}-bubble` : 'tooltip-bubble'}
377
+ testID={typeof testId === 'string' ? `${testId}-bubble` : 'tooltip-bubble'}
377
378
  >
378
379
  <div class="tooltip-arrow"></div>
379
380
  {#if typeof content === 'function'}
@@ -44,7 +44,11 @@
44
44
  const TICK_SIZE = 6;
45
45
  </script>
46
46
 
47
- <g class="axis axis-{orientation} {classes ?? ''}" data-pw={`axis-${orientation}`}>
47
+ <g
48
+ class="axis axis-{orientation} {classes ?? ''}"
49
+ data-pw={`axis-${orientation}`}
50
+ testID={`axis-${orientation}`}
51
+ >
48
52
  {#if isHorizontal}
49
53
  <line class="axis-line" x1={scale.range[0]} x2={scale.range[1]} y1={0} y2={0} />
50
54
  {#each tickValues as tick, i (i)}
@@ -59,6 +63,7 @@
59
63
  text-anchor="end"
60
64
  dominant-baseline="auto"
61
65
  data-pw={`tick-label-${i}`}
66
+ testID={`tick-label-${i}`}
62
67
  >
63
68
  {format(tick)}
64
69
  </text>
@@ -69,6 +74,7 @@
69
74
  text-anchor="middle"
70
75
  dominant-baseline={orientation === 'bottom' ? 'hanging' : 'auto'}
71
76
  data-pw={`tick-label-${i}`}
77
+ testID={`tick-label-${i}`}
72
78
  >
73
79
  {format(tick)}
74
80
  </text>
@@ -105,6 +111,7 @@
105
111
  text-anchor={orientation === 'left' ? 'end' : 'start'}
106
112
  dominant-baseline="middle"
107
113
  data-pw={`tick-label-${i}`}
114
+ testID={`tick-label-${i}`}
108
115
  >
109
116
  {format(tick)}
110
117
  </text>
@@ -69,6 +69,7 @@
69
69
  class="chart-container {classes ?? ''}"
70
70
  bind:this={containerEl}
71
71
  data-pw={typeof testId === 'string' ? testId : null}
72
+ testID={typeof testId === 'string' ? testId : null}
72
73
  >
73
74
  {#if width > 0 && height > 0}
74
75
  <svg
@@ -86,7 +86,7 @@
86
86
  <div class="tooltip-title">{tooltipData.title}</div>
87
87
  {/if}
88
88
  {#each tooltipData.items as item, i (i)}
89
- <div class="tooltip-item" data-pw={`tooltip-item-${i}`}>
89
+ <div class="tooltip-item" data-pw={`tooltip-item-${i}`} testID={`tooltip-item-${i}`}>
90
90
  {#if item.color}
91
91
  <span class="tooltip-swatch" style="background: {item.color}"></span>
92
92
  {/if}
@@ -107,6 +107,7 @@
107
107
  style="left: {pos.left}px; top: {pos.top}px;"
108
108
  use:portalToBody
109
109
  data-pw="chart-tooltip"
110
+ testID="chart-tooltip"
110
111
  >
111
112
  {@render inner(data)}
112
113
  </div>
@@ -118,6 +119,7 @@
118
119
  class="chart-tooltip {unstyled ? 'unstyled' : ''} {classes ?? ''}"
119
120
  style="left: {pos.left}px; top: {pos.top}px;"
120
121
  data-pw="chart-tooltip"
122
+ testID="chart-tooltip"
121
123
  >
122
124
  {@render inner(data)}
123
125
  </div>
@@ -18,6 +18,7 @@
18
18
  aria-pressed={!item.hidden}
19
19
  onclick={() => onToggle(i)}
20
20
  data-pw={`legend-toggle-${i}`}
21
+ testID={`legend-toggle-${i}`}
21
22
  >
22
23
  <span class="legend-swatch" style="background: {item.color}"></span>
23
24
  <span class="legend-label">{item.label}</span>
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Declares the native test-identifier attribute on every DOM element.
3
+ *
4
+ * Test ids have to reach two runners: Playwright reads the `data-pw` attribute,
5
+ * while Appium resolves an element by its native accessibility identifier and
6
+ * never sees `data-pw`. Components therefore emit both from the same value.
7
+ *
8
+ * `data-*` attributes are accepted by Svelte's typings automatically; a bare
9
+ * `testID` is not, so without this augmentation every emission fails
10
+ * `svelte-check` with "'testID' does not exist in type HTMLProps<...>".
11
+ *
12
+ * Spreading an attribute object would dodge the type error, but a spread makes
13
+ * Svelte skip its static a11y analysis for that element — silently disabling
14
+ * real warnings (it turns existing `svelte-ignore` comments into dead code).
15
+ * Declaring the attribute keeps both the type check and the a11y analysis.
16
+ *
17
+ * The declared key is lower-case because Svelte normalises DOM attribute names,
18
+ * as does `setAttribute` on an HTML document; authors still write `testID`.
19
+ *
20
+ * This file ships in `dist`, so consumers get the same typing for their own usage.
21
+ */
22
+ /* eslint-disable unused-imports/no-unused-vars -- the type parameter name must match
23
+ svelte/elements' own declaration exactly, or interface merging silently fails. */
24
+ declare module 'svelte/elements' {
25
+ export interface HTMLAttributes<T extends EventTarget> {
26
+ /** Native (Appium) test identifier. Mirrors `data-pw`, which Appium cannot read. */
27
+ testid?: string | null;
28
+ }
29
+
30
+ export interface SVGAttributes<T extends EventTarget> {
31
+ /** Native (Appium) test identifier. Mirrors `data-pw`, which Appium cannot read. */
32
+ testid?: string | null;
33
+ }
34
+ }
35
+
36
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/svelte-ui-components",
3
- "version": "2.111.0",
3
+ "version": "2.111.2",
4
4
  "description": "A themeable Svelte 5 UI component library with CSS custom property driven styling",
5
5
  "keywords": [
6
6
  "svelte",