@sybilion/uilib 1.3.23 → 1.3.26
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/esm/components/ui/TextWithDeferTooltip/TextWithDeferTooltip.js +1 -25
- package/dist/esm/components/ui/Tooltip/Tooltip.js +92 -7
- package/dist/esm/components/ui/Tooltip/Tooltip.styl.js +2 -2
- package/dist/esm/components/widgets/DriversComparisonChart/DriversComparisonChart.js +1 -2
- package/dist/esm/components/widgets/PerformanceChart/HorizonsSelector/HorizonsSelector.js +34 -0
- package/dist/esm/components/widgets/PerformanceChart/HorizonsSelector/HorizonsSelector.styl.js +7 -0
- package/dist/esm/components/widgets/PerformanceChart/PerformanceChart.constants.js +17 -0
- package/dist/esm/components/widgets/PerformanceChart/PerformanceChart.js +807 -0
- package/dist/esm/components/widgets/PerformanceChart/PerformanceChart.styl.js +7 -0
- package/dist/esm/components/widgets/PerformanceChart/PerformanceTable.js +130 -0
- package/dist/esm/components/widgets/PerformanceChart/PerformanceUnderChartLegend/PerformanceUnderChartLegend.js +20 -0
- package/dist/esm/components/widgets/PerformanceChart/PerformanceUnderChartLegend/PerformanceUnderChartLegend.styl.js +7 -0
- package/dist/esm/components/widgets/PerformanceChart/performanceChart.helpers.js +591 -0
- package/dist/esm/components/widgets/PerformanceChart/performanceChartUserSeries.js +109 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/types/src/components/ui/Tooltip/Tooltip.d.ts +3 -3
- package/dist/esm/types/src/components/ui/Tooltip/Tooltip.types.d.ts +1 -0
- package/dist/esm/types/src/components/widgets/PerformanceChart/HorizonsSelector/HorizonsSelector.d.ts +7 -0
- package/dist/esm/types/src/components/widgets/PerformanceChart/PerformanceChart.constants.d.ts +3 -0
- package/dist/esm/types/src/components/widgets/PerformanceChart/PerformanceChart.d.ts +54 -0
- package/dist/esm/types/src/components/widgets/PerformanceChart/PerformanceTable.d.ts +31 -0
- package/dist/esm/types/src/components/widgets/PerformanceChart/PerformanceUnderChartLegend/PerformanceUnderChartLegend.d.ts +20 -0
- package/dist/esm/types/src/components/widgets/PerformanceChart/index.d.ts +4 -0
- package/dist/esm/types/src/components/widgets/PerformanceChart/performanceChart.helpers.d.ts +212 -0
- package/dist/esm/types/src/components/widgets/PerformanceChart/performanceChartUserSeries.d.ts +20 -0
- package/dist/esm/types/src/docs/pages/PerformanceChartPage.d.ts +1 -0
- package/dist/esm/types/src/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/components/ui/TextWithDeferTooltip/TextWithDeferTooltip.tsx +5 -37
- package/src/components/ui/Tooltip/Tooltip.styl +12 -0
- package/src/components/ui/Tooltip/Tooltip.styl.d.ts +1 -0
- package/src/components/ui/Tooltip/Tooltip.tsx +156 -8
- package/src/components/ui/Tooltip/Tooltip.types.ts +1 -0
- package/src/components/widgets/PerformanceChart/HorizonsSelector/HorizonsSelector.styl +25 -0
- package/src/components/widgets/PerformanceChart/HorizonsSelector/HorizonsSelector.styl.d.ts +11 -0
- package/src/components/widgets/PerformanceChart/HorizonsSelector/HorizonsSelector.tsx +67 -0
- package/src/components/widgets/PerformanceChart/PerformanceChart.constants.ts +17 -0
- package/src/components/widgets/PerformanceChart/PerformanceChart.styl +194 -0
- package/src/components/widgets/PerformanceChart/PerformanceChart.styl.d.ts +30 -0
- package/src/components/widgets/PerformanceChart/PerformanceChart.tsx +1251 -0
- package/src/components/widgets/PerformanceChart/PerformanceTable.tsx +381 -0
- package/src/components/widgets/PerformanceChart/PerformanceUnderChartLegend/PerformanceUnderChartLegend.styl +49 -0
- package/src/components/widgets/PerformanceChart/PerformanceUnderChartLegend/PerformanceUnderChartLegend.styl.d.ts +12 -0
- package/src/components/widgets/PerformanceChart/PerformanceUnderChartLegend/PerformanceUnderChartLegend.tsx +83 -0
- package/src/components/widgets/PerformanceChart/index.ts +28 -0
- package/src/components/widgets/PerformanceChart/performanceChart.helpers.ts +790 -0
- package/src/components/widgets/PerformanceChart/performanceChartUserSeries.ts +149 -0
- package/src/docs/pages/PerformanceChartPage.tsx +211 -0
- package/src/docs/pages/TextWithDeferTooltipPage.tsx +26 -10
- package/src/docs/pages/TooltipPage.tsx +30 -0
- package/src/docs/registry.ts +6 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { ForecastData } from '#uilib/types/forecast-data';
|
|
2
|
+
import { normalizeToMonthStart } from '#uilib/utils/chartConnectionPoint';
|
|
3
|
+
|
|
4
|
+
export const SPAGHETTI_TIME_SERIES_MATRIX_V = 2 as const;
|
|
5
|
+
|
|
6
|
+
export interface SpaghettiPerformanceMatrixPayload {
|
|
7
|
+
v: typeof SPAGHETTI_TIME_SERIES_MATRIX_V;
|
|
8
|
+
dates: string[];
|
|
9
|
+
horizonKeys: string[];
|
|
10
|
+
grid: number[][];
|
|
11
|
+
perHorizonDates?: string[][];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const SPAGHETTI_MATRIX_SYNTHETIC_BASE = 9_800_000;
|
|
15
|
+
export const SPAGHETTI_MATRIX_MAX_COLS = 128;
|
|
16
|
+
export const SPAGHETTI_LOCAL_LS_USER_SERIES_ROW_ID = 9_000_001;
|
|
17
|
+
|
|
18
|
+
const PER_HORIZON_VIEW_CUSTOM_LINE_ID_BASE =
|
|
19
|
+
SPAGHETTI_MATRIX_SYNTHETIC_BASE + 4_000_000;
|
|
20
|
+
|
|
21
|
+
export function spaghettiMatrixSyntheticId(
|
|
22
|
+
userSeriesRowId: number,
|
|
23
|
+
horizonIndex: number,
|
|
24
|
+
): number {
|
|
25
|
+
return (
|
|
26
|
+
SPAGHETTI_MATRIX_SYNTHETIC_BASE +
|
|
27
|
+
userSeriesRowId * SPAGHETTI_MATRIX_MAX_COLS +
|
|
28
|
+
horizonIndex
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function isSpaghettiMatrixSyntheticLineId(id: number): boolean {
|
|
33
|
+
return id >= SPAGHETTI_MATRIX_SYNTHETIC_BASE;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function perHorizonViewCustomMatrixSyntheticId(colIdx: number): number {
|
|
37
|
+
return PER_HORIZON_VIEW_CUSTOM_LINE_ID_BASE + colIdx;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function matrixHasValidPerHorizonDates(
|
|
41
|
+
matrix: SpaghettiPerformanceMatrixPayload,
|
|
42
|
+
): boolean {
|
|
43
|
+
const ph = matrix.perHorizonDates;
|
|
44
|
+
if (!ph || ph.length !== matrix.grid.length) return false;
|
|
45
|
+
const h = matrix.horizonKeys.length;
|
|
46
|
+
return ph.every(
|
|
47
|
+
(row, r) =>
|
|
48
|
+
Array.isArray(row) &&
|
|
49
|
+
row.length === h &&
|
|
50
|
+
row.length === matrix.grid[r].length,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function getCustomMatrixSeriesForHorizonTab(
|
|
55
|
+
matrix: SpaghettiPerformanceMatrixPayload,
|
|
56
|
+
horizonKey: string,
|
|
57
|
+
rowId: number,
|
|
58
|
+
forecastData: Record<string, ForecastData> | undefined,
|
|
59
|
+
): {
|
|
60
|
+
lineId: number;
|
|
61
|
+
dates: string[];
|
|
62
|
+
forecastValues: number[];
|
|
63
|
+
} | null {
|
|
64
|
+
const colIdx = matrix.horizonKeys.indexOf(horizonKey);
|
|
65
|
+
if (colIdx < 0) return null;
|
|
66
|
+
|
|
67
|
+
if (matrixHasValidPerHorizonDates(matrix)) {
|
|
68
|
+
const ph = matrix.perHorizonDates!;
|
|
69
|
+
const dates: string[] = [];
|
|
70
|
+
const forecastValues: number[] = [];
|
|
71
|
+
for (let r = 0; r < matrix.grid.length; r++) {
|
|
72
|
+
const rawD = ph[r][colIdx];
|
|
73
|
+
const v = matrix.grid[r][colIdx];
|
|
74
|
+
if (typeof v !== 'number' || !Number.isFinite(v)) continue;
|
|
75
|
+
dates.push(
|
|
76
|
+
normalizeToMonthStart(typeof rawD === 'string' ? rawD : String(rawD)),
|
|
77
|
+
);
|
|
78
|
+
forecastValues.push(v);
|
|
79
|
+
}
|
|
80
|
+
if (dates.length === 0) return null;
|
|
81
|
+
return {
|
|
82
|
+
lineId: perHorizonViewCustomMatrixSyntheticId(colIdx),
|
|
83
|
+
dates,
|
|
84
|
+
forecastValues,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const lineId = spaghettiMatrixSyntheticId(rowId, colIdx);
|
|
89
|
+
const fd = forecastData?.[String(lineId)];
|
|
90
|
+
if (!fd?.dates?.length || fd.forecastValues.length !== fd.dates.length) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
lineId,
|
|
95
|
+
dates: fd.dates,
|
|
96
|
+
forecastValues: fd.forecastValues,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
101
|
+
return typeof value === 'object' && value !== null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function tryParseSpaghettiPerformanceMatrix(
|
|
105
|
+
parsed: unknown,
|
|
106
|
+
): SpaghettiPerformanceMatrixPayload | null {
|
|
107
|
+
if (!isRecord(parsed)) return null;
|
|
108
|
+
if (parsed.v !== SPAGHETTI_TIME_SERIES_MATRIX_V) return null;
|
|
109
|
+
const dates = parsed.dates;
|
|
110
|
+
const horizonKeys = parsed.horizonKeys;
|
|
111
|
+
const grid = parsed.grid;
|
|
112
|
+
if (
|
|
113
|
+
!Array.isArray(dates) ||
|
|
114
|
+
!Array.isArray(horizonKeys) ||
|
|
115
|
+
!Array.isArray(grid)
|
|
116
|
+
) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
if (
|
|
120
|
+
dates.length === 0 ||
|
|
121
|
+
horizonKeys.length === 0 ||
|
|
122
|
+
grid.length !== dates.length
|
|
123
|
+
) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
const h = horizonKeys.length;
|
|
127
|
+
if (!grid.every(row => Array.isArray(row) && row.length === h)) return null;
|
|
128
|
+
const perHorizonDates = parsed.perHorizonDates;
|
|
129
|
+
let ph: string[][] | undefined;
|
|
130
|
+
if (perHorizonDates !== undefined) {
|
|
131
|
+
if (
|
|
132
|
+
!Array.isArray(perHorizonDates) ||
|
|
133
|
+
perHorizonDates.length !== grid.length
|
|
134
|
+
) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
ph = perHorizonDates.map(row => {
|
|
138
|
+
if (!Array.isArray(row) || row.length !== h) return [];
|
|
139
|
+
return row.map(d => String(d));
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
v: SPAGHETTI_TIME_SERIES_MATRIX_V,
|
|
144
|
+
dates: dates.map(d => String(d)),
|
|
145
|
+
horizonKeys: horizonKeys.map(k => String(k)),
|
|
146
|
+
grid: grid.map(row => row.map(v => Number(v))),
|
|
147
|
+
...(ph ? { perHorizonDates: ph } : {}),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { useMemo, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { ChartDataPoint } from '#uilib/components/ui/ChartAreaInteractive/ChartAreaInteractive.types';
|
|
4
|
+
import { PageContentSection } from '#uilib/components/ui/Page';
|
|
5
|
+
import { Switch } from '#uilib/components/ui/Switch';
|
|
6
|
+
import {
|
|
7
|
+
PerformanceChart,
|
|
8
|
+
type PerformanceChartPayload,
|
|
9
|
+
SPAGHETTI_TIME_SERIES_MATRIX_V,
|
|
10
|
+
} from '#uilib/components/widgets/PerformanceChart';
|
|
11
|
+
import { useTheme } from '#uilib/contexts/theme-context';
|
|
12
|
+
|
|
13
|
+
import { AppPageHeader } from '../components/AppPageHeader/AppPageHeader';
|
|
14
|
+
import { DocsHeaderActions } from '../docsHeaderActions';
|
|
15
|
+
|
|
16
|
+
function monthKey(year: number, month: number): string {
|
|
17
|
+
return `${year}-${String(month).padStart(2, '0')}-01`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function buildMonthlyHistorical(
|
|
21
|
+
startYear: number,
|
|
22
|
+
startMonth: number,
|
|
23
|
+
count: number,
|
|
24
|
+
base: number,
|
|
25
|
+
): ChartDataPoint[] {
|
|
26
|
+
const out: ChartDataPoint[] = [];
|
|
27
|
+
let y = startYear;
|
|
28
|
+
let m = startMonth;
|
|
29
|
+
for (let i = 0; i < count; i++) {
|
|
30
|
+
out.push({
|
|
31
|
+
date: monthKey(y, m),
|
|
32
|
+
historical: base + Math.sin(i * 0.25) * 8 + i * 0.4,
|
|
33
|
+
});
|
|
34
|
+
m += 1;
|
|
35
|
+
if (m > 12) {
|
|
36
|
+
m = 1;
|
|
37
|
+
y += 1;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function buildHorizonForecasts(
|
|
44
|
+
horizonKey: string,
|
|
45
|
+
startYear: number,
|
|
46
|
+
startMonth: number,
|
|
47
|
+
count: number,
|
|
48
|
+
base: number,
|
|
49
|
+
drift: number,
|
|
50
|
+
): Record<string, number> {
|
|
51
|
+
const out: Record<string, number> = {};
|
|
52
|
+
let y = startYear;
|
|
53
|
+
let m = startMonth;
|
|
54
|
+
for (let i = 0; i < count; i++) {
|
|
55
|
+
out[monthKey(y, m)] = base + Math.cos(i * 0.3 + drift) * 3 + i * 0.15;
|
|
56
|
+
m += 1;
|
|
57
|
+
if (m > 12) {
|
|
58
|
+
m = 1;
|
|
59
|
+
y += 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const MOCK_PERFORMANCE: PerformanceChartPayload = {
|
|
66
|
+
model: {
|
|
67
|
+
forecasts: {
|
|
68
|
+
horizon_1: buildHorizonForecasts('horizon_1', 2022, 1, 24, 112, 0),
|
|
69
|
+
horizon_2: buildHorizonForecasts('horizon_2', 2022, 1, 24, 112, 0.5),
|
|
70
|
+
horizon_3: buildHorizonForecasts('horizon_3', 2022, 1, 24, 112, 1),
|
|
71
|
+
},
|
|
72
|
+
metrics_history: {
|
|
73
|
+
horizon_1: {
|
|
74
|
+
mae: { '24m': 0.42 },
|
|
75
|
+
mape: { '24m': 0.038 },
|
|
76
|
+
},
|
|
77
|
+
horizon_2: {
|
|
78
|
+
mae: { '24m': 0.51 },
|
|
79
|
+
mape: { '24m': 0.045 },
|
|
80
|
+
},
|
|
81
|
+
horizon_3: {
|
|
82
|
+
mae: { '24m': 0.58 },
|
|
83
|
+
mape: { '24m': 0.052 },
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
drift: {
|
|
88
|
+
forecasts: {
|
|
89
|
+
horizon_1: buildHorizonForecasts('horizon_1', 2022, 1, 24, 112, 1.2),
|
|
90
|
+
horizon_2: buildHorizonForecasts('horizon_2', 2022, 1, 24, 112, 1.4),
|
|
91
|
+
horizon_3: buildHorizonForecasts('horizon_3', 2022, 1, 24, 112, 1.6),
|
|
92
|
+
},
|
|
93
|
+
metrics_history: {
|
|
94
|
+
horizon_1: {
|
|
95
|
+
mae: { '24m': 0.62 },
|
|
96
|
+
mape: { '24m': 0.055 },
|
|
97
|
+
},
|
|
98
|
+
horizon_2: {
|
|
99
|
+
mae: { '24m': 0.71 },
|
|
100
|
+
mape: { '24m': 0.061 },
|
|
101
|
+
},
|
|
102
|
+
horizon_3: {
|
|
103
|
+
mae: { '24m': 0.79 },
|
|
104
|
+
mape: { '24m': 0.068 },
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export default function PerformanceChartPage() {
|
|
111
|
+
const { isDarkMode } = useTheme();
|
|
112
|
+
const [loading, setLoading] = useState(false);
|
|
113
|
+
const [runAnalysisHint, setRunAnalysisHint] = useState(false);
|
|
114
|
+
const [emptyPayload, setEmptyPayload] = useState(false);
|
|
115
|
+
const [timeRange, setTimeRange] = useState<string>('All');
|
|
116
|
+
|
|
117
|
+
const performanceData = useMemo(
|
|
118
|
+
() => (emptyPayload ? null : MOCK_PERFORMANCE),
|
|
119
|
+
[emptyPayload],
|
|
120
|
+
);
|
|
121
|
+
const historicalData = useMemo(
|
|
122
|
+
() => buildMonthlyHistorical(2020, 1, 48, 108),
|
|
123
|
+
[],
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<>
|
|
128
|
+
<AppPageHeader
|
|
129
|
+
breadcrumbs={[{ label: 'Performance chart' }]}
|
|
130
|
+
title="PerformanceChart"
|
|
131
|
+
subheader="Per-horizon and spaghetti performance plots with linked metrics table."
|
|
132
|
+
actions={<DocsHeaderActions />}
|
|
133
|
+
/>
|
|
134
|
+
<PageContentSection>
|
|
135
|
+
<div
|
|
136
|
+
style={{
|
|
137
|
+
display: 'flex',
|
|
138
|
+
flexWrap: 'wrap',
|
|
139
|
+
alignItems: 'center',
|
|
140
|
+
gap: 16,
|
|
141
|
+
marginBottom: 16,
|
|
142
|
+
}}
|
|
143
|
+
>
|
|
144
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
|
145
|
+
<Switch
|
|
146
|
+
id="loading-overlay"
|
|
147
|
+
checked={loading}
|
|
148
|
+
onCheckedChange={setLoading}
|
|
149
|
+
/>
|
|
150
|
+
<label htmlFor="loading-overlay">Loading overlay</label>
|
|
151
|
+
</div>
|
|
152
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
|
153
|
+
<Switch
|
|
154
|
+
id="run-analysis-hint"
|
|
155
|
+
checked={runAnalysisHint}
|
|
156
|
+
onCheckedChange={setRunAnalysisHint}
|
|
157
|
+
/>
|
|
158
|
+
<label htmlFor="run-analysis-hint">Run analysis hint</label>
|
|
159
|
+
</div>
|
|
160
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
|
161
|
+
<Switch
|
|
162
|
+
id="empty-payload"
|
|
163
|
+
checked={emptyPayload}
|
|
164
|
+
onCheckedChange={setEmptyPayload}
|
|
165
|
+
/>
|
|
166
|
+
<label htmlFor="empty-payload">Empty payload</label>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
<PerformanceChart
|
|
170
|
+
performanceData={performanceData}
|
|
171
|
+
historicalData={historicalData}
|
|
172
|
+
combinedData={historicalData}
|
|
173
|
+
loading={loading}
|
|
174
|
+
chartLoading={loading}
|
|
175
|
+
performanceSectionPending={loading}
|
|
176
|
+
performanceDataLoading={loading}
|
|
177
|
+
perfFetchSettled={!loading}
|
|
178
|
+
isEmpty={emptyPayload}
|
|
179
|
+
runAnalysisHint={runAnalysisHint}
|
|
180
|
+
statusHint={
|
|
181
|
+
emptyPayload ? 'No performance data for this dataset.' : null
|
|
182
|
+
}
|
|
183
|
+
timeRange={timeRange}
|
|
184
|
+
onTimeRangeChange={setTimeRange}
|
|
185
|
+
isDarkTheme={isDarkMode}
|
|
186
|
+
performanceAnalysisId={1}
|
|
187
|
+
seriesInitKey={emptyPayload ? 'empty' : 'mock'}
|
|
188
|
+
showAddEditCustomDataButton
|
|
189
|
+
customPerformanceMatrix={
|
|
190
|
+
emptyPayload
|
|
191
|
+
? null
|
|
192
|
+
: {
|
|
193
|
+
v: SPAGHETTI_TIME_SERIES_MATRIX_V,
|
|
194
|
+
dates: ['2022-01-01', '2022-02-01'],
|
|
195
|
+
horizonKeys: ['horizon_1', 'horizon_2', 'horizon_3'],
|
|
196
|
+
grid: [
|
|
197
|
+
[111, 110.5, 110],
|
|
198
|
+
[112, 111.2, 110.8],
|
|
199
|
+
],
|
|
200
|
+
perHorizonDates: [
|
|
201
|
+
['2022-01-01', '2022-01-01', '2022-01-01'],
|
|
202
|
+
['2022-02-01', '2022-02-01', '2022-02-01'],
|
|
203
|
+
],
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
customPerformanceLabel="Demo custom series"
|
|
207
|
+
/>
|
|
208
|
+
</PageContentSection>
|
|
209
|
+
</>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
@@ -4,6 +4,9 @@ import { TextWithDeferTooltip } from '#uilib/components/ui/TextWithDeferTooltip'
|
|
|
4
4
|
import { AppPageHeader } from '../components/AppPageHeader/AppPageHeader';
|
|
5
5
|
import { DocsHeaderActions } from '../docsHeaderActions';
|
|
6
6
|
|
|
7
|
+
const LONG_LABEL =
|
|
8
|
+
'This is a long label that should overflow and show a tooltip on hover.';
|
|
9
|
+
|
|
7
10
|
export default function TextWithDeferTooltipPage() {
|
|
8
11
|
return (
|
|
9
12
|
<>
|
|
@@ -13,16 +16,29 @@ export default function TextWithDeferTooltipPage() {
|
|
|
13
16
|
subheader="Tooltip only when text overflows."
|
|
14
17
|
actions={<DocsHeaderActions />}
|
|
15
18
|
/>
|
|
16
|
-
<PageContentSection
|
|
17
|
-
style={{
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
<PageContentSection>
|
|
20
|
+
<p style={{ margin: '0 0 8px', fontWeight: 600 }}>Default</p>
|
|
21
|
+
<div
|
|
22
|
+
style={{
|
|
23
|
+
maxWidth: 120,
|
|
24
|
+
border: '1px dashed var(--border)',
|
|
25
|
+
padding: 8,
|
|
26
|
+
}}
|
|
27
|
+
>
|
|
28
|
+
<TextWithDeferTooltip>{LONG_LABEL}</TextWithDeferTooltip>
|
|
29
|
+
</div>
|
|
30
|
+
</PageContentSection>
|
|
31
|
+
<PageContentSection>
|
|
32
|
+
<p style={{ margin: '0 0 8px', fontWeight: 600 }}>Over trigger</p>
|
|
33
|
+
<div
|
|
34
|
+
style={{
|
|
35
|
+
maxWidth: 120,
|
|
36
|
+
border: '1px dashed var(--border)',
|
|
37
|
+
padding: 8,
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
<TextWithDeferTooltip overTrigger>{LONG_LABEL}</TextWithDeferTooltip>
|
|
41
|
+
</div>
|
|
26
42
|
</PageContentSection>
|
|
27
43
|
</>
|
|
28
44
|
);
|
|
@@ -11,6 +11,9 @@ import { DocsHeaderActions } from '../docsHeaderActions';
|
|
|
11
11
|
|
|
12
12
|
const TOOLTIP_SIDES = ['left', 'top', 'bottom', 'right'] as const;
|
|
13
13
|
|
|
14
|
+
const OVER_TRIGGER_TEXT =
|
|
15
|
+
'Actual Order volume for Baerlocher MB 301, a compound that includes stearin as a component. MB 301 is typically used in construction-grade applications.';
|
|
16
|
+
|
|
14
17
|
export default function TooltipPage() {
|
|
15
18
|
return (
|
|
16
19
|
<>
|
|
@@ -34,6 +37,33 @@ export default function TooltipPage() {
|
|
|
34
37
|
))}
|
|
35
38
|
</div>
|
|
36
39
|
</PageContentSection>
|
|
40
|
+
<PageContentSection>
|
|
41
|
+
<p style={{ margin: '0 0 8px', fontWeight: 600 }}>Over trigger</p>
|
|
42
|
+
<div
|
|
43
|
+
style={{
|
|
44
|
+
maxWidth: 280,
|
|
45
|
+
border: '1px dashed var(--border)',
|
|
46
|
+
padding: 8,
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
<Tooltip>
|
|
50
|
+
<TooltipTrigger asChild>
|
|
51
|
+
<div
|
|
52
|
+
style={{
|
|
53
|
+
overflow: 'hidden',
|
|
54
|
+
textOverflow: 'ellipsis',
|
|
55
|
+
whiteSpace: 'nowrap',
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
{OVER_TRIGGER_TEXT}
|
|
59
|
+
</div>
|
|
60
|
+
</TooltipTrigger>
|
|
61
|
+
<TooltipContent overTrigger maxWidth={400}>
|
|
62
|
+
{OVER_TRIGGER_TEXT}
|
|
63
|
+
</TooltipContent>
|
|
64
|
+
</Tooltip>
|
|
65
|
+
</div>
|
|
66
|
+
</PageContentSection>
|
|
37
67
|
</>
|
|
38
68
|
);
|
|
39
69
|
}
|
package/src/docs/registry.ts
CHANGED
|
@@ -151,6 +151,12 @@ export const DOC_REGISTRY: DocEntry[] = [
|
|
|
151
151
|
section: 'Widgets',
|
|
152
152
|
load: () => import('./pages/DriversComparisonChartPage'),
|
|
153
153
|
},
|
|
154
|
+
{
|
|
155
|
+
slug: 'performance-chart',
|
|
156
|
+
title: 'PerformanceChart',
|
|
157
|
+
section: 'Widgets',
|
|
158
|
+
load: () => import('./pages/PerformanceChartPage'),
|
|
159
|
+
},
|
|
154
160
|
{
|
|
155
161
|
slug: 'dropdown-menu',
|
|
156
162
|
title: 'DropdownMenu',
|
package/src/index.ts
CHANGED
|
@@ -74,6 +74,7 @@ export * from './components/widgets/SidebarDatasetsItemsGrouped';
|
|
|
74
74
|
export * from './components/widgets/DriverCard';
|
|
75
75
|
export * from './components/widgets/DriverMap';
|
|
76
76
|
export * from './components/widgets/DriversComparisonChart';
|
|
77
|
+
export * from './components/widgets/PerformanceChart';
|
|
77
78
|
export * from './components/widgets/SybilionAppHeader';
|
|
78
79
|
export * from './components/widgets/SybilionAuthLayout';
|
|
79
80
|
export * from './components/widgets/SybilionSignInPanel';
|