@modern-admin/ui 0.1.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.
- package/dist/components/accordion.d.ts +7 -0
- package/dist/components/accordion.d.ts.map +1 -0
- package/dist/components/accordion.jsx +19 -0
- package/dist/components/accordion.jsx.map +1 -0
- package/dist/components/alert-dialog.d.ts +22 -0
- package/dist/components/alert-dialog.d.ts.map +1 -0
- package/dist/components/alert-dialog.jsx +27 -0
- package/dist/components/alert-dialog.jsx.map +1 -0
- package/dist/components/audit-timeline.d.ts +24 -0
- package/dist/components/audit-timeline.d.ts.map +1 -0
- package/dist/components/audit-timeline.jsx +60 -0
- package/dist/components/audit-timeline.jsx.map +1 -0
- package/dist/components/avatar.d.ts +6 -0
- package/dist/components/avatar.d.ts.map +1 -0
- package/dist/components/avatar.jsx +10 -0
- package/dist/components/avatar.jsx.map +1 -0
- package/dist/components/badge.d.ts +10 -0
- package/dist/components/badge.d.ts.map +1 -0
- package/dist/components/badge.jsx +19 -0
- package/dist/components/badge.jsx.map +1 -0
- package/dist/components/breadcrumb.d.ts +17 -0
- package/dist/components/breadcrumb.d.ts.map +1 -0
- package/dist/components/breadcrumb.jsx +27 -0
- package/dist/components/breadcrumb.jsx.map +1 -0
- package/dist/components/button.d.ts +12 -0
- package/dist/components/button.d.ts.map +1 -0
- package/dist/components/button.jsx +37 -0
- package/dist/components/button.jsx.map +1 -0
- package/dist/components/calendar.d.ts +9 -0
- package/dist/components/calendar.d.ts.map +1 -0
- package/dist/components/calendar.jsx +102 -0
- package/dist/components/calendar.jsx.map +1 -0
- package/dist/components/card.d.ts +8 -0
- package/dist/components/card.d.ts.map +1 -0
- package/dist/components/card.jsx +18 -0
- package/dist/components/card.jsx.map +1 -0
- package/dist/components/chart.d.ts +97 -0
- package/dist/components/chart.d.ts.map +1 -0
- package/dist/components/chart.jsx +233 -0
- package/dist/components/chart.jsx.map +1 -0
- package/dist/components/checkbox.d.ts +4 -0
- package/dist/components/checkbox.d.ts.map +1 -0
- package/dist/components/checkbox.jsx +11 -0
- package/dist/components/checkbox.jsx.map +1 -0
- package/dist/components/combobox.d.ts +46 -0
- package/dist/components/combobox.d.ts.map +1 -0
- package/dist/components/combobox.jsx +145 -0
- package/dist/components/combobox.jsx.map +1 -0
- package/dist/components/command.d.ts +80 -0
- package/dist/components/command.d.ts.map +1 -0
- package/dist/components/command.jsx +32 -0
- package/dist/components/command.jsx.map +1 -0
- package/dist/components/date-picker.d.ts +24 -0
- package/dist/components/date-picker.d.ts.map +1 -0
- package/dist/components/date-picker.jsx +149 -0
- package/dist/components/date-picker.jsx.map +1 -0
- package/dist/components/date-range-input.d.ts +22 -0
- package/dist/components/date-range-input.d.ts.map +1 -0
- package/dist/components/date-range-input.jsx +202 -0
- package/dist/components/date-range-input.jsx.map +1 -0
- package/dist/components/dialog.d.ts +19 -0
- package/dist/components/dialog.d.ts.map +1 -0
- package/dist/components/dialog.jsx +30 -0
- package/dist/components/dialog.jsx.map +1 -0
- package/dist/components/diff-view.d.ts +24 -0
- package/dist/components/diff-view.d.ts.map +1 -0
- package/dist/components/diff-view.jsx +69 -0
- package/dist/components/diff-view.jsx.map +1 -0
- package/dist/components/dropdown-menu.d.ts +27 -0
- package/dist/components/dropdown-menu.d.ts.map +1 -0
- package/dist/components/dropdown-menu.jsx +48 -0
- package/dist/components/dropdown-menu.jsx.map +1 -0
- package/dist/components/empty.d.ts +15 -0
- package/dist/components/empty.d.ts.map +1 -0
- package/dist/components/empty.jsx +27 -0
- package/dist/components/empty.jsx.map +1 -0
- package/dist/components/field.d.ts +23 -0
- package/dist/components/field.d.ts.map +1 -0
- package/dist/components/field.jsx +60 -0
- package/dist/components/field.jsx.map +1 -0
- package/dist/components/file-input.d.ts +50 -0
- package/dist/components/file-input.d.ts.map +1 -0
- package/dist/components/file-input.jsx +104 -0
- package/dist/components/file-input.jsx.map +1 -0
- package/dist/components/form.d.ts +20 -0
- package/dist/components/form.d.ts.map +1 -0
- package/dist/components/form.jsx +66 -0
- package/dist/components/form.jsx.map +1 -0
- package/dist/components/info-tooltip.d.ts +11 -0
- package/dist/components/info-tooltip.d.ts.map +1 -0
- package/dist/components/info-tooltip.jsx +17 -0
- package/dist/components/info-tooltip.jsx.map +1 -0
- package/dist/components/input.d.ts +13 -0
- package/dist/components/input.d.ts.map +1 -0
- package/dist/components/input.jsx +19 -0
- package/dist/components/input.jsx.map +1 -0
- package/dist/components/json-editor.d.ts +23 -0
- package/dist/components/json-editor.d.ts.map +1 -0
- package/dist/components/json-editor.jsx +143 -0
- package/dist/components/json-editor.jsx.map +1 -0
- package/dist/components/kbd.d.ts +15 -0
- package/dist/components/kbd.d.ts.map +1 -0
- package/dist/components/kbd.jsx +23 -0
- package/dist/components/kbd.jsx.map +1 -0
- package/dist/components/key-value-editor.d.ts +92 -0
- package/dist/components/key-value-editor.d.ts.map +1 -0
- package/dist/components/key-value-editor.jsx +187 -0
- package/dist/components/key-value-editor.jsx.map +1 -0
- package/dist/components/keyboard-shortcuts-help.d.ts +17 -0
- package/dist/components/keyboard-shortcuts-help.d.ts.map +1 -0
- package/dist/components/keyboard-shortcuts-help.jsx +97 -0
- package/dist/components/keyboard-shortcuts-help.jsx.map +1 -0
- package/dist/components/label.d.ts +5 -0
- package/dist/components/label.d.ts.map +1 -0
- package/dist/components/label.jsx +8 -0
- package/dist/components/label.jsx.map +1 -0
- package/dist/components/media-preview.d.ts +30 -0
- package/dist/components/media-preview.d.ts.map +1 -0
- package/dist/components/media-preview.jsx +189 -0
- package/dist/components/media-preview.jsx.map +1 -0
- package/dist/components/multi-file-input.d.ts +76 -0
- package/dist/components/multi-file-input.d.ts.map +1 -0
- package/dist/components/multi-file-input.jsx +131 -0
- package/dist/components/multi-file-input.jsx.map +1 -0
- package/dist/components/password-input.d.ts +10 -0
- package/dist/components/password-input.d.ts.map +1 -0
- package/dist/components/password-input.jsx +18 -0
- package/dist/components/password-input.jsx.map +1 -0
- package/dist/components/popover.d.ts +7 -0
- package/dist/components/popover.d.ts.map +1 -0
- package/dist/components/popover.jsx +11 -0
- package/dist/components/popover.jsx.map +1 -0
- package/dist/components/revision-timeline.d.ts +30 -0
- package/dist/components/revision-timeline.d.ts.map +1 -0
- package/dist/components/revision-timeline.jsx +42 -0
- package/dist/components/revision-timeline.jsx.map +1 -0
- package/dist/components/richtext-editor.d.ts +43 -0
- package/dist/components/richtext-editor.d.ts.map +1 -0
- package/dist/components/richtext-editor.jsx +319 -0
- package/dist/components/richtext-editor.jsx.map +1 -0
- package/dist/components/richtext-mode.d.ts +23 -0
- package/dist/components/richtext-mode.d.ts.map +1 -0
- package/dist/components/richtext-mode.js +36 -0
- package/dist/components/richtext-mode.js.map +1 -0
- package/dist/components/richtext-render.d.ts +8 -0
- package/dist/components/richtext-render.d.ts.map +1 -0
- package/dist/components/richtext-render.jsx +33 -0
- package/dist/components/richtext-render.jsx.map +1 -0
- package/dist/components/richtext-sync.d.ts +37 -0
- package/dist/components/richtext-sync.d.ts.map +1 -0
- package/dist/components/richtext-sync.js +46 -0
- package/dist/components/richtext-sync.js.map +1 -0
- package/dist/components/scroll-area.d.ts +5 -0
- package/dist/components/scroll-area.d.ts.map +1 -0
- package/dist/components/scroll-area.jsx +16 -0
- package/dist/components/scroll-area.jsx.map +1 -0
- package/dist/components/select.d.ts +36 -0
- package/dist/components/select.d.ts.map +1 -0
- package/dist/components/select.jsx +87 -0
- package/dist/components/select.jsx.map +1 -0
- package/dist/components/separator.d.ts +4 -0
- package/dist/components/separator.d.ts.map +1 -0
- package/dist/components/separator.jsx +6 -0
- package/dist/components/separator.jsx.map +1 -0
- package/dist/components/sheet.d.ts +29 -0
- package/dist/components/sheet.d.ts.map +1 -0
- package/dist/components/sheet.jsx +44 -0
- package/dist/components/sheet.jsx.map +1 -0
- package/dist/components/sidebar.d.ts +70 -0
- package/dist/components/sidebar.d.ts.map +1 -0
- package/dist/components/sidebar.jsx +245 -0
- package/dist/components/sidebar.jsx.map +1 -0
- package/dist/components/skeleton.d.ts +3 -0
- package/dist/components/skeleton.d.ts.map +1 -0
- package/dist/components/skeleton.jsx +6 -0
- package/dist/components/skeleton.jsx.map +1 -0
- package/dist/components/sonner.d.ts +6 -0
- package/dist/components/sonner.d.ts.map +1 -0
- package/dist/components/sonner.jsx +29 -0
- package/dist/components/sonner.jsx.map +1 -0
- package/dist/components/switch.d.ts +4 -0
- package/dist/components/switch.d.ts.map +1 -0
- package/dist/components/switch.jsx +8 -0
- package/dist/components/switch.jsx.map +1 -0
- package/dist/components/table.d.ts +10 -0
- package/dist/components/table.d.ts.map +1 -0
- package/dist/components/table.jsx +21 -0
- package/dist/components/table.jsx.map +1 -0
- package/dist/components/tabs.d.ts +7 -0
- package/dist/components/tabs.d.ts.map +1 -0
- package/dist/components/tabs.jsx +14 -0
- package/dist/components/tabs.jsx.map +1 -0
- package/dist/components/textarea.d.ts +4 -0
- package/dist/components/textarea.d.ts.map +1 -0
- package/dist/components/textarea.jsx +5 -0
- package/dist/components/textarea.jsx.map +1 -0
- package/dist/components/tooltip.d.ts +7 -0
- package/dist/components/tooltip.d.ts.map +1 -0
- package/dist/components/tooltip.jsx +11 -0
- package/dist/components/tooltip.jsx.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/theme.d.ts +11 -0
- package/dist/lib/theme.d.ts.map +1 -0
- package/dist/lib/theme.js +44 -0
- package/dist/lib/theme.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +6 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/styles.css +242 -0
- package/package.json +85 -0
- package/src/components/accordion.tsx +48 -0
- package/src/components/alert-dialog.tsx +113 -0
- package/src/components/audit-timeline.tsx +102 -0
- package/src/components/avatar.tsx +42 -0
- package/src/components/badge.tsx +34 -0
- package/src/components/breadcrumb.tsx +99 -0
- package/src/components/button.tsx +58 -0
- package/src/components/calendar.tsx +176 -0
- package/src/components/card.tsx +60 -0
- package/src/components/chart.tsx +558 -0
- package/src/components/checkbox.tsx +23 -0
- package/src/components/combobox.tsx +264 -0
- package/src/components/command.tsx +120 -0
- package/src/components/date-picker.tsx +221 -0
- package/src/components/date-range-input.tsx +295 -0
- package/src/components/dialog.tsx +94 -0
- package/src/components/diff-view.tsx +182 -0
- package/src/components/dropdown-menu.tsx +165 -0
- package/src/components/empty.tsx +100 -0
- package/src/components/field.tsx +168 -0
- package/src/components/file-input.tsx +233 -0
- package/src/components/form.tsx +152 -0
- package/src/components/info-tooltip.tsx +40 -0
- package/src/components/input.tsx +55 -0
- package/src/components/json-editor.tsx +210 -0
- package/src/components/kbd.tsx +35 -0
- package/src/components/key-value-editor.tsx +423 -0
- package/src/components/keyboard-shortcuts-help.tsx +136 -0
- package/src/components/label.tsx +16 -0
- package/src/components/media-preview.tsx +278 -0
- package/src/components/multi-file-input.tsx +315 -0
- package/src/components/password-input.tsx +50 -0
- package/src/components/popover.tsx +26 -0
- package/src/components/revision-timeline.tsx +93 -0
- package/src/components/richtext-editor.tsx +624 -0
- package/src/components/richtext-mode.ts +39 -0
- package/src/components/richtext-render.tsx +51 -0
- package/src/components/richtext-sync.ts +57 -0
- package/src/components/scroll-area.tsx +41 -0
- package/src/components/select.tsx +200 -0
- package/src/components/separator.tsx +21 -0
- package/src/components/sheet.tsx +109 -0
- package/src/components/sidebar.tsx +660 -0
- package/src/components/skeleton.tsx +9 -0
- package/src/components/sonner.tsx +45 -0
- package/src/components/switch.tsx +24 -0
- package/src/components/table.tsx +93 -0
- package/src/components/tabs.tsx +57 -0
- package/src/components/textarea.tsx +18 -0
- package/src/components/tooltip.tsx +25 -0
- package/src/index.ts +342 -0
- package/src/lib/theme.ts +45 -0
- package/src/lib/utils.ts +6 -0
- package/src/styles.css +242 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type ChartType = 'line' | 'area' | 'bar' | 'pie';
|
|
3
|
+
export interface ChartDataPoint {
|
|
4
|
+
label: string;
|
|
5
|
+
value: number;
|
|
6
|
+
}
|
|
7
|
+
export interface ChartPanelLabels {
|
|
8
|
+
noData?: string;
|
|
9
|
+
value?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ChartPanelProps {
|
|
12
|
+
data: ChartDataPoint[];
|
|
13
|
+
type?: ChartType;
|
|
14
|
+
color?: string;
|
|
15
|
+
height?: number;
|
|
16
|
+
labels?: ChartPanelLabels;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function ChartPanel({ data, type, color, height, labels, className, }: ChartPanelProps): React.ReactElement;
|
|
20
|
+
export interface KpiCardLabels {
|
|
21
|
+
noData?: string;
|
|
22
|
+
/** Template with `{value}` and `{percent}` placeholders. */
|
|
23
|
+
deltaUp?: string;
|
|
24
|
+
deltaDown?: string;
|
|
25
|
+
deltaFlat?: string;
|
|
26
|
+
previousPeriod?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface KpiCardProps {
|
|
29
|
+
/** Aggregated value over the current window. */
|
|
30
|
+
value: number | null | undefined;
|
|
31
|
+
/** Aggregated value over the equal-length previous window. */
|
|
32
|
+
previousValue?: number | null;
|
|
33
|
+
/** Custom number formatter — defaults to `Intl.NumberFormat()`. */
|
|
34
|
+
formatNumber?: (n: number) => string;
|
|
35
|
+
labels?: KpiCardLabels;
|
|
36
|
+
className?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Big-number KPI card with optional period-over-period delta. Renders a
|
|
40
|
+
* single value when `previousValue` is null/undefined; otherwise shows the
|
|
41
|
+
* absolute and percentage difference and tints up/down/flat.
|
|
42
|
+
*
|
|
43
|
+
* i18n-unaware: pass localised templates via `labels`. Templates use
|
|
44
|
+
* `{value}` / `{percent}` placeholders which are substituted at render time.
|
|
45
|
+
*/
|
|
46
|
+
export declare function KpiCard({ value, previousValue, formatNumber, labels, className, }: KpiCardProps): React.ReactElement;
|
|
47
|
+
export interface TimeSeriesChartSeries {
|
|
48
|
+
/** Stable key (used for React keys). */
|
|
49
|
+
key: string;
|
|
50
|
+
/** Human-readable label shown in legend / tooltip. */
|
|
51
|
+
label: string;
|
|
52
|
+
/** Aligned points — every series MUST share the same `date` axis (zero-filled upstream). */
|
|
53
|
+
points: ReadonlyArray<{
|
|
54
|
+
date: string;
|
|
55
|
+
value: number;
|
|
56
|
+
}>;
|
|
57
|
+
}
|
|
58
|
+
export interface TimeSeriesChartLabels {
|
|
59
|
+
noData?: string;
|
|
60
|
+
showAll?: string;
|
|
61
|
+
hideAll?: string;
|
|
62
|
+
}
|
|
63
|
+
export type TimeSeriesChartVisualisation = 'area' | 'line' | 'bar';
|
|
64
|
+
export interface TimeSeriesChartProps {
|
|
65
|
+
series: ReadonlyArray<TimeSeriesChartSeries>;
|
|
66
|
+
height?: number;
|
|
67
|
+
/** ISO `YYYY-MM-DD` → short axis tick (e.g. `01.05`). */
|
|
68
|
+
tickFormatter?: (iso: string) => string;
|
|
69
|
+
/** ISO `YYYY-MM-DD` → tooltip header (e.g. `01 May 2024`). */
|
|
70
|
+
labelFormatter?: (iso: string) => string;
|
|
71
|
+
/** Tooltip / Y-axis number formatting. */
|
|
72
|
+
valueFormatter?: (value: number) => string;
|
|
73
|
+
/**
|
|
74
|
+
* Forces a specific Recharts primitive. When omitted, falls back to an
|
|
75
|
+
* auto heuristic: `area` for ≤2 series (single-metric look), `line`
|
|
76
|
+
* for more (multi-series comparison).
|
|
77
|
+
*/
|
|
78
|
+
visualisation?: TimeSeriesChartVisualisation;
|
|
79
|
+
labels?: TimeSeriesChartLabels;
|
|
80
|
+
className?: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Date-axis chart used by dashboard widgets. The Recharts primitive is
|
|
84
|
+
* chosen by `visualisation` (`area` | `line` | `bar`). When the caller
|
|
85
|
+
* does not pass `visualisation` the component falls back to a heuristic:
|
|
86
|
+
* `area` for ≤2 series (single-metric look) and `line` for more
|
|
87
|
+
* (multi-series comparison).
|
|
88
|
+
*
|
|
89
|
+
* Legend is clickable: click a label to toggle that series' visibility;
|
|
90
|
+
* hover dims the rest. When >7 series a "show/hide all" button appears
|
|
91
|
+
* under the chart.
|
|
92
|
+
*
|
|
93
|
+
* Pure presentation — i18n-unaware. Caller supplies pre-aligned, zero-
|
|
94
|
+
* filled `series` plus locale-aware tick/label/value formatters.
|
|
95
|
+
*/
|
|
96
|
+
export declare function TimeSeriesChart({ series, height, tickFormatter, labelFormatter, valueFormatter, visualisation, labels, className, }: TimeSeriesChartProps): React.ReactElement;
|
|
97
|
+
//# sourceMappingURL=chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../src/components/chart.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ResponsiveContainer, LineChart, AreaChart, BarChart, PieChart, Line, Area, Bar, Pie, Cell, XAxis, YAxis, CartesianGrid, Tooltip, Legend, } from 'recharts';
|
|
3
|
+
import { cn } from '../lib/utils.js';
|
|
4
|
+
const PALETTE = [
|
|
5
|
+
'hsl(220, 70%, 55%)',
|
|
6
|
+
'hsl(160, 60%, 45%)',
|
|
7
|
+
'hsl(30, 80%, 55%)',
|
|
8
|
+
'hsl(280, 65%, 60%)',
|
|
9
|
+
'hsl(0, 65%, 55%)',
|
|
10
|
+
];
|
|
11
|
+
const TOOLTIP_STYLE = {
|
|
12
|
+
background: 'var(--card, #fff)',
|
|
13
|
+
border: '1px solid var(--border, #e2e8f0)',
|
|
14
|
+
borderRadius: '6px',
|
|
15
|
+
fontSize: 12,
|
|
16
|
+
padding: '6px 10px',
|
|
17
|
+
};
|
|
18
|
+
const AXIS_STYLE = { fontSize: 11 };
|
|
19
|
+
const GRID_STROKE = 'hsl(215 16% 85%)';
|
|
20
|
+
export function ChartPanel({ data, type = 'line', color = PALETTE[0], height = 260, labels, className, }) {
|
|
21
|
+
if (data.length === 0) {
|
|
22
|
+
return (<div className={cn('flex items-center justify-center text-sm text-muted-foreground', className)} style={{ height }}>
|
|
23
|
+
{labels?.noData ?? 'No data'}
|
|
24
|
+
</div>);
|
|
25
|
+
}
|
|
26
|
+
const vKey = labels?.value ?? 'value';
|
|
27
|
+
const mapped = data.map((d) => ({ label: d.label, [vKey]: d.value }));
|
|
28
|
+
if (type === 'pie') {
|
|
29
|
+
return (<div className={cn('w-full [&_*:focus]:outline-none [&_*:focus-visible]:outline-none', className)} style={{ height }}>
|
|
30
|
+
<ResponsiveContainer width="100%" height="100%">
|
|
31
|
+
<PieChart>
|
|
32
|
+
<Pie data={mapped} dataKey={vKey} nameKey="label" cx="50%" cy="50%" outerRadius="65%">
|
|
33
|
+
{mapped.map((_, i) => (<Cell key={i} fill={PALETTE[i % PALETTE.length]}/>))}
|
|
34
|
+
</Pie>
|
|
35
|
+
<Tooltip contentStyle={TOOLTIP_STYLE} formatter={(value) => [value, vKey]}/>
|
|
36
|
+
</PieChart>
|
|
37
|
+
</ResponsiveContainer>
|
|
38
|
+
</div>);
|
|
39
|
+
}
|
|
40
|
+
const ChartCmp = type === 'area' ? AreaChart : type === 'bar' ? BarChart : LineChart;
|
|
41
|
+
return (<div className={cn('w-full [&_*:focus]:outline-none [&_*:focus-visible]:outline-none', className)} style={{ height }}>
|
|
42
|
+
<ResponsiveContainer width="100%" height="100%">
|
|
43
|
+
<ChartCmp data={mapped} margin={{ top: 8, right: 8, left: -16, bottom: 0 }}>
|
|
44
|
+
<CartesianGrid strokeDasharray="3 3" stroke={GRID_STROKE}/>
|
|
45
|
+
<XAxis dataKey="label" tick={AXIS_STYLE} interval="preserveStartEnd" tickLine={false} axisLine={false}/>
|
|
46
|
+
<YAxis tick={AXIS_STYLE} tickLine={false} axisLine={false}/>
|
|
47
|
+
<Tooltip contentStyle={TOOLTIP_STYLE}/>
|
|
48
|
+
{type === 'area' ? (<Area type="monotone" dataKey={vKey} stroke={color} fill={color} fillOpacity={0.18} strokeWidth={2} dot={false} activeDot={{ r: 4 }}/>) : type === 'bar' ? (<Bar dataKey={vKey} fill={color} radius={[3, 3, 0, 0]} maxBarSize={48}/>) : (<Line type="monotone" dataKey={vKey} stroke={color} strokeWidth={2} dot={false} activeDot={{ r: 4 }}/>)}
|
|
49
|
+
</ChartCmp>
|
|
50
|
+
</ResponsiveContainer>
|
|
51
|
+
</div>);
|
|
52
|
+
}
|
|
53
|
+
const defaultFormat = (n) => new Intl.NumberFormat().format(n);
|
|
54
|
+
const fillTemplate = (tpl, value, percent) => tpl.replace('{value}', value).replace('{percent}', percent);
|
|
55
|
+
/**
|
|
56
|
+
* Big-number KPI card with optional period-over-period delta. Renders a
|
|
57
|
+
* single value when `previousValue` is null/undefined; otherwise shows the
|
|
58
|
+
* absolute and percentage difference and tints up/down/flat.
|
|
59
|
+
*
|
|
60
|
+
* i18n-unaware: pass localised templates via `labels`. Templates use
|
|
61
|
+
* `{value}` / `{percent}` placeholders which are substituted at render time.
|
|
62
|
+
*/
|
|
63
|
+
export function KpiCard({ value, previousValue, formatNumber = defaultFormat, labels, className, }) {
|
|
64
|
+
if (value == null) {
|
|
65
|
+
return (<div className={cn('flex h-32 items-center justify-center text-sm text-muted-foreground', className)}>
|
|
66
|
+
{labels?.noData ?? 'No data'}
|
|
67
|
+
</div>);
|
|
68
|
+
}
|
|
69
|
+
const hasPrev = previousValue != null && Number.isFinite(previousValue);
|
|
70
|
+
const delta = hasPrev ? value - previousValue : 0;
|
|
71
|
+
const percent = hasPrev && previousValue !== 0
|
|
72
|
+
? Math.round((delta / previousValue) * 1000) / 10
|
|
73
|
+
: 0;
|
|
74
|
+
const direction = !hasPrev ? 'flat' : delta > 0 ? 'up' : delta < 0 ? 'down' : 'flat';
|
|
75
|
+
const tone = direction === 'up'
|
|
76
|
+
? 'text-emerald-600 dark:text-emerald-400'
|
|
77
|
+
: direction === 'down'
|
|
78
|
+
? 'text-rose-600 dark:text-rose-400'
|
|
79
|
+
: 'text-muted-foreground';
|
|
80
|
+
const tpl = direction === 'up'
|
|
81
|
+
? labels?.deltaUp ?? '+{value} ({percent}%)'
|
|
82
|
+
: direction === 'down'
|
|
83
|
+
? labels?.deltaDown ?? '−{value} ({percent}%)'
|
|
84
|
+
: labels?.deltaFlat ?? '{value} ({percent}%)';
|
|
85
|
+
return (<div className={cn('flex h-32 flex-col justify-center px-1', className)}>
|
|
86
|
+
<div className="text-3xl font-semibold tabular-nums sm:text-4xl">
|
|
87
|
+
{formatNumber(value)}
|
|
88
|
+
</div>
|
|
89
|
+
{hasPrev && (<div className={cn('mt-2 text-xs sm:text-sm', tone)}>
|
|
90
|
+
<span className="tabular-nums">
|
|
91
|
+
{fillTemplate(tpl, formatNumber(Math.abs(delta)), String(Math.abs(percent)))}
|
|
92
|
+
</span>
|
|
93
|
+
{labels?.previousPeriod && (<span className="ml-1 text-muted-foreground">
|
|
94
|
+
{labels.previousPeriod}
|
|
95
|
+
</span>)}
|
|
96
|
+
</div>)}
|
|
97
|
+
</div>);
|
|
98
|
+
}
|
|
99
|
+
// Six-color HSL palette mirroring the legacy AdminJS dashboard. For >6
|
|
100
|
+
// series we generate evenly-spaced hues so each line stays distinguishable.
|
|
101
|
+
const TS_PALETTE = [
|
|
102
|
+
'hsl(2, 50%, 50%)',
|
|
103
|
+
'hsl(25, 56%, 50%)',
|
|
104
|
+
'hsl(48, 65%, 49%)',
|
|
105
|
+
'hsl(189, 50%, 50%)',
|
|
106
|
+
'hsl(143, 60%, 55%)',
|
|
107
|
+
'hsl(286, 70%, 55%)',
|
|
108
|
+
];
|
|
109
|
+
function paletteFor(n) {
|
|
110
|
+
if (n <= TS_PALETTE.length)
|
|
111
|
+
return TS_PALETTE.slice(0, Math.max(n, 1));
|
|
112
|
+
const stepDeg = Math.floor(360 / n);
|
|
113
|
+
return Array.from({ length: n }, (_, i) => `hsl(${stepDeg * (i + 1)}, 55%, 55%)`);
|
|
114
|
+
}
|
|
115
|
+
const TS_TOOLTIP_STYLE = {
|
|
116
|
+
background: 'hsla(220, 10%, 12%, 0.92)',
|
|
117
|
+
border: '1px solid hsla(220, 10%, 30%, 0.5)',
|
|
118
|
+
borderRadius: 6,
|
|
119
|
+
color: '#fff',
|
|
120
|
+
fontSize: 12,
|
|
121
|
+
padding: '6px 10px',
|
|
122
|
+
};
|
|
123
|
+
const TS_TOOLTIP_LABEL_STYLE = {
|
|
124
|
+
textAlign: 'center',
|
|
125
|
+
color: '#fff',
|
|
126
|
+
marginBottom: 2,
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Date-axis chart used by dashboard widgets. The Recharts primitive is
|
|
130
|
+
* chosen by `visualisation` (`area` | `line` | `bar`). When the caller
|
|
131
|
+
* does not pass `visualisation` the component falls back to a heuristic:
|
|
132
|
+
* `area` for ≤2 series (single-metric look) and `line` for more
|
|
133
|
+
* (multi-series comparison).
|
|
134
|
+
*
|
|
135
|
+
* Legend is clickable: click a label to toggle that series' visibility;
|
|
136
|
+
* hover dims the rest. When >7 series a "show/hide all" button appears
|
|
137
|
+
* under the chart.
|
|
138
|
+
*
|
|
139
|
+
* Pure presentation — i18n-unaware. Caller supplies pre-aligned, zero-
|
|
140
|
+
* filled `series` plus locale-aware tick/label/value formatters.
|
|
141
|
+
*/
|
|
142
|
+
export function TimeSeriesChart({ series, height = 320, tickFormatter, labelFormatter, valueFormatter, visualisation, labels, className, }) {
|
|
143
|
+
const [hovered, setHovered] = React.useState(null);
|
|
144
|
+
const [hidden, setHidden] = React.useState(() => new Set());
|
|
145
|
+
// Merge all series into row-oriented data keyed by date. Memoized so
|
|
146
|
+
// Recharts only sees a new `data` prop when series content actually changes.
|
|
147
|
+
// Uses per-series Maps for O(1) lookup instead of O(N) `.find()` per date.
|
|
148
|
+
const { rows, palette, tickInterval } = React.useMemo(() => {
|
|
149
|
+
const dates = Array.from(new Set(series.flatMap((s) => s.points.map((p) => p.date)))).sort();
|
|
150
|
+
const maps = series.map((s) => new Map(s.points.map((p) => [p.date, p.value])));
|
|
151
|
+
const rows = dates.map((date) => {
|
|
152
|
+
const row = { date };
|
|
153
|
+
series.forEach((s, i) => {
|
|
154
|
+
row[s.key] = maps[i].get(date) ?? 0;
|
|
155
|
+
});
|
|
156
|
+
return row;
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
rows,
|
|
160
|
+
palette: paletteFor(series.length),
|
|
161
|
+
tickInterval: Math.max(0, Math.floor(dates.length / 32)),
|
|
162
|
+
};
|
|
163
|
+
}, [series]);
|
|
164
|
+
if (series.length === 0 || series.every((s) => s.points.length === 0)) {
|
|
165
|
+
return (<div className={cn('flex items-center justify-center text-sm text-muted-foreground', className)} style={{ height }}>
|
|
166
|
+
{labels?.noData ?? 'No data'}
|
|
167
|
+
</div>);
|
|
168
|
+
}
|
|
169
|
+
// Explicit `visualisation` wins; otherwise auto: area for ≤2 series,
|
|
170
|
+
// line for more (preserves legacy behaviour for callers that don't
|
|
171
|
+
// pass `visualisation`).
|
|
172
|
+
const resolvedVis = visualisation ?? (series.length > 2 ? 'line' : 'area');
|
|
173
|
+
const ChartCmp = resolvedVis === 'bar' ? BarChart
|
|
174
|
+
: resolvedVis === 'line' ? LineChart
|
|
175
|
+
: AreaChart;
|
|
176
|
+
// Suppress animation for large datasets — animating thousands of path
|
|
177
|
+
// points is expensive and retains old state in Recharts' animation subsystem.
|
|
178
|
+
const animateChart = rows.length <= 200;
|
|
179
|
+
const toggleHidden = (key) => {
|
|
180
|
+
setHidden((prev) => {
|
|
181
|
+
const next = new Set(prev);
|
|
182
|
+
if (next.has(key))
|
|
183
|
+
next.delete(key);
|
|
184
|
+
else
|
|
185
|
+
next.add(key);
|
|
186
|
+
return next;
|
|
187
|
+
});
|
|
188
|
+
};
|
|
189
|
+
const allHidden = hidden.size === series.length;
|
|
190
|
+
const handleToggleAll = () => {
|
|
191
|
+
setHidden(allHidden ? new Set() : new Set(series.map((s) => s.key)));
|
|
192
|
+
};
|
|
193
|
+
const formatValue = (v) => {
|
|
194
|
+
const n = typeof v === 'number' ? v : Number(v);
|
|
195
|
+
if (!Number.isFinite(n))
|
|
196
|
+
return String(v);
|
|
197
|
+
return valueFormatter ? valueFormatter(n) : new Intl.NumberFormat().format(n);
|
|
198
|
+
};
|
|
199
|
+
return (<div className={cn('w-full [&_*:focus]:outline-none [&_*:focus-visible]:outline-none', className)}>
|
|
200
|
+
<ResponsiveContainer width="100%" height={height}>
|
|
201
|
+
<ChartCmp data={rows} margin={{ top: 16, right: 12, left: -28, bottom: 8 }}>
|
|
202
|
+
<CartesianGrid strokeDasharray="6 6" stroke={GRID_STROKE}/>
|
|
203
|
+
<XAxis dataKey="date" tick={AXIS_STYLE} interval={tickInterval} tickLine={false} axisLine={false} tickFormatter={tickFormatter}/>
|
|
204
|
+
<YAxis tick={AXIS_STYLE} tickLine={false} axisLine={false} tickFormatter={(v) => formatValue(v)} allowDecimals={false}/>
|
|
205
|
+
<Tooltip contentStyle={TS_TOOLTIP_STYLE} labelStyle={TS_TOOLTIP_LABEL_STYLE} itemStyle={{ color: '#fff' }} cursor={{ stroke: 'hsla(0, 0%, 50%, 0.4)', strokeWidth: 1 }} labelFormatter={(value) => labelFormatter ? labelFormatter(String(value)) : String(value)} formatter={(value, name) => [formatValue(value), name]}/>
|
|
206
|
+
<Legend layout="horizontal" align="center" verticalAlign="bottom" wrapperStyle={{ fontSize: 12 }} onClick={(data) => {
|
|
207
|
+
const key = data.dataKey;
|
|
208
|
+
if (key)
|
|
209
|
+
toggleHidden(key);
|
|
210
|
+
}} onMouseEnter={(data) => {
|
|
211
|
+
const key = data.dataKey;
|
|
212
|
+
if (key)
|
|
213
|
+
setHovered(key);
|
|
214
|
+
}} onMouseLeave={() => setHovered(null)}/>
|
|
215
|
+
{series.map((s, i) => {
|
|
216
|
+
if (resolvedVis === 'line') {
|
|
217
|
+
return (<Line key={s.key} type="monotone" dataKey={s.key} name={s.label} stroke={palette[i]} strokeWidth={2} strokeOpacity={hovered === null || hovered === s.key ? 1 : 0.2} dot={false} activeDot={{ r: 4 }} hide={hidden.has(s.key)} isAnimationActive={animateChart} animationDuration={300}/>);
|
|
218
|
+
}
|
|
219
|
+
if (resolvedVis === 'bar') {
|
|
220
|
+
return (<Bar key={s.key} dataKey={s.key} name={s.label} fill={palette[i]} fillOpacity={hovered === null || hovered === s.key ? 1 : 0.25} radius={[3, 3, 0, 0]} maxBarSize={48} hide={hidden.has(s.key)} isAnimationActive={animateChart} animationDuration={300}/>);
|
|
221
|
+
}
|
|
222
|
+
return (<Area key={s.key} type="monotone" dataKey={s.key} name={s.label} stroke={palette[i]} strokeWidth={2} fill={palette[i]} fillOpacity={0.25} dot={false} activeDot={{ r: 4 }} hide={hidden.has(s.key)} isAnimationActive={animateChart} animationDuration={300}/>);
|
|
223
|
+
})}
|
|
224
|
+
</ChartCmp>
|
|
225
|
+
</ResponsiveContainer>
|
|
226
|
+
{series.length > 7 && (<div className="mt-2 flex justify-end">
|
|
227
|
+
<button type="button" onClick={handleToggleAll} className="text-xs text-muted-foreground hover:text-foreground">
|
|
228
|
+
{allHidden ? labels?.showAll ?? 'Show all' : labels?.hideAll ?? 'Hide all'}
|
|
229
|
+
</button>
|
|
230
|
+
</div>)}
|
|
231
|
+
</div>);
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=chart.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart.jsx","sourceRoot":"","sources":["../../src/components/chart.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
3
|
+
export declare const Checkbox: React.ForwardRefExoticComponent<Omit<CheckboxPrimitive.CheckboxProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
4
|
+
//# sourceMappingURL=checkbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../src/components/checkbox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAA;AAI7D,eAAO,MAAM,QAAQ,iKAgBnB,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
3
|
+
import { Check } from 'lucide-react';
|
|
4
|
+
import { cn } from '../lib/utils.js';
|
|
5
|
+
export const Checkbox = React.forwardRef(({ className, ...props }, ref) => (<CheckboxPrimitive.Root ref={ref} className={cn('peer h-4 w-4 cursor-pointer shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground', className)} {...props}>
|
|
6
|
+
<CheckboxPrimitive.Indicator className={cn('flex items-center justify-center text-current')}>
|
|
7
|
+
<Check className="h-3.5 w-3.5"/>
|
|
8
|
+
</CheckboxPrimitive.Indicator>
|
|
9
|
+
</CheckboxPrimitive.Root>));
|
|
10
|
+
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
|
11
|
+
//# sourceMappingURL=checkbox.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkbox.jsx","sourceRoot":"","sources":["../../src/components/checkbox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AACpC,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAA;AAEpC,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAGtC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,CAAC,iBAAiB,CAAC,IAAI,CACrB,GAAG,CAAC,CAAC,GAAG,CAAC,CACT,SAAS,CAAC,CAAC,EAAE,CACX,oVAAoV,EACpV,SAAS,CACV,CAAC,CACF,IAAI,KAAK,CAAC,CAEV;IAAA,CAAC,iBAAiB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,+CAA+C,CAAC,CAAC,CAC1F;MAAA,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa,EAChC;IAAA,EAAE,iBAAiB,CAAC,SAAS,CAC/B;EAAA,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAC1B,CAAC,CAAA;AACF,QAAQ,CAAC,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/** Each suggestion may be a bare string (used as both value + label) or
|
|
3
|
+
* an explicit `{ value, label }` pair. */
|
|
4
|
+
export type ComboboxSuggestion = string | {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
};
|
|
8
|
+
export interface ComboboxLabels {
|
|
9
|
+
/** Shown while `loading` is true and the panel is open. Default: 'Loading…'. */
|
|
10
|
+
loading?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Shown when the panel is open, the user has typed something, but no
|
|
13
|
+
* suggestion matches. Default: 'No matches — press Enter to keep what
|
|
14
|
+
* you typed.' Use `{value}` to interpolate the current input value.
|
|
15
|
+
*/
|
|
16
|
+
noMatches?: string;
|
|
17
|
+
/** Visually-hidden trigger label for screen readers. Default: 'Toggle suggestions'. */
|
|
18
|
+
toggleSuggestions?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ComboboxProps {
|
|
21
|
+
/** Current input value. */
|
|
22
|
+
value: string;
|
|
23
|
+
/** Called on every keystroke and on suggestion pick. */
|
|
24
|
+
onChange(next: string): void;
|
|
25
|
+
/** Called when the input loses focus (after the picker closes). */
|
|
26
|
+
onBlur?(): void;
|
|
27
|
+
/** Static or pre-loaded suggestion list. May change while `loading`. */
|
|
28
|
+
suggestions?: ReadonlyArray<ComboboxSuggestion>;
|
|
29
|
+
/** When true and the panel is open, render a small spinner. */
|
|
30
|
+
loading?: boolean;
|
|
31
|
+
/** Disables the input and prevents the panel from opening. */
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
placeholder?: string;
|
|
34
|
+
/** Forwarded to the `<input>` for accessibility (paired with a `<label>`). */
|
|
35
|
+
id?: string;
|
|
36
|
+
'aria-label'?: string;
|
|
37
|
+
className?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Maximum suggestions to render after filtering. Default: 50. Keeps the
|
|
40
|
+
* panel snappy when callers pass thousands of distinct values.
|
|
41
|
+
*/
|
|
42
|
+
maxItems?: number;
|
|
43
|
+
labels?: ComboboxLabels;
|
|
44
|
+
}
|
|
45
|
+
export declare function Combobox({ value, onChange, onBlur, suggestions, loading, disabled, placeholder, id, 'aria-label': ariaLabel, className, maxItems, labels, }: ComboboxProps): React.ReactElement;
|
|
46
|
+
//# sourceMappingURL=combobox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../src/components/combobox.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAU9B;2CAC2C;AAC3C,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE1E,MAAM,WAAW,cAAc;IAC7B,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,mEAAmE;IACnE,MAAM,CAAC,IAAI,IAAI,CAAA;IACf,wEAAwE;IACxE,WAAW,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAA;IAC/C,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8EAA8E;IAC9E,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB;AAyBD,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,WAAW,EACX,OAAO,EACP,QAAQ,EACR,WAAW,EACX,EAAE,EACF,YAAY,EAAE,SAAS,EACvB,SAAS,EACT,QAAa,EACb,MAAM,GACP,EAAE,aAAa,GAAG,KAAK,CAAC,YAAY,CAoJpC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// Combobox — free-text autocomplete input.
|
|
2
|
+
//
|
|
3
|
+
// Distinct from `ReferenceCombobox` (in @modern-admin/react) which strictly
|
|
4
|
+
// constrains the value to an existing referenced record. This primitive is
|
|
5
|
+
// permissive: the user may type any string, and the suggestion list is
|
|
6
|
+
// purely advisory. Suggestions can be:
|
|
7
|
+
// • static (declared per field, e.g. enum-like hints), or
|
|
8
|
+
// • dynamic (loaded by the parent — e.g. distinct values pulled from a
|
|
9
|
+
// resource's column). The component itself is i18n-unaware and does
|
|
10
|
+
// no fetching: callers feed `suggestions` and toggle `loading`.
|
|
11
|
+
//
|
|
12
|
+
// Behaviour:
|
|
13
|
+
// • The input is fully controlled (`value` / `onChange`).
|
|
14
|
+
// • Suggestions filter as you type: case-insensitive substring match
|
|
15
|
+
// against label and value.
|
|
16
|
+
// • Down/Up cycle highlight; Enter commits the highlighted item or
|
|
17
|
+
// keeps the typed value if none is highlighted.
|
|
18
|
+
// • Escape closes the panel; click-outside closes it (handled by Radix
|
|
19
|
+
// Popover). Selecting an item sets the input value and closes.
|
|
20
|
+
//
|
|
21
|
+
// Mobile-first: the panel matches the input width via the
|
|
22
|
+
// `--radix-popover-trigger-width` CSS var.
|
|
23
|
+
//
|
|
24
|
+
// i18n: optional `labels` prop with English defaults. The React layer is
|
|
25
|
+
// expected to translate and feed them in.
|
|
26
|
+
import * as React from 'react';
|
|
27
|
+
import { ChevronDown, Loader2 } from 'lucide-react';
|
|
28
|
+
import { cn } from '../lib/utils.js';
|
|
29
|
+
import { Input } from './input.js';
|
|
30
|
+
import { Popover, PopoverAnchor, PopoverContent, } from './popover.js';
|
|
31
|
+
const defaultLabels = {
|
|
32
|
+
loading: 'Loading…',
|
|
33
|
+
noMatches: 'No matches — press Enter to keep "{value}".',
|
|
34
|
+
toggleSuggestions: 'Toggle suggestions',
|
|
35
|
+
};
|
|
36
|
+
/** Normalise a `ComboboxSuggestion` into `{ value, label }`. */
|
|
37
|
+
const normalise = (s) => typeof s === 'string' ? { value: s, label: s } : s;
|
|
38
|
+
/** Case-insensitive substring match on label OR value. */
|
|
39
|
+
const matchesQuery = (s, q) => {
|
|
40
|
+
if (!q)
|
|
41
|
+
return true;
|
|
42
|
+
const needle = q.toLowerCase();
|
|
43
|
+
return (s.label.toLowerCase().includes(needle) ||
|
|
44
|
+
s.value.toLowerCase().includes(needle));
|
|
45
|
+
};
|
|
46
|
+
export function Combobox({ value, onChange, onBlur, suggestions, loading, disabled, placeholder, id, 'aria-label': ariaLabel, className, maxItems = 50, labels, }) {
|
|
47
|
+
const l = { ...defaultLabels, ...labels };
|
|
48
|
+
const [focused, setFocused] = React.useState(false);
|
|
49
|
+
const [highlight, setHighlight] = React.useState(0);
|
|
50
|
+
const items = React.useMemo(() => {
|
|
51
|
+
const all = (suggestions ?? []).map(normalise);
|
|
52
|
+
return all.filter((s) => matchesQuery(s, value)).slice(0, maxItems);
|
|
53
|
+
}, [suggestions, value, maxItems]);
|
|
54
|
+
// Reset highlight whenever the filtered set changes — otherwise the
|
|
55
|
+
// index can point past the end after typing a more specific query.
|
|
56
|
+
React.useEffect(() => {
|
|
57
|
+
setHighlight(0);
|
|
58
|
+
}, [items.length]);
|
|
59
|
+
// Open whenever the input is focused AND there's something to show
|
|
60
|
+
// (either matching items or a loading spinner). Empty + non-loading =
|
|
61
|
+
// no panel, so the component degrades to a plain input.
|
|
62
|
+
const open = !disabled && focused && (items.length > 0 || Boolean(loading));
|
|
63
|
+
const commit = (s) => {
|
|
64
|
+
onChange(s.value);
|
|
65
|
+
setFocused(false);
|
|
66
|
+
};
|
|
67
|
+
const handleKeyDown = (e) => {
|
|
68
|
+
if (!open)
|
|
69
|
+
return;
|
|
70
|
+
if (e.key === 'ArrowDown') {
|
|
71
|
+
e.preventDefault();
|
|
72
|
+
setHighlight((h) => Math.min(h + 1, items.length - 1));
|
|
73
|
+
}
|
|
74
|
+
else if (e.key === 'ArrowUp') {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
setHighlight((h) => Math.max(h - 1, 0));
|
|
77
|
+
}
|
|
78
|
+
else if (e.key === 'Enter') {
|
|
79
|
+
const picked = items[highlight];
|
|
80
|
+
if (picked) {
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
commit(picked);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else if (e.key === 'Escape') {
|
|
86
|
+
setFocused(false);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
return (<Popover open={open}>
|
|
90
|
+
<PopoverAnchor asChild>
|
|
91
|
+
<div className={cn('relative', className)}>
|
|
92
|
+
<Input id={id} type="text" value={value} placeholder={placeholder} disabled={disabled} aria-label={ariaLabel} aria-autocomplete="list" aria-expanded={open} autoComplete="off" className="pr-8" onFocus={() => setFocused(true)} onBlur={() => {
|
|
93
|
+
// Defer so a click on a suggestion (which fires after blur)
|
|
94
|
+
// can still commit before we close the panel.
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
setFocused(false);
|
|
97
|
+
onBlur?.();
|
|
98
|
+
}, 120);
|
|
99
|
+
}} onChange={(e) => onChange(e.target.value)} onKeyDown={handleKeyDown}/>
|
|
100
|
+
{/* Trailing affordance: spinner while loading, otherwise a chevron
|
|
101
|
+
hint that suggestions exist. Pure decoration — focusing the
|
|
102
|
+
input is what opens the panel. */}
|
|
103
|
+
<span aria-hidden="true" className="pointer-events-none absolute inset-y-0 right-2 flex items-center text-muted-foreground">
|
|
104
|
+
{loading ? (<Loader2 className="size-4 animate-spin"/>) : (<ChevronDown className="size-4 opacity-50"/>)}
|
|
105
|
+
</span>
|
|
106
|
+
</div>
|
|
107
|
+
</PopoverAnchor>
|
|
108
|
+
<PopoverContent align="start" sideOffset={4}
|
|
109
|
+
// Prevent Radix from stealing focus from the input when the panel
|
|
110
|
+
// opens — otherwise typing would move focus to the popover root.
|
|
111
|
+
onOpenAutoFocus={(e) => e.preventDefault()}
|
|
112
|
+
// Allow clicks inside the panel without closing the popover before
|
|
113
|
+
// the click handler on the option fires.
|
|
114
|
+
onInteractOutside={(e) => {
|
|
115
|
+
// The blur handler closes the panel; nothing more to do here.
|
|
116
|
+
// Preventing the default keeps Radix from re-toggling internal state.
|
|
117
|
+
e.preventDefault();
|
|
118
|
+
}} className="w-[var(--radix-popover-trigger-width)] p-1">
|
|
119
|
+
{loading && items.length === 0 ? (<div className="px-2 py-2 text-sm text-muted-foreground">
|
|
120
|
+
{l.loading}
|
|
121
|
+
</div>) : items.length === 0 ? (<div className="px-2 py-2 text-sm text-muted-foreground">
|
|
122
|
+
{l.noMatches.replace('{value}', value)}
|
|
123
|
+
</div>) : (<ul role="listbox" className="max-h-60 overflow-y-auto">
|
|
124
|
+
{items.map((s, i) => {
|
|
125
|
+
const active = i === highlight;
|
|
126
|
+
return (<li key={s.value} role="option" aria-selected={active}
|
|
127
|
+
// Use mousedown (fires before input blur) so the click
|
|
128
|
+
// commits the value before the panel closes.
|
|
129
|
+
onMouseDown={(e) => {
|
|
130
|
+
e.preventDefault();
|
|
131
|
+
commit(s);
|
|
132
|
+
}} onMouseEnter={() => setHighlight(i)} className={cn('cursor-pointer rounded-sm px-2 py-1.5 text-sm', active
|
|
133
|
+
? 'bg-accent text-accent-foreground'
|
|
134
|
+
: 'text-foreground')}>
|
|
135
|
+
<span className="truncate">{s.label}</span>
|
|
136
|
+
{s.label !== s.value ? (<span className="ml-2 text-xs text-muted-foreground">
|
|
137
|
+
{s.value}
|
|
138
|
+
</span>) : null}
|
|
139
|
+
</li>);
|
|
140
|
+
})}
|
|
141
|
+
</ul>)}
|
|
142
|
+
</PopoverContent>
|
|
143
|
+
</Popover>);
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=combobox.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combobox.jsx","sourceRoot":"","sources":["../../src/components/combobox.tsx"],"names":[],"mappings":"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"}
|