@juspay/svelte-ui-components 2.100.1 → 2.101.0
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.
|
@@ -641,7 +641,25 @@
|
|
|
641
641
|
right: dims.margin.right,
|
|
642
642
|
bottom: dims.margin.bottom,
|
|
643
643
|
left: dims.margin.left
|
|
644
|
-
}
|
|
644
|
+
},
|
|
645
|
+
bars: bars.map((bar, index) => {
|
|
646
|
+
// barLabels is index-aligned with bars (both derive from the same list);
|
|
647
|
+
// fall back to the bar's top-centre when value labels are hidden.
|
|
648
|
+
const barLabel = barLabels[index];
|
|
649
|
+
return {
|
|
650
|
+
index,
|
|
651
|
+
seriesIndex: bar.si,
|
|
652
|
+
pointIndex: bar.pi,
|
|
653
|
+
x: bar.x,
|
|
654
|
+
y: bar.y,
|
|
655
|
+
width: bar.width,
|
|
656
|
+
height: bar.height,
|
|
657
|
+
value: bar.dataPoint.value,
|
|
658
|
+
label: bar.dataPoint.label ?? '',
|
|
659
|
+
labelX: barLabel ? barLabel.p.x : bar.x + bar.width / 2,
|
|
660
|
+
labelY: barLabel ? barLabel.p.y : bar.y
|
|
661
|
+
};
|
|
662
|
+
})
|
|
645
663
|
});
|
|
646
664
|
|
|
647
665
|
// ── Interactions ───────────────────────────────────────────────
|
|
@@ -47,6 +47,36 @@ export type BarChartSeries = {
|
|
|
47
47
|
/** Series-level fill: plain color, pattern, or gradient. */
|
|
48
48
|
color?: BarFill;
|
|
49
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* Geometry for a single rendered bar, in inner (post-margin) coordinates — the
|
|
52
|
+
* same space the overlay `<g>` draws in, so values map 1:1 without re-applying
|
|
53
|
+
* the margin. `labelX`/`labelY` are the value-label anchor when `showValues` is
|
|
54
|
+
* on, otherwise the bar's top-centre.
|
|
55
|
+
*/
|
|
56
|
+
export type BarChartBarPosition = {
|
|
57
|
+
/** Zero-based index in render order. */
|
|
58
|
+
index: number;
|
|
59
|
+
/** Series index (0-based). */
|
|
60
|
+
seriesIndex: number;
|
|
61
|
+
/** Category / point index (0-based). */
|
|
62
|
+
pointIndex: number;
|
|
63
|
+
/** Bar rectangle x (left edge). */
|
|
64
|
+
x: number;
|
|
65
|
+
/** Bar rectangle y (top edge). */
|
|
66
|
+
y: number;
|
|
67
|
+
/** Bar rectangle width. */
|
|
68
|
+
width: number;
|
|
69
|
+
/** Bar rectangle height. */
|
|
70
|
+
height: number;
|
|
71
|
+
/** The datum's numeric value. */
|
|
72
|
+
value: number;
|
|
73
|
+
/** The datum's category label. */
|
|
74
|
+
label: string;
|
|
75
|
+
/** Value-label anchor x. */
|
|
76
|
+
labelX: number;
|
|
77
|
+
/** Value-label anchor y. */
|
|
78
|
+
labelY: number;
|
|
79
|
+
};
|
|
50
80
|
export type BarChartRenderContext = {
|
|
51
81
|
/** Inner drawing width (pixels) */
|
|
52
82
|
innerWidth: number;
|
|
@@ -65,6 +95,12 @@ export type BarChartRenderContext = {
|
|
|
65
95
|
bottom: number;
|
|
66
96
|
left: number;
|
|
67
97
|
};
|
|
98
|
+
/**
|
|
99
|
+
* Per-bar geometry in render order. Lets an overlay anchor annotations
|
|
100
|
+
* (e.g. an icon above the first funnel step's value) to a specific bar
|
|
101
|
+
* without re-deriving the band scale from innerWidth.
|
|
102
|
+
*/
|
|
103
|
+
bars: BarChartBarPosition[];
|
|
68
104
|
};
|
|
69
105
|
export type BarChartProperties = OptionalBarChartProperties & BarChartEventProperties;
|
|
70
106
|
export type OptionalBarChartProperties = {
|
|
@@ -15,11 +15,22 @@
|
|
|
15
15
|
|
|
16
16
|
let dragOver = $state(false);
|
|
17
17
|
let inputEl: HTMLInputElement | null = $state(null);
|
|
18
|
+
let pickerBusy = false;
|
|
18
19
|
|
|
19
20
|
export const openFilePicker = (): void => {
|
|
20
|
-
if (
|
|
21
|
-
|
|
21
|
+
if (disabled || pickerBusy) {
|
|
22
|
+
return;
|
|
22
23
|
}
|
|
24
|
+
// Idempotent within one click dispatch: if an inner trigger control wires
|
|
25
|
+
// openFilePicker AND the wrapper's own onclick fires for the same user click,
|
|
26
|
+
// the second call is a no-op (guarding against a double-open). Released on the
|
|
27
|
+
// next microtask — after the whole click has finished bubbling — so a genuinely
|
|
28
|
+
// separate later click still opens the picker.
|
|
29
|
+
pickerBusy = true;
|
|
30
|
+
inputEl?.click();
|
|
31
|
+
queueMicrotask(() => {
|
|
32
|
+
pickerBusy = false;
|
|
33
|
+
});
|
|
23
34
|
};
|
|
24
35
|
|
|
25
36
|
function isAccepted(file: File): boolean {
|
|
@@ -107,6 +118,20 @@
|
|
|
107
118
|
openFilePicker();
|
|
108
119
|
}
|
|
109
120
|
}
|
|
121
|
+
|
|
122
|
+
function handleClick(event: MouseEvent): void {
|
|
123
|
+
if (disabled) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
// openFilePicker() calls inputEl.click(), whose click bubbles back up to this
|
|
127
|
+
// wrapper — ignore it so we don't re-enter openFilePicker in a loop. Consumers
|
|
128
|
+
// whose trigger already wires openFilePicker on an inner control should NOT also
|
|
129
|
+
// rely on this handler (it would double-open); clicking the trigger is enough.
|
|
130
|
+
if (event.target === inputEl) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
openFilePicker();
|
|
134
|
+
}
|
|
110
135
|
</script>
|
|
111
136
|
|
|
112
137
|
<div
|
|
@@ -121,6 +146,7 @@
|
|
|
121
146
|
ondragleave={handleDragLeave}
|
|
122
147
|
ondrop={handleDrop}
|
|
123
148
|
onkeydown={handleKeyDown}
|
|
149
|
+
onclick={handleClick}
|
|
124
150
|
>
|
|
125
151
|
<input
|
|
126
152
|
bind:this={inputEl}
|