@lotics/ui 1.6.0 → 1.6.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 +1 -1
- package/src/bar_chart.tsx +45 -20
- package/src/metric.tsx +15 -1
package/package.json
CHANGED
package/src/bar_chart.tsx
CHANGED
|
@@ -90,10 +90,12 @@ export function BarChart(props: BarChartProps) {
|
|
|
90
90
|
|
|
91
91
|
return (
|
|
92
92
|
<View key={index} style={styles.horizontalBarContainer}>
|
|
93
|
-
<
|
|
94
|
-
{
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
<View style={styles.horizontalBarLabel}>
|
|
94
|
+
<Text size="sm" numberOfLines={1}>
|
|
95
|
+
{item.label}
|
|
96
|
+
</Text>
|
|
97
|
+
</View>
|
|
98
|
+
<View style={styles.horizontalBarTrack}>
|
|
97
99
|
<View
|
|
98
100
|
style={[
|
|
99
101
|
styles.horizontalBar,
|
|
@@ -103,23 +105,31 @@ export function BarChart(props: BarChartProps) {
|
|
|
103
105
|
},
|
|
104
106
|
]}
|
|
105
107
|
/>
|
|
106
|
-
|
|
108
|
+
</View>
|
|
109
|
+
<View style={styles.horizontalBarValue}>
|
|
110
|
+
<Text size="sm" numberOfLines={1}>
|
|
111
|
+
{formatNumber(item.value)}
|
|
112
|
+
</Text>
|
|
107
113
|
</View>
|
|
108
114
|
</View>
|
|
109
115
|
);
|
|
110
116
|
})}
|
|
111
117
|
<View style={styles.horizontalAxisContainer}>
|
|
112
|
-
{
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
{
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
<View style={styles.horizontalBarLabel} />
|
|
119
|
+
<View style={styles.horizontalAxisTrack}>
|
|
120
|
+
{axisTicks.map((tick, index) => (
|
|
121
|
+
<View
|
|
122
|
+
key={index}
|
|
123
|
+
style={[styles.horizontalAxisTick, { left: `${(tick / axisMax) * 100}%` }]}
|
|
124
|
+
>
|
|
125
|
+
<View style={styles.tickMark} />
|
|
126
|
+
<Text size="xs" color="muted">
|
|
127
|
+
{formatNumber(tick)}
|
|
128
|
+
</Text>
|
|
129
|
+
</View>
|
|
130
|
+
))}
|
|
131
|
+
</View>
|
|
132
|
+
<View style={styles.horizontalBarValue} />
|
|
123
133
|
</View>
|
|
124
134
|
</View>
|
|
125
135
|
</View>
|
|
@@ -239,14 +249,24 @@ const styles = StyleSheet.create({
|
|
|
239
249
|
horizontalChart: {
|
|
240
250
|
gap: 8,
|
|
241
251
|
},
|
|
252
|
+
// One row per item: a fixed label column, the bar in a flexing track, and
|
|
253
|
+
// the value in a fixed column — so neither label nor value can be clipped
|
|
254
|
+
// by a long bar, and each item takes one compact row instead of two.
|
|
242
255
|
horizontalBarContainer: {
|
|
243
|
-
gap: 4,
|
|
244
|
-
},
|
|
245
|
-
horizontalBarWrapper: {
|
|
246
256
|
flexDirection: "row",
|
|
247
257
|
alignItems: "center",
|
|
248
258
|
gap: 8,
|
|
249
259
|
},
|
|
260
|
+
horizontalBarLabel: {
|
|
261
|
+
width: 80,
|
|
262
|
+
},
|
|
263
|
+
horizontalBarTrack: {
|
|
264
|
+
flex: 1,
|
|
265
|
+
},
|
|
266
|
+
horizontalBarValue: {
|
|
267
|
+
width: 96,
|
|
268
|
+
alignItems: "flex-end",
|
|
269
|
+
},
|
|
250
270
|
horizontalBar: {
|
|
251
271
|
backgroundColor: colors.blue[500],
|
|
252
272
|
borderRadius: 2,
|
|
@@ -254,9 +274,14 @@ const styles = StyleSheet.create({
|
|
|
254
274
|
minWidth: 2,
|
|
255
275
|
},
|
|
256
276
|
horizontalAxisContainer: {
|
|
277
|
+
flexDirection: "row",
|
|
278
|
+
gap: 8,
|
|
279
|
+
marginTop: 4,
|
|
280
|
+
},
|
|
281
|
+
horizontalAxisTrack: {
|
|
282
|
+
flex: 1,
|
|
257
283
|
position: "relative",
|
|
258
284
|
height: 24,
|
|
259
|
-
marginTop: 4,
|
|
260
285
|
},
|
|
261
286
|
horizontalAxisTick: {
|
|
262
287
|
position: "absolute",
|
package/src/metric.tsx
CHANGED
|
@@ -5,6 +5,9 @@ import { useMemo } from "react";
|
|
|
5
5
|
|
|
6
6
|
export type MetricFormat = "currency" | "number" | "percentage" | "none";
|
|
7
7
|
|
|
8
|
+
/** Semantic colour of the metric value. `default` inherits the text colour. */
|
|
9
|
+
export type MetricTone = "default" | "warning" | "danger";
|
|
10
|
+
|
|
8
11
|
export interface MetricProps {
|
|
9
12
|
value: number | string | null | undefined;
|
|
10
13
|
previousValue?: number | string | null | undefined;
|
|
@@ -12,12 +15,18 @@ export interface MetricProps {
|
|
|
12
15
|
currency?: string;
|
|
13
16
|
locale?: string;
|
|
14
17
|
emptyLabel?: string;
|
|
18
|
+
tone?: MetricTone;
|
|
15
19
|
}
|
|
16
20
|
|
|
17
21
|
const TREND_UP = "↑";
|
|
18
22
|
const TREND_DOWN = "↓";
|
|
19
23
|
const TREND_FLAT = "→";
|
|
20
24
|
|
|
25
|
+
const TONE_COLOR: Record<Exclude<MetricTone, "default">, string> = {
|
|
26
|
+
warning: colors.amber[600],
|
|
27
|
+
danger: colors.red[600],
|
|
28
|
+
};
|
|
29
|
+
|
|
21
30
|
export function Metric(props: MetricProps) {
|
|
22
31
|
const {
|
|
23
32
|
value,
|
|
@@ -26,6 +35,7 @@ export function Metric(props: MetricProps) {
|
|
|
26
35
|
currency = "USD",
|
|
27
36
|
locale,
|
|
28
37
|
emptyLabel = "-",
|
|
38
|
+
tone = "default",
|
|
29
39
|
} = props;
|
|
30
40
|
|
|
31
41
|
const displayValue = useMemo(() => {
|
|
@@ -55,7 +65,11 @@ export function Metric(props: MetricProps) {
|
|
|
55
65
|
|
|
56
66
|
return (
|
|
57
67
|
<View style={styles.container}>
|
|
58
|
-
<Text
|
|
68
|
+
<Text
|
|
69
|
+
size="xl"
|
|
70
|
+
weight="semibold"
|
|
71
|
+
style={tone === "default" ? undefined : { color: TONE_COLOR[tone] }}
|
|
72
|
+
>
|
|
59
73
|
{displayValue}
|
|
60
74
|
</Text>
|
|
61
75
|
{trend && (
|