@umituz/web-dashboard 4.4.0 → 4.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/web-dashboard",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.1",
|
|
4
4
|
"description": "Installable app skeleton for the fleet — layouts, auth, onboarding, analytics (dependency-free SVG charts), calendar, i18n injection, permissions/session/module registry; ships its own udb-* stylesheet and --u-* tokens",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"react-router-dom": "^6.0.0 || ^7.0.0"
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
-
"@umituz/web-design-system": "^4.0
|
|
75
|
+
"@umituz/web-design-system": "^4.4.0",
|
|
76
76
|
"lucide-react": "^0.577.0"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
@@ -10,14 +10,21 @@ describe('charts markup smoke', () => {
|
|
|
10
10
|
expect(renderToString(<Sparkline data={[1]} />)).toBe('');
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
it('BarChart renders one column per
|
|
13
|
+
it('BarChart renders one grouped column per label with one bar per series', () => {
|
|
14
14
|
const html = renderToString(
|
|
15
|
-
<BarChart
|
|
15
|
+
<BarChart
|
|
16
|
+
labels={['mon', 'tue', 'wed']}
|
|
17
|
+
series={[
|
|
18
|
+
{ key: 'a', label: 'A', values: [4, 8, 0] },
|
|
19
|
+
{ key: 'b', label: 'B', values: [2, 4, 6], tone: '#111111' },
|
|
20
|
+
]}
|
|
21
|
+
/>,
|
|
16
22
|
);
|
|
17
|
-
expect(html.match(/udb-barchart__col/g)?.length).toBe(3);
|
|
18
|
-
expect(html).
|
|
23
|
+
expect(html.match(/udb-barchart__col(?![a-z])/g)?.length).toBe(3);
|
|
24
|
+
expect(html.match(/udb-barchart__bar(?![a-z_])/g)?.length).toBe(6);
|
|
19
25
|
expect(html).toContain('height:100%');
|
|
20
|
-
expect(html).toContain('
|
|
26
|
+
expect(html).toContain('height:50%');
|
|
27
|
+
expect(html).toContain('#111111');
|
|
21
28
|
});
|
|
22
29
|
|
|
23
30
|
it('Donut renders a segment circle per label with dash math and center fallback', () => {
|
|
@@ -138,51 +138,63 @@ export function HBars({ rows, formatValue = (n: number) => String(n) }: { rows:
|
|
|
138
138
|
);
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
export interface
|
|
141
|
+
export interface BarSeries {
|
|
142
|
+
key: string;
|
|
142
143
|
label: string;
|
|
143
|
-
|
|
144
|
+
values: number[];
|
|
144
145
|
tone?: string;
|
|
145
|
-
highlight?: boolean;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
export function BarChart({
|
|
149
|
-
|
|
149
|
+
labels,
|
|
150
|
+
series,
|
|
150
151
|
height = 130,
|
|
151
|
-
tone = PALETTE[0]!,
|
|
152
|
-
highlightTone = '#c2410c',
|
|
153
152
|
formatValue = (v: number) => String(v),
|
|
154
153
|
formatLabel = (l: string) => l,
|
|
155
154
|
}: {
|
|
156
|
-
|
|
155
|
+
labels: string[];
|
|
156
|
+
series: BarSeries[];
|
|
157
157
|
height?: number;
|
|
158
|
-
tone?: string;
|
|
159
|
-
highlightTone?: string;
|
|
160
158
|
formatValue?: (v: number) => string;
|
|
161
159
|
formatLabel?: (l: string) => string;
|
|
162
160
|
}) {
|
|
163
161
|
const [hover, setHover] = useState<number | null>(null);
|
|
164
|
-
const max = Math.max(1, ...
|
|
162
|
+
const max = Math.max(1, ...series.flatMap((s) => [...s.values]));
|
|
163
|
+
const toneOf = (s: BarSeries, i: number) => s.tone ?? PALETTE[i % PALETTE.length]!;
|
|
165
164
|
return (
|
|
166
165
|
<div className="udb-barchart" style={{ height }}>
|
|
167
|
-
{
|
|
166
|
+
{labels.map((label, i) => (
|
|
168
167
|
<div
|
|
169
|
-
key={
|
|
168
|
+
key={label}
|
|
170
169
|
className="udb-barchart__col"
|
|
171
170
|
onMouseEnter={() => setHover(i)}
|
|
172
171
|
onMouseLeave={() => setHover(null)}
|
|
173
172
|
>
|
|
174
|
-
<div
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
173
|
+
<div className="udb-barchart__bars">
|
|
174
|
+
{series.map((s, si) => (
|
|
175
|
+
<div
|
|
176
|
+
key={s.key}
|
|
177
|
+
className="udb-barchart__bar"
|
|
178
|
+
style={{
|
|
179
|
+
height: `${Math.max(2, ((s.values[i] ?? 0) / max) * 100)}%`,
|
|
180
|
+
background: toneOf(s, si),
|
|
181
|
+
opacity: hover === null || hover === i ? 1 : 0.4,
|
|
182
|
+
}}
|
|
183
|
+
/>
|
|
184
|
+
))}
|
|
185
|
+
</div>
|
|
182
186
|
{hover === i && (
|
|
183
187
|
<div className="udb-barchart__tip">
|
|
184
|
-
<
|
|
185
|
-
{
|
|
188
|
+
<div className="udb-barchart__tiptitle">{formatLabel(label)}</div>
|
|
189
|
+
{series.map((s, si) => (
|
|
190
|
+
<div key={s.key} className="udb-barchart__tiprow">
|
|
191
|
+
<span className="udb-barchart__tiplabel">
|
|
192
|
+
<span className="udb-chartlegend__dot" style={{ background: toneOf(s, si) }} />
|
|
193
|
+
{s.label}
|
|
194
|
+
</span>
|
|
195
|
+
<b>{formatValue(s.values[i] ?? 0)}</b>
|
|
196
|
+
</div>
|
|
197
|
+
))}
|
|
186
198
|
</div>
|
|
187
199
|
)}
|
|
188
200
|
</div>
|
package/src/styles/dashboard.css
CHANGED
|
@@ -2925,6 +2925,20 @@
|
|
|
2925
2925
|
height: 100%;
|
|
2926
2926
|
}
|
|
2927
2927
|
|
|
2928
|
+
.udb-barchart__bars {
|
|
2929
|
+
display: flex;
|
|
2930
|
+
align-items: flex-end;
|
|
2931
|
+
justify-content: center;
|
|
2932
|
+
gap: 2px;
|
|
2933
|
+
width: 100%;
|
|
2934
|
+
height: 100%;
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2937
|
+
.udb-barchart__bars .udb-barchart__bar {
|
|
2938
|
+
flex: 1;
|
|
2939
|
+
width: auto;
|
|
2940
|
+
}
|
|
2941
|
+
|
|
2928
2942
|
.udb-barchart__bar {
|
|
2929
2943
|
width: 100%;
|
|
2930
2944
|
min-height: 2px;
|
|
@@ -2948,6 +2962,24 @@
|
|
|
2948
2962
|
color: var(--u-color-muted);
|
|
2949
2963
|
}
|
|
2950
2964
|
|
|
2965
|
+
.udb-barchart__tiptitle {
|
|
2966
|
+
font-weight: var(--u-font-weight-medium);
|
|
2967
|
+
color: var(--u-color-text);
|
|
2968
|
+
}
|
|
2969
|
+
|
|
2970
|
+
.udb-barchart__tiprow {
|
|
2971
|
+
display: flex;
|
|
2972
|
+
align-items: center;
|
|
2973
|
+
justify-content: space-between;
|
|
2974
|
+
gap: 10px;
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2977
|
+
.udb-barchart__tiplabel {
|
|
2978
|
+
display: inline-flex;
|
|
2979
|
+
align-items: center;
|
|
2980
|
+
gap: 5px;
|
|
2981
|
+
}
|
|
2982
|
+
|
|
2951
2983
|
.udb-barchart__tip b {
|
|
2952
2984
|
margin-right: 4px;
|
|
2953
2985
|
font-weight: var(--u-font-weight-medium);
|