@juspay/svelte-ui-components 2.110.0 → 2.111.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 (81) 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 +29 -5
  25. package/dist/DeltaIndicator/DeltaIndicator.svelte +10 -0
  26. package/dist/DualAxisBarChart/DualAxisBarChart.svelte +2 -0
  27. package/dist/EmptyState/EmptyState.svelte +5 -1
  28. package/dist/FileInput/FileInput.svelte +2 -0
  29. package/dist/FunnelChart/FunnelChart.svelte +2 -0
  30. package/dist/Gauge/Gauge.svelte +1 -0
  31. package/dist/GridItem/GridItem.svelte +1 -0
  32. package/dist/Icon/Icon.svelte +1 -0
  33. package/dist/IconStack/IconStack.svelte +5 -1
  34. package/dist/IframeViewer/IframeViewer.svelte +1 -1
  35. package/dist/Img/Img.svelte +9 -1
  36. package/dist/Input/Input.svelte +3 -0
  37. package/dist/InputButton/InputButton.svelte +5 -1
  38. package/dist/KeyValue/KeyValue.svelte +2 -1
  39. package/dist/KeyboardInput/KeyboardInput.svelte +1 -0
  40. package/dist/LineChart/LineChart.svelte +3 -0
  41. package/dist/ListItem/ListItem.svelte +5 -0
  42. package/dist/Loader/Loader.svelte +5 -1
  43. package/dist/LoadingDots/LoadingDots.svelte +2 -0
  44. package/dist/LottiePlayer/LottiePlayer.svelte +1 -0
  45. package/dist/Menu/Menu.svelte +2 -0
  46. package/dist/Modal/Modal.svelte +4 -1
  47. package/dist/Pagination/Pagination.svelte +4 -0
  48. package/dist/Phone/Phone.svelte +5 -1
  49. package/dist/PieChart/PieChart.svelte +1 -0
  50. package/dist/Pill/Pill.svelte +1 -0
  51. package/dist/Progress/Progress.svelte +5 -1
  52. package/dist/ProportionBar/ProportionBar.svelte +4 -0
  53. package/dist/Radio/Radio.svelte +1 -0
  54. package/dist/RelativeTime/RelativeTime.svelte +2 -0
  55. package/dist/SankeyChart/SankeyChart.svelte +1 -0
  56. package/dist/Scroller/Scroller.svelte +1 -0
  57. package/dist/Select/Select.svelte +18 -5
  58. package/dist/Sheet/Sheet.svelte +2 -0
  59. package/dist/Shimmer/Shimmer.svelte +5 -1
  60. package/dist/Slider/Slider.svelte +1 -0
  61. package/dist/Snippet/Snippet.svelte +5 -1
  62. package/dist/SplitButton/SplitButton.svelte +1 -0
  63. package/dist/SplitInput/SplitInput.svelte +1 -1
  64. package/dist/StatCard/StatCard.svelte +62 -4
  65. package/dist/StatCard/properties.d.ts +11 -2
  66. package/dist/Status/Status.svelte +5 -1
  67. package/dist/Stepper/Stepper.svelte +6 -1
  68. package/dist/Table/BuiltinCell.svelte +13 -2
  69. package/dist/Table/Table.svelte +24 -1
  70. package/dist/Tabs/Tabs.svelte +2 -1
  71. package/dist/ThemeSwitcher/ThemeSwitcher.svelte +6 -1
  72. package/dist/Toast/Toast.svelte +4 -2
  73. package/dist/Toggle/Toggle.svelte +7 -1
  74. package/dist/Toolbar/Toolbar.svelte +7 -3
  75. package/dist/Tooltip/Tooltip.svelte +5 -4
  76. package/dist/_chart/Axis.svelte +8 -1
  77. package/dist/_chart/ChartContainer.svelte +1 -0
  78. package/dist/_chart/ChartTooltip.svelte +3 -1
  79. package/dist/_chart/Legend.svelte +1 -0
  80. package/dist/testing-attributes.d.ts +36 -0
  81. package/package.json +1 -1
@@ -45,6 +45,7 @@
45
45
  class="accordion {classes ?? ''}"
46
46
  class:expanded={expand}
