@juspay/svelte-ui-components 2.96.2 → 2.97.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.
- package/dist/Animations/ModalAnimation.svelte +26 -5
- package/dist/Animations/ModalAnimation.svelte.d.ts +1 -0
- package/dist/Animations/OverlayAnimation.svelte +3 -2
- package/dist/Animations/OverlayAnimation.svelte.d.ts +1 -0
- package/dist/BarChart/BarChart.svelte +4 -0
- package/dist/BrandLoader/BrandLoader.svelte +2 -2
- package/dist/BrandLoader/properties.d.ts +1 -0
- package/dist/Checkbox/Checkbox.svelte +2 -0
- package/dist/DateRangePicker/DateRangePicker.svelte +9 -1
- package/dist/DeltaIndicator/properties.d.ts +1 -1
- package/dist/DualAxisBarChart/DualAxisBarChart.svelte +1 -0
- package/dist/FunnelChart/FunnelChart.svelte +1 -0
- package/dist/GridItem/GridItem.svelte +10 -2
- package/dist/GridItem/properties.d.ts +1 -0
- package/dist/Icon/Icon.svelte +9 -2
- package/dist/Icon/properties.d.ts +1 -0
- package/dist/IconStack/IconStack.svelte +2 -2
- package/dist/IconStack/properties.d.ts +1 -0
- package/dist/Input/Input.svelte +4 -1
- package/dist/InputButton/InputButton.svelte +3 -2
- package/dist/InputButton/properties.d.ts +1 -0
- package/dist/LineChart/LineChart.svelte +9 -1
- package/dist/LoadingDots/LoadingDots.svelte +6 -1
- package/dist/ProportionBar/ProportionBar.svelte +10 -2
- package/dist/SankeyChart/SankeyChart.svelte +35 -6
- package/dist/Select/Select.svelte +13 -1
- package/dist/Sheet/Sheet.svelte +1 -0
- package/dist/StatCard/StatCard.svelte +45 -10
- package/dist/Status/Status.svelte +3 -2
- package/dist/Status/properties.d.ts +1 -0
- package/dist/Table/BuiltinCell.svelte +27 -8
- package/dist/Table/Table.svelte +15 -1
- package/dist/Table/properties.d.ts +1 -3
- package/dist/Toolbar/Toolbar.svelte +1 -1
- package/dist/Tooltip/Tooltip.svelte +5 -0
- package/dist/_chart/Axis.svelte +4 -1
- package/dist/_chart/ChartTooltip.svelte +3 -1
- package/dist/_chart/Legend.svelte +1 -0
- package/package.json +1 -1
|
@@ -9,9 +9,16 @@
|
|
|
9
9
|
align?: ModalAlign;
|
|
10
10
|
transitionType?: ModalTransition;
|
|
11
11
|
children?: Snippet;
|
|
12
|
+
testId?: string;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
let {
|
|
15
|
+
let {
|
|
16
|
+
enable = true,
|
|
17
|
+
align = 'bottom',
|
|
18
|
+
transitionType = 'ALL',
|
|
19
|
+
children,
|
|
20
|
+
testId
|
|
21
|
+
}: Props = $props();
|
|
15
22
|
|
|
16
23
|
let flyAnimationProperties = $derived.by(() => {
|
|
17
24
|
const base = { x: 0, y: 0, duration: 380 };
|
|
@@ -34,19 +41,33 @@
|
|
|
34
41
|
|
|
35
42
|
{#if enable}
|
|
36
43
|
{#if useFlyAnimation && useOutTransition}
|
|
37
|
-
<div
|
|
44
|
+
<div
|
|
45
|
+
in:fly|global={flyAnimationProperties}
|
|
46
|
+
out:fly|global={flyAnimationProperties}
|
|
47
|
+
data-pw={typeof testId === 'string' ? testId : null}
|
|
48
|
+
>
|
|
38
49
|
{@render children?.()}
|
|
39
50
|
</div>
|
|
40
51
|
{:else if useFlyAnimation}
|
|
41
|
-
<div
|
|
52
|
+
<div
|
|
53
|
+
in:fly|global={flyAnimationProperties}
|
|
54
|
+
data-pw={typeof testId === 'string' ? testId : null}
|
|
55
|
+
>
|
|
42
56
|
{@render children?.()}
|
|
43
57
|
</div>
|
|
44
58
|
{:else if useOutTransition}
|
|
45
|
-
<div
|
|
59
|
+
<div
|
|
60
|
+
in:fade|global={fadeAnimationProperties}
|
|
61
|
+
out:fade|global={fadeAnimationProperties}
|
|
62
|
+
data-pw={typeof testId === 'string' ? testId : null}
|
|
63
|
+
>
|
|
46
64
|
{@render children?.()}
|
|
47
65
|
</div>
|
|
48
66
|
{:else}
|
|
49
|
-
<div
|
|
67
|
+
<div
|
|
68
|
+
in:fade|global={fadeAnimationProperties}
|
|
69
|
+
data-pw={typeof testId === 'string' ? testId : null}
|
|
70
|
+
>
|
|
50
71
|
{@render children?.()}
|
|
51
72
|
</div>
|
|
52
73
|
{/if}
|
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
type Props = {
|
|
6
6
|
children?: Snippet;
|
|
7
|
+
testId?: string;
|
|
7
8
|
};
|
|
8
9
|
|
|
9
|
-
let { children }: Props = $props();
|
|
10
|
+
let { children, testId }: Props = $props();
|
|
10
11
|
</script>
|
|
11
12
|
|
|
12
|
-
<div out:fade={{ duration: 350 }}>
|
|
13
|
+
<div out:fade={{ duration: 350 }} data-pw={typeof testId === 'string' ? testId : null}>
|
|
13
14
|
{@render children?.()}
|
|
14
15
|
</div>
|
|
@@ -884,6 +884,7 @@
|
|
|
884
884
|
effectiveHighlightedIndex !== bar.pi)}
|
|
885
885
|
d={stackedBarPath(bar)}
|
|
886
886
|
fill={barFillAttr(bar)}
|
|
887
|
+
data-pw={`bar-${i}`}
|
|
887
888
|
tabindex="0"
|
|
888
889
|
role="button"
|
|
889
890
|
aria-label="{bar.dataPoint.label}: {getDisplayValue(bar)}"
|
|
@@ -912,6 +913,7 @@
|
|
|
912
913
|
rx={barRadius}
|
|
913
914
|
ry={barRadius}
|
|
914
915
|
fill={barFillAttr(bar)}
|
|
916
|
+
data-pw={`bar-${i}`}
|
|
915
917
|
tabindex="0"
|
|
916
918
|
role="button"
|
|
917
919
|
aria-label="{bar.dataPoint.label}: {getDisplayValue(bar)}"
|
|
@@ -930,10 +932,12 @@
|
|
|
930
932
|
<text
|
|
931
933
|
class="bar-value"
|
|
932
934
|
class:bar-value-inside={bl.p.placement === 'inside'}
|
|
935
|
+
data-inside={bl.p.placement === 'inside' ? 'true' : 'false'}
|
|
933
936
|
x={bl.p.x}
|
|
934
937
|
y={bl.p.y}
|
|
935
938
|
text-anchor={bl.p.textAnchor}
|
|
936
939
|
dominant-baseline={bl.p.dominantBaseline}
|
|
940
|
+
data-pw={`bar-value-${i}`}
|
|
937
941
|
style={bl.p.placement === 'inside'
|
|
938
942
|
? `fill: ${getContrastColor(bl.bar.color)}; stroke: ${contrastOutline(bl.bar.color)};`
|
|
939
943
|
: ''}>{bl.text}</text
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { BrandLoaderProperties } from './properties';
|
|
3
3
|
|
|
4
|
-
let { brandLogoURL, brandText, subText, classes }: BrandLoaderProperties = $props();
|
|
4
|
+
let { brandLogoURL, brandText, subText, classes, testId }: BrandLoaderProperties = $props();
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
|
-
<div class="background {classes ?? ''}">
|
|
7
|
+
<div class="background {classes ?? ''}" data-pw={typeof testId === 'string' ? testId : null}>
|
|
8
8
|
<div class="loader">
|
|
9
9
|
<img src={brandLogoURL} alt="" />
|
|
10
10
|
<div class="text">{brandText}</div>
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
tabindex={-1}
|
|
59
59
|
aria-hidden="true"
|
|
60
60
|
onclick={(e: MouseEvent) => e.stopPropagation()}
|
|
61
|
+
data-pw={typeof testId === 'string' ? `${testId}-native-input` : null}
|
|
61
62
|
/>
|
|
62
63
|
<span
|
|
63
64
|
class="box"
|
|
@@ -69,6 +70,7 @@
|
|
|
69
70
|
aria-disabled={disabled}
|
|
70
71
|
aria-controls={ariaControls ?? null}
|
|
71
72
|
onkeydown={handleKeyDown}
|
|
73
|
+
data-pw={typeof testId === 'string' ? `${testId}-box` : null}
|
|
72
74
|
>
|
|
73
75
|
{#if checked && !indeterminate}
|
|
74
76
|
{#if typeof checkedIcon === 'function'}
|
|
@@ -556,6 +556,7 @@
|
|
|
556
556
|
onclick={togglePicker}
|
|
557
557
|
ariaLabel={isOpen ? 'Close date picker' : 'Open date picker'}
|
|
558
558
|
classes="drp-trigger {isOpen ? 'drp-trigger-open' : ''}"
|
|
559
|
+
{...typeof testId === 'string' ? { testId: `${testId}-trigger` } : {}}
|
|
559
560
|
>
|
|
560
561
|
{#if typeof triggerSnippet === 'function'}
|
|
561
562
|
{@render triggerSnippet(triggerLabel)}
|
|
@@ -652,6 +653,7 @@
|
|
|
652
653
|
role="dialog"
|
|
653
654
|
aria-label="Date range picker"
|
|
654
655
|
aria-modal="true"
|
|
656
|
+
data-pw={typeof testId === 'string' ? `${testId}-panel` : null}
|
|
655
657
|
>
|
|
656
658
|
<div class="drp-panel-inner">
|
|
657
659
|
<!-- Preset sidebar -->
|
|
@@ -676,11 +678,17 @@
|
|
|
676
678
|
role="option"
|
|
677
679
|
aria-selected={isPresetActive(preset)}
|
|
678
680
|
onclick={() => handlePreset(preset)}
|
|
681
|
+
data-pw={typeof testId === 'string' ? `${testId}-preset-${preset.label}` : null}
|
|
679
682
|
>
|
|
680
683
|
{preset.label}
|
|
681
684
|
{#if presetCheckmark && isPresetActive(preset)}
|
|
682
685
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
683
|
-
<span
|
|
686
|
+
<span
|
|
687
|
+
class="drp-preset-check"
|
|
688
|
+
aria-hidden="true"
|
|
689
|
+
data-pw={typeof testId === 'string' ? `${testId}-preset-check` : null}
|
|
690
|
+
>{@html checkmarkSvg}</span
|
|
691
|
+
>
|
|
684
692
|
{/if}
|
|
685
693
|
</button>
|
|
686
694
|
{/each}
|
|
@@ -20,7 +20,7 @@ export type OptionalDeltaIndicatorProperties = {
|
|
|
20
20
|
/** Absolute values at or below this are treated as `neutral` (default 0). */
|
|
21
21
|
neutralThreshold?: number;
|
|
22
22
|
/** Test selector applied as the `data-pw` attribute. */
|
|
23
|
-
testId?: string;
|
|
23
|
+
testId?: string | null;
|
|
24
24
|
/** Additional CSS classes for theming. */
|
|
25
25
|
classes?: string;
|
|
26
26
|
};
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
showLoader = $bindable(false),
|
|
9
9
|
onclick,
|
|
10
10
|
onkeydown,
|
|
11
|
-
classes
|
|
11
|
+
classes,
|
|
12
|
+
testId
|
|
12
13
|
}: GridItemProperties = $props();
|
|
13
14
|
|
|
14
15
|
function handleClick(event: MouseEvent) {
|
|
@@ -17,7 +18,14 @@
|
|
|
17
18
|
}
|
|
18
19
|
</script>
|
|
19
20
|
|
|
20
|
-
<div
|
|
21
|
+
<div
|
|
22
|
+
class="container {classes ?? ''}"
|
|
23
|
+
onclick={handleClick}
|
|
24
|
+
{onkeydown}
|
|
25
|
+
role="button"
|
|
26
|
+
tabindex="0"
|
|
27
|
+
data-pw={typeof testId === 'string' ? testId : null}
|
|
28
|
+
>
|
|
21
29
|
<div class="grid-header">
|
|
22
30
|
<img src={headerIcon} alt="" class="grid-item-header-icon" />
|
|
23
31
|
</div>
|
package/dist/Icon/Icon.svelte
CHANGED
|
@@ -2,10 +2,17 @@
|
|
|
2
2
|
import Img from '../Img/Img.svelte';
|
|
3
3
|
import type { IconProperties } from './properties';
|
|
4
4
|
|
|
5
|
-
let { icon, svg, text, onclick, onkeydown, classes }: IconProperties = $props();
|
|
5
|
+
let { icon, svg, text, onclick, onkeydown, classes, testId }: IconProperties = $props();
|
|
6
6
|
</script>
|
|
7
7
|
|
|
8
|
-
<div
|
|
8
|
+
<div
|
|
9
|
+
class="icon-container {classes ?? ''}"
|
|
10
|
+
{onclick}
|
|
11
|
+
{onkeydown}
|
|
12
|
+
role="button"
|
|
13
|
+
tabindex="0"
|
|
14
|
+
data-pw={typeof testId === 'string' ? testId : null}
|
|
15
|
+
>
|
|
9
16
|
{#if typeof svg === 'string' && svg.length > 0}
|
|
10
17
|
<!-- eslint-disable svelte/no-at-html-tags -->
|
|
11
18
|
<span class="icon-svg">{@html svg}</span>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { IconStackProperties } from './properties';
|
|
3
3
|
|
|
4
|
-
let { icons, classes }: IconStackProperties = $props();
|
|
4
|
+
let { icons, classes, testId }: IconStackProperties = $props();
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
|
-
<div class="stack-container {classes ?? ''}">
|
|
7
|
+
<div class="stack-container {classes ?? ''}" data-pw={typeof testId === 'string' ? testId : null}>
|
|
8
8
|
{#each icons as icon, i (i)}
|
|
9
9
|
<div class="stack-icon" style:z-index={icons.length - i}>
|
|
10
10
|
{#if icon.type === 'image'}
|
package/dist/Input/Input.svelte
CHANGED
|
@@ -359,7 +359,10 @@
|
|
|
359
359
|
{/if}
|
|
360
360
|
|
|
361
361
|
{#if onErrorMessage !== '' && showError && !actionInput}
|
|
362
|
-
<div
|
|
362
|
+
<div
|
|
363
|
+
class="error-message"
|
|
364
|
+
data-pw={typeof testId === 'string' && testId.length > 0 ? `${testId}-error-message` : null}
|
|
365
|
+
>
|
|
363
366
|
{onErrorMessage}
|
|
364
367
|
</div>
|
|
365
368
|
{/if}
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
classes,
|
|
20
20
|
mandatory,
|
|
21
21
|
size,
|
|
22
|
-
error
|
|
22
|
+
error,
|
|
23
|
+
testId
|
|
23
24
|
}: InputButtonProperties = $props();
|
|
24
25
|
|
|
25
26
|
let validationState = $state<ValidationState>('InProgress');
|
|
@@ -61,7 +62,7 @@
|
|
|
61
62
|
}
|
|
62
63
|
</script>
|
|
63
64
|
|
|
64
|
-
<div class="container {classes ?? ''}">
|
|
65
|
+
<div class="container {classes ?? ''}" data-pw={typeof testId === 'string' ? testId : null}>
|
|
65
66
|
{#if inputProperties.label && inputProperties.label !== ''}
|
|
66
67
|
<label class="label" for={inputProperties.name}>
|
|
67
68
|
{inputProperties.label}{#if mandatory}<span class="mandatory-marker" aria-label="required">
|
|
@@ -584,7 +584,14 @@
|
|
|
584
584
|
{/if}
|
|
585
585
|
|
|
586
586
|
{#each haloPoints as hp, i (i)}
|
|
587
|
-
<circle
|
|
587
|
+
<circle
|
|
588
|
+
class="dot-halo"
|
|
589
|
+
cx={hp.x}
|
|
590
|
+
cy={hp.y}
|
|
591
|
+
r={dotRadius + 6}
|
|
592
|
+
fill={hp.color}
|
|
593
|
+
data-pw={`dot-halo-${i}`}
|
|
594
|
+
/>
|
|
588
595
|
{/each}
|
|
589
596
|
|
|
590
597
|
{#each lines as line, si (si)}
|
|
@@ -672,6 +679,7 @@
|
|
|
672
679
|
width={dims.innerWidth}
|
|
673
680
|
height={dims.innerHeight}
|
|
674
681
|
fill="transparent"
|
|
682
|
+
data-pw="hover-overlay"
|
|
675
683
|
onpointermove={handleOverlayMove}
|
|
676
684
|
onpointerleave={handleLeave}
|
|
677
685
|
onclick={handleClick}
|
|
@@ -13,7 +13,12 @@
|
|
|
13
13
|
data-pw={typeof testId === 'string' ? testId : null}
|
|
14
14
|
>
|
|
15
15
|
{#each { length: count } as _, i (i)}
|
|
16
|
-
<span
|
|
16
|
+
<span
|
|
17
|
+
class="dot"
|
|
18
|
+
class:pulse={animation === 'pulse'}
|
|
19
|
+
style="--i: {i}"
|
|
20
|
+
data-pw={typeof testId === 'string' ? `${testId}-dot-${i}` : null}
|
|
21
|
+
></span>
|
|
17
22
|
{/each}
|
|
18
23
|
</span>
|
|
19
24
|
|
|
@@ -109,6 +109,7 @@
|
|
|
109
109
|
role={showLegend ? null : 'img'}
|
|
110
110
|
aria-hidden={showLegend ? 'true' : null}
|
|
111
111
|
aria-label={showLegend ? null : ariaSummary}
|
|
112
|
+
data-pw={typeof testId === 'string' ? `${testId}-svg` : null}
|
|
112
113
|
>
|
|
113
114
|
{#each rectSegments as rectSegment, rectIndex (rectIndex)}
|
|
114
115
|
<rect
|
|
@@ -130,9 +131,16 @@
|
|
|
130
131
|
</div>
|
|
131
132
|
|
|
132
133
|
{#if showLegend}
|
|
133
|
-
<ul
|
|
134
|
+
<ul
|
|
135
|
+
class="proportion-bar-legend"
|
|
136
|
+
aria-label="Segment breakdown"
|
|
137
|
+
data-pw={typeof testId === 'string' ? `${testId}-legend` : null}
|
|
138
|
+
>
|
|
134
139
|
{#each computedSegments as computedSegment, legendIndex (legendIndex)}
|
|
135
|
-
<li
|
|
140
|
+
<li
|
|
141
|
+
class="proportion-bar-legend-item"
|
|
142
|
+
data-pw={typeof testId === 'string' ? `${testId}-legend-item-${legendIndex}` : null}
|
|
143
|
+
>
|
|
136
144
|
<span
|
|
137
145
|
class="proportion-bar-swatch"
|
|
138
146
|
style="background: {computedSegment.color};"
|
|
@@ -95,7 +95,35 @@
|
|
|
95
95
|
return Math.max(0, Math.min(chartWidth * 0.25, wanted));
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
// First-column labels render to the LEFT of their node, anchored `end` into the
|
|
99
|
+
// left margin. The bare 40px margin is nowhere near enough for real source labels
|
|
100
|
+
// ("SESSIONS", "Source A", "START") — they truncate to a few characters and, once
|
|
101
|
+
// the room falls below an ellipsis, vanish entirely. Mirror the sink gutter:
|
|
102
|
+
// reserve a capped left gutter sized from the source-node labels (sources are what
|
|
103
|
+
// land in the first column) and shift the diagram right by it.
|
|
104
|
+
let firstColumnLabelGutter = $derived.by(() => {
|
|
105
|
+
if (!showLabels || nodes.length === 0 || chartWidth <= 0) {
|
|
106
|
+
return 0;
|
|
107
|
+
}
|
|
108
|
+
const targetIds = new Set(links.map((link) => link.target));
|
|
109
|
+
const sourceLabels = nodes
|
|
110
|
+
.filter((node) => !targetIds.has(node.id))
|
|
111
|
+
.map((node) => node.label ?? node.id);
|
|
112
|
+
if (sourceLabels.length === 0) {
|
|
113
|
+
return 0;
|
|
114
|
+
}
|
|
115
|
+
const longestPx =
|
|
116
|
+
Math.max(...sourceLabels.map((label) => measureText(label, labelFont).width)) +
|
|
117
|
+
(showValues ? measureText(' (999,999)', labelFont).width : 0);
|
|
118
|
+
const wanted = longestPx + 10 + dataLabelOffsetX;
|
|
119
|
+
// Same 25% cap and 0 floor as the sink gutter so the two together can never
|
|
120
|
+
// starve the diagram, and a negative dataLabelOffsetX can't push past the margin.
|
|
121
|
+
return Math.max(0, Math.min(chartWidth * 0.25, wanted));
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
let plotWidth = $derived(
|
|
125
|
+
Math.max(0, chartWidth - MARGIN * 2 - firstColumnLabelGutter - lastColumnLabelGutter)
|
|
126
|
+
);
|
|
99
127
|
let layout = $derived(
|
|
100
128
|
computeSankeyLayout(
|
|
101
129
|
nodes,
|
|
@@ -151,12 +179,13 @@
|
|
|
151
179
|
// node.x + nodeWidth + 6 + dataLabelOffsetX, so the room before the next
|
|
152
180
|
// column's bar shrinks by the same offset. Omitting it let "fitting"
|
|
153
181
|
// labels run under the neighbouring column's node rect.
|
|
154
|
-
// First-column labels anchor `end` at node.x - 6 - offset with node.x = 0
|
|
155
|
-
//
|
|
156
|
-
//
|
|
182
|
+
// First-column labels anchor `end` at node.x - 6 - offset with node.x = 0.
|
|
183
|
+
// The diagram is shifted right by firstColumnLabelGutter, so the room to the
|
|
184
|
+
// SVG's left edge is that gutter plus the base margin, minus the inset —
|
|
185
|
+
// symmetric with the last column's sink-gutter budget below.
|
|
157
186
|
const available =
|
|
158
187
|
column === 0
|
|
159
|
-
? Math.max(0, MARGIN - 6 - dataLabelOffsetX)
|
|
188
|
+
? Math.max(0, firstColumnLabelGutter + MARGIN - 6 - dataLabelOffsetX)
|
|
160
189
|
: column === columnCount - 1
|
|
161
190
|
? Math.max(0, lastColumnLabelGutter + MARGIN - 6 - dataLabelOffsetX)
|
|
162
191
|
: Math.max(0, colWidth - nodeWidth - 12 - dataLabelOffsetX);
|
|
@@ -396,7 +425,7 @@
|
|
|
396
425
|
<div class="chart-empty">{@render empty()}</div>
|
|
397
426
|
{:else}
|
|
398
427
|
<ChartContainer bind:width={chartWidth} bind:height={chartHeight} {aspectRatio} {maxHeight}>
|
|
399
|
-
<g transform="translate({MARGIN}, {MARGIN})">
|
|
428
|
+
<g transform="translate({MARGIN + firstColumnLabelGutter}, {MARGIN})">
|
|
400
429
|
{#if columnLabels != null && columnLabels.length > 0}
|
|
401
430
|
{#each columnLabels.slice(0, columnCount) as label, ci (ci)}
|
|
402
431
|
<text
|
|
@@ -427,6 +427,7 @@
|
|
|
427
427
|
{disabled}
|
|
428
428
|
autocomplete="off"
|
|
429
429
|
tabindex={disabled ? -1 : 0}
|
|
430
|
+
data-pw={typeof testId === 'string' ? `${testId}-search` : null}
|
|
430
431
|
/>
|
|
431
432
|
{/if}
|
|
432
433
|
{:else}
|
|
@@ -451,6 +452,7 @@
|
|
|
451
452
|
{disabled}
|
|
452
453
|
autocomplete="off"
|
|
453
454
|
tabindex={disabled ? -1 : 0}
|
|
455
|
+
data-pw={typeof testId === 'string' ? `${testId}-search` : null}
|
|
454
456
|
/>
|
|
455
457
|
{:else if value.length === 0}
|
|
456
458
|
<span class="select-placeholder">{placeholder}</span>
|
|
@@ -468,6 +470,7 @@
|
|
|
468
470
|
{disabled}
|
|
469
471
|
autocomplete="off"
|
|
470
472
|
tabindex={disabled ? -1 : 0}
|
|
473
|
+
data-pw={typeof testId === 'string' ? `${testId}-search` : null}
|
|
471
474
|
/>
|
|
472
475
|
{:else}
|
|
473
476
|
<span class={displayText.length > 0 ? 'select-value' : 'select-placeholder'}>
|
|
@@ -524,12 +527,17 @@
|
|
|
524
527
|
class:checked={allFilteredSelected}
|
|
525
528
|
class:indeterminate={selectAllIndeterminate}
|
|
526
529
|
aria-hidden="true"
|
|
530
|
+
data-checked={allFilteredSelected ? 'true' : 'false'}
|
|
531
|
+
data-pw={typeof testId === 'string' ? `${testId}-select-all-indicator` : null}
|
|
527
532
|
>
|
|
528
533
|
{#if allFilteredSelected}
|
|
529
534
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
530
535
|
<span class="select-option-check">{@html checkmarkSvg}</span>
|
|
531
536
|
{:else if selectAllIndeterminate}
|
|
532
|
-
<span
|
|
537
|
+
<span
|
|
538
|
+
class="select-option-dash"
|
|
539
|
+
data-pw={typeof testId === 'string' ? `${testId}-select-all-dash` : null}
|
|
540
|
+
></span>
|
|
533
541
|
{/if}
|
|
534
542
|
</span>
|
|
535
543
|
{/if}
|
|
@@ -567,6 +575,10 @@
|
|
|
567
575
|
class="select-option-indicator"
|
|
568
576
|
class:checked={value.includes(row.item.id)}
|
|
569
577
|
aria-hidden="true"
|
|
578
|
+
data-checked={value.includes(row.item.id) ? 'true' : 'false'}
|
|
579
|
+
data-pw={typeof testId === 'string'
|
|
580
|
+
? `${testId}-option-indicator-${row.item.id}`
|
|
581
|
+
: null}
|
|
570
582
|
>
|
|
571
583
|
{#if value.includes(row.item.id)}
|
|
572
584
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
package/dist/Sheet/Sheet.svelte
CHANGED
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
onkeydown={isInteractive ? handleKeydown : null}
|
|
92
92
|
>
|
|
93
93
|
{#if hasHeaderContent}
|
|
94
|
-
<div class="statcard-header">
|
|
94
|
+
<div class="statcard-header" data-pw={typeof testId === 'string' ? `${testId}-header` : null}>
|
|
95
95
|
<div class="statcard-header-left">
|
|
96
96
|
{#if hasTitle}
|
|
97
97
|
{#if tooltip}
|
|
@@ -112,7 +112,12 @@
|
|
|
112
112
|
</span>
|
|
113
113
|
</Tooltip>
|
|
114
114
|
{:else}
|
|
115
|
-
<div
|
|
115
|
+
<div
|
|
116
|
+
class="statcard-title"
|
|
117
|
+
data-pw={typeof testId === 'string' ? `${testId}-title` : null}
|
|
118
|
+
>
|
|
119
|
+
{title}
|
|
120
|
+
</div>
|
|
116
121
|
{/if}
|
|
117
122
|
{/if}
|
|
118
123
|
{#if checkbox}
|
|
@@ -137,10 +142,17 @@
|
|
|
137
142
|
{/if}
|
|
138
143
|
|
|
139
144
|
{#if hasRows && rows}
|
|
140
|
-
<div
|
|
145
|
+
<div
|
|
146
|
+
class="statcard-rows"
|
|
147
|
+
class:statcard-rows-horizontal={rowsDirection === 'row'}
|
|
148
|
+
data-pw={typeof testId === 'string' ? `${testId}-rows` : null}
|
|
149
|
+
>
|
|
141
150
|
{#each rows as row, rowIndex (rowIndex)}
|
|
142
151
|
{#if rowIndex > 0}
|
|
143
|
-
<div
|
|
152
|
+
<div
|
|
153
|
+
class="statcard-row-divider"
|
|
154
|
+
data-pw={typeof testId === 'string' ? `${testId}-row-divider-${rowIndex}` : null}
|
|
155
|
+
></div>
|
|
144
156
|
{/if}
|
|
145
157
|
<div class="statcard-row" data-pw={typeof row.testId === 'string' ? row.testId : null}>
|
|
146
158
|
{#if typeof row.heading === 'string' && row.heading.length > 0}
|
|
@@ -159,9 +171,18 @@
|
|
|
159
171
|
</div>
|
|
160
172
|
{/if}
|
|
161
173
|
<div class="statcard-row-value-line">
|
|
162
|
-
<div
|
|
174
|
+
<div
|
|
175
|
+
class="statcard-value"
|
|
176
|
+
data-pw={typeof testId === 'string' ? `${testId}-value-${rowIndex}` : null}
|
|
177
|
+
>
|
|
178
|
+
{row.value}
|
|
179
|
+
</div>
|
|
163
180
|
{#if typeof row.change === 'number'}
|
|
164
|
-
<DeltaIndicator
|
|
181
|
+
<DeltaIndicator
|
|
182
|
+
value={row.change}
|
|
183
|
+
invertColors={row.invertChangeColors ?? false}
|
|
184
|
+
testId={testId ? `${testId}-delta-${rowIndex}` : null}
|
|
185
|
+
/>
|
|
165
186
|
{/if}
|
|
166
187
|
{#if typeof row.additionalContent === 'string' && row.additionalContent.length > 0}
|
|
167
188
|
<div class="statcard-row-additional">{row.additionalContent}</div>
|
|
@@ -173,7 +194,12 @@
|
|
|
173
194
|
{/if}
|
|
174
195
|
<div class="statcard-breakdown-grid">
|
|
175
196
|
{#each row.breakdown as breakdownItem, breakdownIndex (breakdownIndex)}
|
|
176
|
-
<div
|
|
197
|
+
<div
|
|
198
|
+
class="statcard-breakdown-item"
|
|
199
|
+
data-pw={typeof testId === 'string'
|
|
200
|
+
? `${testId}-breakdown-item-${rowIndex}-${breakdownIndex}`
|
|
201
|
+
: null}
|
|
202
|
+
>
|
|
177
203
|
<div class="statcard-breakdown-label">{breakdownItem.label}</div>
|
|
178
204
|
<div class="statcard-breakdown-value">{breakdownItem.value}</div>
|
|
179
205
|
{#if typeof breakdownItem.change === 'number'}
|
|
@@ -192,9 +218,13 @@
|
|
|
192
218
|
{:else}
|
|
193
219
|
<div class="statcard-value-row">
|
|
194
220
|
{#if typeof valueSnippet === 'function'}
|
|
195
|
-
<div class="statcard-value"
|
|
221
|
+
<div class="statcard-value" data-pw={typeof testId === 'string' ? `${testId}-value` : null}>
|
|
222
|
+
{@render valueSnippet()}
|
|
223
|
+
</div>
|
|
196
224
|
{:else if typeof value === 'string' && value.length > 0}
|
|
197
|
-
<div class="statcard-value"
|
|
225
|
+
<div class="statcard-value" data-pw={typeof testId === 'string' ? `${testId}-value` : null}>
|
|
226
|
+
{value}
|
|
227
|
+
</div>
|
|
198
228
|
{/if}
|
|
199
229
|
|
|
200
230
|
{#if hasDelta}
|
|
@@ -210,7 +240,12 @@
|
|
|
210
240
|
{/if}
|
|
211
241
|
|
|
212
242
|
{#if typeof subtitle === 'string' && subtitle.length > 0}
|
|
213
|
-
<div
|
|
243
|
+
<div
|
|
244
|
+
class="statcard-subtitle"
|
|
245
|
+
data-pw={typeof testId === 'string' ? `${testId}-subtitle` : null}
|
|
246
|
+
>
|
|
247
|
+
{subtitle}
|
|
248
|
+
</div>
|
|
214
249
|
{/if}
|
|
215
250
|
|
|
216
251
|
{#if children}
|
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
buttonProperties,
|
|
11
11
|
classes,
|
|
12
12
|
onbuttonClick,
|
|
13
|
-
icon
|
|
13
|
+
icon,
|
|
14
|
+
testId
|
|
14
15
|
}: StatusProperties = $props();
|
|
15
16
|
</script>
|
|
16
17
|
|
|
17
|
-
<div class="background {classes ?? ''}">
|
|
18
|
+
<div class="background {classes ?? ''}" data-pw={typeof testId === 'string' ? testId : null}>
|
|
18
19
|
<div class="order-status">
|
|
19
20
|
<div class="status-image">
|
|
20
21
|
{#if icon}
|
|
@@ -141,7 +141,10 @@
|
|
|
141
141
|
: []}
|
|
142
142
|
<div class="builtin-icon-label {alignmentClass}">
|
|
143
143
|
{#each icons as iconSrc, iconIndex (`${iconIndex}-${iconSrc}`)}
|
|
144
|
-
<span
|
|
144
|
+
<span
|
|
145
|
+
class="builtin-icon-label-icon"
|
|
146
|
+
data-pw={column.testId ? `${column.testId}-icon-${iconIndex}` : null}
|
|
147
|
+
>
|
|
145
148
|
<Img src={String(iconSrc)} alt="" fallback="" />
|
|
146
149
|
</span>
|
|
147
150
|
{/each}
|
|
@@ -151,7 +154,7 @@
|
|
|
151
154
|
{@const data = asJsonObject(value) ?? {}}
|
|
152
155
|
<div class="builtin-image-two-line {alignmentClass}">
|
|
153
156
|
{#if typeof data.imageUrl === 'string' && data.imageUrl}
|
|
154
|
-
<span class="builtin-thumb">
|
|
157
|
+
<span class="builtin-thumb" data-pw={column.testId ? `${column.testId}-thumb` : null}>
|
|
155
158
|
<Img
|
|
156
159
|
src={data.imageUrl}
|
|
157
160
|
alt={typeof data.text1 === 'string' ? data.text1 : ''}
|
|
@@ -159,7 +162,10 @@
|
|
|
159
162
|
/>
|
|
160
163
|
</span>
|
|
161
164
|
{:else}
|
|
162
|
-
<span
|
|
165
|
+
<span
|
|
166
|
+
class="builtin-thumb builtin-thumb-placeholder"
|
|
167
|
+
data-pw={column.testId ? `${column.testId}-thumb-placeholder` : null}
|
|
168
|
+
></span>
|
|
163
169
|
{/if}
|
|
164
170
|
<div class="builtin-two-line {alignmentClass}">
|
|
165
171
|
<span class="builtin-primary-text">{typeof data.text1 === 'string' ? data.text1 : '-'}</span>
|
|
@@ -171,8 +177,12 @@
|
|
|
171
177
|
{@const tags = asTagArrayItems(value)}
|
|
172
178
|
{#if tags}
|
|
173
179
|
<div class="builtin-tag-array {alignmentClass}">
|
|
174
|
-
{#each tags as tag (tag.text)}
|
|
175
|
-
<Pill
|
|
180
|
+
{#each tags as tag, tagIndex (`${tagIndex}-${tag.text}`)}
|
|
181
|
+
<Pill
|
|
182
|
+
text={tag.text}
|
|
183
|
+
classes={tag.classes ?? ''}
|
|
184
|
+
testId={tag.testId ?? (column.testId && `${column.testId}-tag-${tagIndex}`)}
|
|
185
|
+
/>
|
|
176
186
|
{/each}
|
|
177
187
|
</div>
|
|
178
188
|
{:else}
|
|
@@ -206,13 +216,19 @@
|
|
|
206
216
|
{/if}
|
|
207
217
|
{#if typeof compare.trendPercent === 'number'}
|
|
208
218
|
{#if compare.trendPercent > 0}
|
|
209
|
-
<span
|
|
219
|
+
<span
|
|
220
|
+
class="builtin-trend builtin-trend-up"
|
|
221
|
+
data-pw={column.testId ? `${column.testId}-trend-up` : null}
|
|
222
|
+
>
|
|
210
223
|
<!-- eslint-disable svelte/no-at-html-tags -->
|
|
211
224
|
<span class="builtin-trend-icon">{@html trendUpSvg}</span>
|
|
212
225
|
{compare.trendPercent}%
|
|
213
226
|
</span>
|
|
214
227
|
{:else if compare.trendPercent < 0}
|
|
215
|
-
<span
|
|
228
|
+
<span
|
|
229
|
+
class="builtin-trend builtin-trend-down"
|
|
230
|
+
data-pw={column.testId ? `${column.testId}-trend-down` : null}
|
|
231
|
+
>
|
|
216
232
|
<!-- eslint-disable svelte/no-at-html-tags -->
|
|
217
233
|
<span class="builtin-trend-icon">{@html trendDownSvg}</span>
|
|
218
234
|
{compare.trendPercent}%
|
|
@@ -480,7 +496,10 @@
|
|
|
480
496
|
</Button>
|
|
481
497
|
</span>
|
|
482
498
|
{#if copied}
|
|
483
|
-
<span
|
|
499
|
+
<span
|
|
500
|
+
class="builtin-link-copied"
|
|
501
|
+
data-pw={column.testId ? `${column.testId}-link-copied` : null}>Copied</span
|
|
502
|
+
>
|
|
484
503
|
{/if}
|
|
485
504
|
{/if}
|
|
486
505
|
</div>
|
package/dist/Table/Table.svelte
CHANGED
|
@@ -630,6 +630,7 @@
|
|
|
630
630
|
? 'mixed'
|
|
631
631
|
: headerCheckboxState === 'all'}
|
|
632
632
|
aria-label="Select all rows"
|
|
633
|
+
data-pw={typeof testId === 'string' ? `${testId}-select-all` : null}
|
|
633
634
|
{...checkboxSelection?.getRowAttributes
|
|
634
635
|
? checkboxSelection.getRowAttributes('__header__', -1)
|
|
635
636
|
: {}}
|
|
@@ -817,6 +818,9 @@
|
|
|
817
818
|
aria-checked={rowSelected}
|
|
818
819
|
aria-disabled={rowDisabled}
|
|
819
820
|
aria-label={`Select row ${rowId || 'non-selectable'}`}
|
|
821
|
+
data-pw={typeof testId === 'string'
|
|
822
|
+
? `${testId}-row-checkbox-${rowId}`
|
|
823
|
+
: null}
|
|
820
824
|
{...checkboxSelection?.getRowAttributes
|
|
821
825
|
? checkboxSelection.getRowAttributes(rowId, rowIndex)
|
|
822
826
|
: {}}
|
|
@@ -859,6 +863,9 @@
|
|
|
859
863
|
<div
|
|
860
864
|
class={isContentScrollable ? 'scrollable-content' : ''}
|
|
861
865
|
class:table-cell-clamp={keyedColumn?.maxWidth && isScalarCell}
|
|
866
|
+
data-pw={keyedColumn?.testId
|
|
867
|
+
? `${keyedColumn.testId}-cell-${rowIndex}`
|
|
868
|
+
: null}
|
|
862
869
|
>
|
|
863
870
|
{#if keyedColumn && typeof keyedColumn.cell === 'function' && keyedRow}
|
|
864
871
|
{@render keyedColumn.cell(keyedRow, rowIndex, originalIndex)}
|
|
@@ -894,7 +901,14 @@
|
|
|
894
901
|
more than one page (or the server reports more chunks); a
|
|
895
902
|
single-page table shows no footer. -->
|
|
896
903
|
<div class="table-footer table-paginator" data-pw={pagination.testId ?? null}>
|
|
897
|
-
<span
|
|
904
|
+
<span
|
|
905
|
+
class="table-paginator-range"
|
|
906
|
+
data-pw={typeof testId === 'string'
|
|
907
|
+
? `${testId}-paginator-range`
|
|
908
|
+
: pagination?.testId
|
|
909
|
+
? `${pagination.testId}-range`
|
|
910
|
+
: null}>{paginationRangeText}</span
|
|
911
|
+
>
|
|
898
912
|
<span class="table-paginator-controls">
|
|
899
913
|
{#if pageSizeOptions.length > 0}
|
|
900
914
|
<span class="table-paginator-size">
|
|
@@ -52,6 +52,7 @@ export type TableImageTwoLineTextCellData = {
|
|
|
52
52
|
export type TableTagArrayCellItem = {
|
|
53
53
|
text: string;
|
|
54
54
|
classes?: string;
|
|
55
|
+
testId?: string;
|
|
55
56
|
};
|
|
56
57
|
/** Cell shape for `type: 'avatar-stack'` — initials chips with overflow. */
|
|
57
58
|
export type TableAvatarStackCellData = {
|
|
@@ -243,9 +244,6 @@ export type TableColumn = {
|
|
|
243
244
|
/**
|
|
244
245
|
* Horizontal alignment for this column's header and body cells. When unset,
|
|
245
246
|
* cells follow the table-wide `--table-text-align` (left by default).
|
|
246
|
-
* Built-in flex cells (compare, two-line-text, text-tag, icon-label,
|
|
247
|
-
* image-two-line-text, tag-array, avatar-stack) mirror it into their flex
|
|
248
|
-
* alignment so stacked/inline content follows the aligned edge too.
|
|
249
247
|
*/
|
|
250
248
|
align?: 'left' | 'center' | 'right';
|
|
251
249
|
/**
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
</script>
|
|
19
19
|
|
|
20
20
|
<div class="toolbar {classes ?? ''}" data-pw={testId}>
|
|
21
|
-
<div class="content">
|
|
21
|
+
<div class="content" data-pw={typeof testId === 'string' ? `${testId}-content` : null}>
|
|
22
22
|
{#if typeof leftContent === 'function'}
|
|
23
23
|
{@render leftContent()}
|
|
24
24
|
{:else if showBackButton && typeof backIcon === 'string' && backIcon.length > 0}
|
|
@@ -234,6 +234,10 @@
|
|
|
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
241
|
|
|
238
242
|
const coords = computePortalCoords(rect, pos);
|
|
239
243
|
bubble.style.cssText = [
|
|
@@ -369,6 +373,7 @@
|
|
|
369
373
|
class="tooltip-bubble {displayPosition}"
|
|
370
374
|
role="tooltip"
|
|
371
375
|
style:--tooltip-shift="{bubbleShift}px"
|
|
376
|
+
data-pw={typeof testId === 'string' ? `${testId}-bubble` : 'tooltip-bubble'}
|
|
372
377
|
>
|
|
373
378
|
<div class="tooltip-arrow"></div>
|
|
374
379
|
{#if typeof content === 'function'}
|
package/dist/_chart/Axis.svelte
CHANGED
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
const TICK_SIZE = 6;
|
|
45
45
|
</script>
|
|
46
46
|
|
|
47
|
-
<g class="axis axis-{orientation} {classes ?? ''}">
|
|
47
|
+
<g class="axis axis-{orientation} {classes ?? ''}" data-pw={`axis-${orientation}`}>
|
|
48
48
|
{#if isHorizontal}
|
|
49
49
|
<line class="axis-line" x1={scale.range[0]} x2={scale.range[1]} y1={0} y2={0} />
|
|
50
50
|
{#each tickValues as tick, i (i)}
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
transform="translate(0, {TICK_SIZE + 4}) rotate(-45)"
|
|
59
59
|
text-anchor="end"
|
|
60
60
|
dominant-baseline="auto"
|
|
61
|
+
data-pw={`tick-label-${i}`}
|
|
61
62
|
>
|
|
62
63
|
{format(tick)}
|
|
63
64
|
</text>
|
|
@@ -67,6 +68,7 @@
|
|
|
67
68
|
y={orientation === 'bottom' ? TICK_SIZE + 4 : -(TICK_SIZE + 4)}
|
|
68
69
|
text-anchor="middle"
|
|
69
70
|
dominant-baseline={orientation === 'bottom' ? 'hanging' : 'auto'}
|
|
71
|
+
data-pw={`tick-label-${i}`}
|
|
70
72
|
>
|
|
71
73
|
{format(tick)}
|
|
72
74
|
</text>
|
|
@@ -102,6 +104,7 @@
|
|
|
102
104
|
x={orientation === 'left' ? -(TICK_SIZE + 4) : TICK_SIZE + 4}
|
|
103
105
|
text-anchor={orientation === 'left' ? 'end' : 'start'}
|
|
104
106
|
dominant-baseline="middle"
|
|
107
|
+
data-pw={`tick-label-${i}`}
|
|
105
108
|
>
|
|
106
109
|
{format(tick)}
|
|
107
110
|
</text>
|
|
@@ -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">
|
|
89
|
+
<div class="tooltip-item" data-pw={`tooltip-item-${i}`}>
|
|
90
90
|
{#if item.color}
|
|
91
91
|
<span class="tooltip-swatch" style="background: {item.color}"></span>
|
|
92
92
|
{/if}
|
|
@@ -106,6 +106,7 @@
|
|
|
106
106
|
class="chart-tooltip portal {unstyled ? 'unstyled' : ''} {classes ?? ''}"
|
|
107
107
|
style="left: {pos.left}px; top: {pos.top}px;"
|
|
108
108
|
use:portalToBody
|
|
109
|
+
data-pw="chart-tooltip"
|
|
109
110
|
>
|
|
110
111
|
{@render inner(data)}
|
|
111
112
|
</div>
|
|
@@ -116,6 +117,7 @@
|
|
|
116
117
|
bind:clientHeight={tooltipHeight}
|
|
117
118
|
class="chart-tooltip {unstyled ? 'unstyled' : ''} {classes ?? ''}"
|
|
118
119
|
style="left: {pos.left}px; top: {pos.top}px;"
|
|
120
|
+
data-pw="chart-tooltip"
|
|
119
121
|
>
|
|
120
122
|
{@render inner(data)}
|
|
121
123
|
</div>
|