47
47
  data-pw={typeof testId === 'string' ? testId : null}
48
+ testID={typeof testId === 'string' ? testId : null}
48
49
  >
49
50
  <div class="accordion-content">
50
51
  {@render children?.()}
@@ -45,6 +45,7 @@
45
45
  in:fly|global={flyAnimationProperties}
46
46
  out:fly|global={flyAnimationProperties}
47
47
  data-pw={typeof testId === 'string' ? testId : null}
48
+ testID={typeof testId === 'string' ? testId : null}
48
49
  >
49
50
  {@render children?.()}
50
51
  </div>
@@ -52,6 +53,7 @@
52
53
  <div
53
54
  in:fly|global={flyAnimationProperties}
54
55
  data-pw={typeof testId === 'string' ? testId : null}
56
+ testID={typeof testId === 'string' ? testId : null}
55
57
  >
56
58
  {@render children?.()}
57
59
  </div>
@@ -60,6 +62,7 @@
60
62
  in:fade|global={fadeAnimationProperties}
61
63
  out:fade|global={fadeAnimationProperties}
62
64
  data-pw={typeof testId === 'string' ? testId : null}
65
+ testID={typeof testId === 'string' ? testId : null}
63
66
  >
64
67
  {@render children?.()}
65
68
  </div>
@@ -67,6 +70,7 @@
67
70
  <div
68
71
  in:fade|global={fadeAnimationProperties}
69
72
  data-pw={typeof testId === 'string' ? testId : null}
73
+ testID={typeof testId === 'string' ? testId : null}
70
74
  >
71
75
  {@render children?.()}
72
76
  </div>
@@ -10,6 +10,10 @@
10
10
  let { children, testId }: Props = $props();
11
11
  </script>
12
12
 
13
- <div out:fade={{ duration: 350 }} data-pw={typeof testId === 'string' ? testId : null}>
13
+ <div
14
+ out:fade={{ duration: 350 }}
15
+ data-pw={typeof testId === 'string' ? testId : null}
16
+ testID={typeof testId === 'string' ? testId : null}
17
+ >
14
18
  {@render children?.()}
15
19
  </div>
@@ -350,6 +350,7 @@
350
350
  class="area-chart {classes ?? ''}"
351
351
  bind:this={containerEl}
352
352
  data-pw={typeof testId === 'string' ? testId : null}
353
+ testID={typeof testId === 'string' ? testId : null}
353
354
  >
354
355
  {#if isEmpty && typeof empty === 'function'}
355
356
  <div class="chart-empty">{@render empty()}</div>
@@ -47,12 +47,19 @@
47
47
  type="button"
48
48
  aria-label={alt}
49
49
  data-pw={testId}
50
+ testID={testId}
50
51
  {onclick}
51
52
  >
52
53
  {@render content()}
53
54
  </button>
54
55
  {:else}
55
- <div class="avatar avatar-{size} {classes ?? ''}" role="img" aria-label={alt} data-pw={testId}>
56
+ <div
57
+ class="avatar avatar-{size} {classes ?? ''}"
58
+ role="img"
59
+ aria-label={alt}
60
+ data-pw={testId}
61
+ testID={testId}
62
+ >
56
63
  {@render content()}
57
64
  </div>
58
65
  {/if}
@@ -23,7 +23,11 @@
23
23
  </script>
24
24
 
25
25
  {#if showImage}
26
- <div class="badge-icon {classes ?? ''}" data-pw={typeof testId === 'string' ? testId : null}>
26
+ <div
27
+ class="badge-icon {classes ?? ''}"
28
+ data-pw={typeof testId === 'string' ? testId : null}
29
+ testID={typeof testId === 'string' ? testId : null}
30
+ >
27
31
  <div class="badge-wrap">
28
32
  <img class="icon-img" src={image} {alt} />
29
33
  {#if showBadge}
@@ -38,6 +42,7 @@
38
42
  role={standaloneRole}
39
43
  aria-label={standaloneAriaLabel}
40
44
  data-pw={typeof testId === 'string' ? testId : null}
45
+ testID={typeof testId === 'string' ? testId : null}
41
46
  >
42
47
  {isDot ? '' : (value ?? '')}
43
48
  </div>
@@ -53,6 +53,7 @@
53
53
  role={role !== null ? role : interactive ? 'button' : null}
54
54
  tabindex={interactive ? 0 : null}
55
55
  data-pw={typeof testId === 'string' ? testId : null}
56
+ testID={typeof testId === 'string' ? testId : null}
56
57
  transition:slide={{ duration: 300 }}
57
58
  >
58
59
  {#if typeof icon === 'function'}
@@ -796,6 +796,7 @@
796
796
  class="bar-chart {classes ?? ''}"
797
797
  bind:this={containerEl}
798
798
  data-pw={typeof testId === 'string' ? testId : null}
799
+ testID={typeof testId === 'string' ? testId : null}
799
800
  >
800
801
  {#if isEmpty && typeof empty === 'function'}
801
802
  <div class="chart-empty">{@render empty()}</div>
@@ -951,6 +952,7 @@
951
952
  d={stackedBarPath(bar)}
952
953
  fill={barFillAttr(bar)}
953
954
  data-pw={`bar-${i}`}
955
+ testID={`bar-${i}`}
954
956
  tabindex="0"
955
957
  role="button"
956
958
  aria-label="{bar.dataPoint.label}: {getDisplayValue(bar)}"
@@ -975,6 +977,7 @@
975
977
  d={valueEndBarPath(bar)}
976
978
  fill={barFillAttr(bar)}
977
979
  data-pw={`bar-${i}`}
980
+ testID={`bar-${i}`}
978
981
  tabindex="0"
979
982
  role="button"
980
983
  aria-label="{bar.dataPoint.label}: {getDisplayValue(bar)}"
@@ -999,6 +1002,7 @@
999
1002
  text-anchor={bl.p.textAnchor}
1000
1003
  dominant-baseline={bl.p.dominantBaseline}
1001
1004
  data-pw={`bar-value-${i}`}
1005
+ testID={`bar-value-${i}`}
1002
1006
  style={bl.p.placement === 'inside'
1003
1007
  ? `fill: ${getContrastColor(bl.bar.color)}; stroke: ${contrastOutline(bl.bar.color)};`
1004
1008
  : ''}>{bl.text}</text
@@ -101,6 +101,7 @@
101
101
  <div
102
102
  class="book {classes ?? ''}"
103
103
  data-pw={testId}
104
+ testID={testId}
104
105
  onkeydown={handleKeyDown}
105
106
  ontouchstart={handleTouchStart}
106
107
  ontouchend={handleTouchEnd}
@@ -4,7 +4,11 @@
4
4
  let { brandLogoURL, brandText, subText, classes, testId }: BrandLoaderProperties = $props();
5
5
  </script>
6
6
 
7
- <div class="background {classes ?? ''}" data-pw={typeof testId === 'string' ? testId : null}>
7
+ <div
8
+ class="background {classes ?? ''}"
9
+ data-pw={typeof testId === 'string' ? testId : null}
10
+ testID={typeof testId === 'string' ? testId : null}
11
+ >
8
12
  <div class="loader">
9
13
  <img src={brandLogoURL} alt="" />
10
14
  <div class="text">{brandText}</div>
@@ -8,6 +8,7 @@
8
8
  class="breadcrumb {classes ?? ''}"
9
9
  aria-label={ariaLabel}
10
10
  data-pw={typeof testId === 'string' ? testId : null}
11
+ testID={typeof testId === 'string' ? testId : null}
11
12
  >
12
13
  <ol class="breadcrumb-list">
13
14
  {#each items as crumb, index (index)}
@@ -17,7 +17,13 @@
17
17
  }: BrowserProperties = $props();
18
18
  </script>
19
19
 
20
- <div class="browser {variant} {classes ?? ''}" class:shadow class:rounded data-pw={testId}>
20
+ <div
21
+ class="browser {variant} {classes ?? ''}"
22
+ class:shadow
23
+ class:rounded
24
+ data-pw={testId}
25
+ testID={testId}
26
+ >
21
27
  <div class="chrome">
22
28
  <div class="titlebar">
23
29
  <div class="dots">
@@ -84,6 +84,7 @@
84
84
  {ontouchstart}
85
85
  {ontouchend}
86
86
  data-pw={testId}
87
+ testID={testId}
87
88
  role={role ?? null}
88
89
  aria-label={ariaLabel ?? null}
89
90
  aria-expanded={ariaExpanded ?? null}
@@ -301,7 +301,13 @@
301
301
  }
302
302
  </script>
303
303
 
304
- <div class="calendar {classes ?? ''}" data-pw={testId} role="application" aria-label="Calendar">
304
+ <div
305
+ class="calendar {classes ?? ''}"
306
+ data-pw={testId}
307
+ testID={testId}
308
+ role="application"
309
+ aria-label="Calendar"
310
+ >
305
311
  <div class="header">
306
312
  <div class="nav-button nav-prev">
307
313
  <Button onclick={() => navigateMonth(-1)} ariaLabel="Previous month">
@@ -45,6 +45,7 @@
45
45
  class:card-has-scroll={scrollable}
46
46
  style={styleAttr}
47
47
  data-pw={typeof testId === 'string' ? testId : null}
48
+ testID={typeof testId === 'string' ? testId : null}
48
49
  role={isInteractive ? 'button' : null}
49
50
  tabindex={isInteractive ? 0 : null}
50
51
  onclick={isInteractive ? onclick : null}
@@ -144,6 +144,7 @@
144
144
  <div
145
145
  class="carousel-container {classes ?? ''}"
146
146
  data-pw={typeof testId === 'string' ? testId : null}
147
+ testID={typeof testId === 'string' ? testId : null}
147
148
  >
148
149
  {#if views.length > 0}
149
150
  <div class="carousel" bind:this={carouselDiv}>
@@ -164,6 +165,7 @@
164
165
  <div
165
166
  class="dots-wrapper"
166
167
  data-pw={typeof dotsWrapperTestId === 'string' ? dotsWrapperTestId : null}
168
+ testID={typeof dotsWrapperTestId === 'string' ? dotsWrapperTestId : null}
167
169
  >
168
170
  <!-- eslint-disable-next-line -->
169
171
  {#each views as _, index}
@@ -173,6 +175,7 @@
173
175
  {onkeydown}
174
176
  role="none"
175
177
  data-pw={typeof dotTestId === 'string' ? `${dotTestId}-${index + 1}` : null}
178
+ testID={typeof dotTestId === 'string' ? `${dotTestId}-${index + 1}` : null}
176
179
  ></div>
177
180
  {/each}
178
181
  </div>
@@ -18,7 +18,7 @@
18
18
  }
19
19
  </script>
20
20
 
21
- <div class="container {classes ?? ''}" class:disabled data-pw={testId}>
21
+ <div class="container {classes ?? ''}" class:disabled data-pw={testId} testID={testId}>
22
22
  <div class="checkbox-wrapper">
23
23
  <Checkbox
24
24
  text=""
@@ -49,6 +49,7 @@
49
49
  handleClick();
50
50
  }}
51
51
  data-pw={testId}
52
+ testID={testId}
52
53
  >
53
54
  <input
54
55
  type="checkbox"
@@ -59,6 +60,7 @@
59
60
  aria-hidden="true"
60
61
  onclick={(e: MouseEvent) => e.stopPropagation()}
61
62
  data-pw={typeof testId === 'string' ? `${testId}-native-input` : null}
63
+ testID={typeof testId === 'string' ? `${testId}-native-input` : null}
62
64
  />
63
65
  <span
64
66
  class="box"
@@ -71,6 +73,7 @@
71
73
  aria-controls={ariaControls ?? null}
72
74
  onkeydown={handleKeyDown}
73
75
  data-pw={typeof testId === 'string' ? `${testId}-box` : null}
76
+ testID={typeof testId === 'string' ? `${testId}-box` : null}
74
77
  >
75
78
  {#if checked && !indeterminate}
76
79
  {#if typeof checkedIcon === 'function'}
@@ -42,6 +42,7 @@
42
42
  onclick={handleClick}
43
43
  onkeydown={handleKeyDown}
44
44
  data-pw={testId}
45
+ testID={testId}
45
46
  >
46
47
  {#if typeof children === 'function'}
47
48
  {@render children()}
@@ -188,6 +188,7 @@
188
188
  class="color-picker-container {classes ?? ''}"
189
189
  class:disabled
190
190
  data-pw={testId}
191
+ testID={testId}
191
192
  bind:this={containerEl}
192
193
  >
193
194
  {#if typeof label === 'string'}
@@ -345,7 +345,13 @@
345
345
  });
346
346
  </script>
347
347
 
348
- <div class="combobox {classes ?? ''}" class:disabled bind:this={containerEl} data-pw={testId}>
348
+ <div
349
+ class="combobox {classes ?? ''}"
350
+ class:disabled
351
+ bind:this={containerEl}
352
+ data-pw={testId}
353
+ testID={testId}
354
+ >
349
355
  <!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_static_element_interactions -->
350
356
  <div class="combobox-input-wrapper" class:multiple onclick={handleControlClick}>
351
357
  {#if typeof inputPrefix === 'function'}
@@ -423,6 +429,7 @@
423
429
  }
424
430
  }}
425
431
  data-pw={typeof testId === 'string' ? `${testId}-option-${item.id}` : null}
432
+ testID={typeof testId === 'string' ? `${testId}-option-${item.id}` : null}
426
433
  >
427
434
  {#if typeof itemSnippet === 'function'}
428
435
  {@render itemSnippet(item, isHighlighted)}
@@ -446,6 +453,7 @@
446
453
  onclick={() => create()}
447
454
  onmouseenter={() => (highlightedIndex = createNavIndex)}
448
455
  data-pw={typeof testId === 'string' ? `${testId}-create` : null}
456
+ testID={typeof testId === 'string' ? `${testId}-create` : null}
449
457
  >
450
458
  <span class="combobox-create-icon" aria-hidden="true">
451
459
  <svg viewBox="0 0 20 20" width="14" height="14" fill="none">
@@ -474,6 +482,7 @@
474
482
  onclick={() => runAction()}
475
483
  onmouseenter={() => (highlightedIndex = actionNavIndex)}
476
484
  data-pw={typeof testId === 'string' ? `${testId}-action` : null}
485
+ testID={typeof testId === 'string' ? `${testId}-action` : null}
477
486
  >
478
487
  {#if typeof actionIcon === 'function'}
479
488
  <span class="combobox-action-icon" aria-hidden="true">{@render actionIcon()}</span>
@@ -198,6 +198,7 @@
198
198
  aria-label="Command menu"
199
199
  tabindex="-1"
200
200
  data-pw={typeof testId === 'string' ? testId : null}
201
+ testID={typeof testId === 'string' ? testId : null}
201
202
  >
202
203
  <div class="command-menu-dialog">
203
204
  <div class="command-menu-input-wrapper">
@@ -219,6 +220,7 @@
219
220
  autocomplete="off"
220
221
  spellcheck="false"
221
222
  data-pw={typeof testId === 'string' ? `${testId}-input` : null}
223
+ testID={typeof testId === 'string' ? `${testId}-input` : null}
222
224
  />
223
225
  </div>
224
226
 
@@ -253,6 +255,7 @@
253
255
  aria-disabled={item.disabled}
254
256
  tabindex="-1"
255
257
  data-pw={typeof testId === 'string' ? `${testId}-item-${item.value}` : null}
258
+ testID={typeof testId === 'string' ? `${testId}-item-${item.value}` : null}
256
259
  >
257
260
  {#if typeof itemIcon === 'function'}
258
261
  <span class="command-menu-item-icon">
@@ -164,6 +164,7 @@
164
164
  oncontextmenu={handleContextMenu}
165
165
  role="application"
166
166
  data-pw={testId}
167
+ testID={testId}
167
168
  >
168
169
  {#if typeof children === 'function'}
169
170
  {@render children()}
@@ -203,6 +204,7 @@
203
204
  }
204
205
  }}
205
206
  data-pw={testId ? `${testId}-item-${item.value}` : null}
207
+ testID={testId ? `${testId}-item-${item.value}` : null}
206
208
  >
207
209
  {#if item.icon}
208
210
  <img class="context-menu-item-icon" src={item.icon} alt="" />
@@ -549,7 +549,7 @@
549
549
 
550
550
  <svelte:document onclick={handleDocumentClick} onkeydown={handleDocumentKeyDown} />
551
551
 
552
- <div class="drp-root {classes ?? ''}" data-pw={testId}>
552
+ <div class="drp-root {classes ?? ''}" data-pw={testId} testID={testId}>
553
553
  <!-- Trigger wrapper — bind:this here so outside-click detection works -->
554
554
  <div bind:this={triggerRef} class="drp-trigger-wrapper">
555
555
  <Button
@@ -654,6 +654,7 @@
654
654
  aria-label="Date range picker"
655
655
  aria-modal="true"
656
656
  data-pw={typeof testId === 'string' ? `${testId}-panel` : null}
657
+ testID={typeof testId === 'string' ? `${testId}-panel` : null}
657
658
  >
658
659
  <div class="drp-panel-inner">
659
660
  <!-- Preset sidebar -->
@@ -679,6 +680,7 @@
679
680
  aria-selected={isPresetActive(preset)}
680
681
  onclick={() => handlePreset(preset)}
681
682
  data-pw={typeof testId === 'string' ? `${testId}-preset-${preset.label}` : null}
683
+ testID={typeof testId === 'string' ? `${testId}-preset-${preset.label}` : null}
682
684
  >
683
685
  {preset.label}
684
686
  {#if presetCheckmark && isPresetActive(preset)}
@@ -687,6 +689,7 @@
687
689
  class="drp-preset-check"
688
690
  aria-hidden="true"
689
691
  data-pw={typeof testId === 'string' ? `${testId}-preset-check` : null}
692
+ testID={typeof testId === 'string' ? `${testId}-preset-check` : null}
690
693
  >{@html checkmarkSvg}</span
691
694
  >
692
695
  {/if}
@@ -702,7 +705,11 @@
702
705
  <div class="drp-date-input-row">
703
706
  {#if isInlineTime}
704
707
  <div class="drp-date-time-group">
705
- <div class="drp-date-input" data-pw={testId ? `${testId}-start-date` : null}>
708
+ <div
709
+ class="drp-date-input"
710
+ data-pw={testId ? `${testId}-start-date` : null}
711
+ testID={testId ? `${testId}-start-date` : null}
712
+ >
706
713
  <span class="drp-date-input-value">{draftStartDateLabel || 'Start date'}</span
707
714
  >
708
715
  </div>
@@ -721,13 +728,18 @@
721
728
  aria-label="Start time"
722
729
  aria-invalid={!isStartTimeValid}
723
730
  data-pw={testId ? `${testId}-start-time` : null}
731
+ testID={testId ? `${testId}-start-time` : null}
724
732
  />
725
733
  </div>
726
734
  </div>
727
735
  <!-- eslint-disable-next-line svelte/no-at-html-tags -->
728
736
  <span class="drp-datetime-arrow" aria-hidden="true">{@html chevronRightSvg}</span>
729
737
  <div class="drp-date-time-group">
730
- <div class="drp-date-input" data-pw={testId ? `${testId}-end-date` : null}>
738
+ <div
739
+ class="drp-date-input"
740
+ data-pw={testId ? `${testId}-end-date` : null}
741
+ testID={testId ? `${testId}-end-date` : null}
742
+ >
731
743
  <span class="drp-date-input-value">{draftEndDateLabel || 'End date'}</span>
732
744
  </div>
733
745
  <div
@@ -745,16 +757,25 @@
745
757
  aria-label="End time"
746
758
  aria-invalid={!isEndTimeValid}
747
759
  data-pw={testId ? `${testId}-end-time` : null}
760
+ testID={testId ? `${testId}-end-time` : null}
748
761
  />
749
762
  </div>
750
763
  </div>
751
764
  {:else}
752
- <div class="drp-date-input" data-pw={testId ? `${testId}-start-date` : null}>
765
+ <div
766
+ class="drp-date-input"
767
+ data-pw={testId ? `${testId}-start-date` : null}
768
+ testID={testId ? `${testId}-start-date` : null}
769
+ >
753
770
  <span class="drp-date-input-value">{draftStartDateLabel || 'Start date'}</span>
754
771
  </div>
755
772
  <!-- eslint-disable-next-line svelte/no-at-html-tags -->
756
773
  <span class="drp-datetime-arrow" aria-hidden="true">{@html chevronRightSvg}</span>
757
- <div class="drp-date-input" data-pw={testId ? `${testId}-end-date` : null}>
774
+ <div
775
+ class="drp-date-input"
776
+ data-pw={testId ? `${testId}-end-date` : null}
777
+ testID={testId ? `${testId}-end-date` : null}
778
+ >
758
779
  <span class="drp-date-input-value">{draftEndDateLabel || 'End date'}</span>
759
780
  </div>
760
781
  {#if showTimeSelection}
@@ -765,6 +786,7 @@
765
786
  aria-label="Toggle time selection"
766
787
  aria-pressed={showTimeRow}
767
788
  data-pw={testId ? `${testId}-time-toggle` : null}
789
+ testID={testId ? `${testId}-time-toggle` : null}
768
790
  onclick={() => (showTimeRow = !showTimeRow)}
769
791
  >
770
792
  <!-- eslint-disable-next-line svelte/no-at-html-tags -->
@@ -787,6 +809,7 @@
787
809
  aria-label="Start time"
788
810
  aria-invalid={!isStartTimeValid}
789
811
  data-pw={testId ? `${testId}-start-time` : null}
812
+ testID={testId ? `${testId}-start-time` : null}
790
813
  />
791
814
  </div>
792
815
  <!-- eslint-disable-next-line svelte/no-at-html-tags -->
@@ -803,6 +826,7 @@
803
826
  aria-label="End time"
804
827
  aria-invalid={!isEndTimeValid}
805
828
  data-pw={testId ? `${testId}-end-time` : null}
829
+ testID={testId ? `${testId}-end-time` : null}
806
830
  />
807
831
  </div>
808
832
  </div>
@@ -37,6 +37,7 @@
37
37
  <span
38
38
  class="delta-indicator delta-{tone} {classes ?? ''}"
39
39
  data-pw={typeof testId === 'string' ? testId : null}
40
+ testID={typeof testId === 'string' ? testId : null}
40
41
  >
41
42
  {#if !hideArrow && direction !== 'neutral'}
42
43
  <span class="delta-indicator-arrow delta-arrow-{direction}" aria-hidden="true">
@@ -44,6 +45,10 @@
44
45
  ><path d="M22 7L13.5 15.5L8.5 10.5L2 17" /><path d="M16 7H22V13" /></svg
45
46
  >
46
47
  </span>
48
+ {:else if !hideArrow}
49
+ <!-- Neutral/no-change glyph (design-system "— 0%" treatment): an em dash in
50
+ place of the trend arrow, so a flat delta still reads as a stated state. -->
51
+ <span class="delta-indicator-dash" aria-hidden="true">—</span>
47
52
  {/if}
48
53
  <span class="delta-indicator-text">{text}</span>
49
54
  </span>
@@ -85,6 +90,11 @@
85
90
  flex-shrink: 0;
86
91
  }
87
92
 
93
+ .delta-indicator-dash {
94
+ color: inherit;
95
+ flex-shrink: 0;
96
+ }
97
+
88
98
  .delta-indicator-arrow svg {
89
99
  width: 100%;
90
100
  height: 100%;
@@ -441,6 +441,7 @@
441
441
  class="dual-axis-bar-chart {classes ?? ''}"
442
442
  bind:this={containerEl}
443
443
  data-pw={typeof testId === 'string' ? testId : null}
444
+ testID={typeof testId === 'string' ? testId : null}
444
445
  >
445
446
  {#if !isEmpty}
446
447
  {#if showLegend && (chartWidth === 0 || hideLegendBelow === 0 || chartWidth >= hideLegendBelow)}
@@ -568,6 +569,7 @@
568
569
  height={dims.innerHeight}
569
570
  fill="transparent"
570
571
  data-pw={`hover-target-${hr.catIdx}`}
572
+ testID={`hover-target-${hr.catIdx}`}
571
573
  data-category-index={hr.catIdx}
572
574
  tabindex="0"
573
575
  role="button"
@@ -13,7 +13,11 @@
13
13
  }: EmptyStateProperties = $props();
14
14
  </script>
15
15
 
16
- <div class="empty-state {classes ?? ''}" data-pw={typeof testId === 'string' ? testId : null}>
16
+ <div
17
+ class="empty-state {classes ?? ''}"
18
+ data-pw={typeof testId === 'string' ? testId : null}
19
+ testID={typeof testId === 'string' ? testId : null}
20
+ >
17
21
  {#if typeof icon === 'function'}
18
22
  <div class="empty-state-icon">
19
23
  {@render icon()}
@@ -139,6 +139,7 @@
139
139
  class:file-input-dragover={dragOver}
140
140
  class:file-input-disabled={disabled}
141
141
  data-pw={testId}
142
+ testID={testId}
142
143
  role="button"
143
144
  tabindex={disabled ? -1 : 0}
144
145
  aria-disabled={disabled}
@@ -156,6 +157,7 @@
156
157
  {multiple}
157
158
  {disabled}
158
159
  data-pw={typeof testId === 'string' ? `${testId}-input` : null}
160
+ testID={typeof testId === 'string' ? `${testId}-input` : null}
159
161
  onchange={handleInputChange}
160
162
  tabindex="-1"
161
163
  aria-hidden="true"
@@ -294,6 +294,7 @@
294
294
  class="funnel-chart {classes ?? ''}"
295
295
  bind:this={containerEl}
296
296
  data-pw={typeof testId === 'string' ? testId : null}
297
+ testID={typeof testId === 'string' ? testId : null}
297
298
  >
298
299
  {#if isEmpty && typeof empty === 'function'}
299
300
  <div class="chart-empty">{@render empty()}</div>
@@ -333,6 +334,7 @@
333
334
  x={bx}
334
335
  y={by}
335
336
  data-pw={`funnel-bar-${index}`}
337
+ testID={`funnel-bar-${index}`}
336
338
  width={stageColumnWidth}
337
339
  height={bh}
338
340
  fill={color}
@@ -30,6 +30,7 @@
30
30
  <div
31
31
  class="gauge {classes ?? ''}"
32
32
  data-pw={typeof testId === 'string' ? testId : null}
33
+ testID={typeof testId === 'string' ? testId : null}
33
34
  role="progressbar"
34
35
  aria-valuenow={clamped}
35
36
  aria-valuemin={0}
@@ -25,6 +25,7 @@
25
25
  role="button"
26
26
  tabindex="0"
27
27
  data-pw={typeof testId === 'string' ? testId : null}
28
+ testID={typeof testId === 'string' ? testId : null}
28
29
  >
29
30
  <div class="grid-header">
30
31
  <img src={headerIcon} alt="" class="grid-item-header-icon" />
@@ -12,6 +12,7 @@
12
12
  role="button"
13
13
  tabindex="0"
14
14
  data-pw={typeof testId === 'string' ? testId : null}
15
+ testID={typeof testId === 'string' ? testId : null}
15
16
  >
16
17
  {#if typeof svg === 'string' && svg.length > 0}
17
18
  <!-- eslint-disable svelte/no-at-html-tags -->
@@ -4,7 +4,11 @@
4
4
  let { icons, classes, testId }: IconStackProperties = $props();
5
5
  </script>
6
6
 
7
- <div class="stack-container {classes ?? ''}" data-pw={typeof testId === 'string' ? testId : null}>
7
+ <div
8
+ class="stack-container {classes ?? ''}"
9
+ data-pw={typeof testId === 'string' ? testId : null}
10
+ testID={typeof testId === 'string' ? testId : null}
11
+ >
8
12
  {#each icons as icon, i (i)}
9
13
  <div class="stack-icon" style:z-index={icons.length - i}>
10
14
  {#if icon.type === 'image'}
@@ -42,7 +42,7 @@
42
42
  });
43
43
  </script>
44
44
 
45
- <div class="iframe-viewer {classes ?? ''}" data-pw={testId}>
45
+ <div class="iframe-viewer {classes ?? ''}" data-pw={testId} testID={testId}>
46
46
  {#if src}
47
47
  <iframe bind:this={iframeEl} {src} {title} {allow} {sandbox} {loading} {referrerpolicy}
48
48
  ></iframe>