@squadbase/vantage 0.0.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/LICENSE +21 -0
- package/README.md +95 -0
- package/dist/chunk-73J5ZD4C.js +96 -0
- package/dist/chunk-73J5ZD4C.js.map +1 -0
- package/dist/chunk-ATYZ45XL.js +19 -0
- package/dist/chunk-ATYZ45XL.js.map +1 -0
- package/dist/chunk-B7LLBNLV.js +23 -0
- package/dist/chunk-B7LLBNLV.js.map +1 -0
- package/dist/chunk-ZGDU5YLH.js +753 -0
- package/dist/chunk-ZGDU5YLH.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +765 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/index.d.ts +45 -0
- package/dist/client/index.js +141 -0
- package/dist/client/index.js.map +1 -0
- package/dist/define-page-B6y9TOfZ.d.ts +44 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/query/index.d.ts +11 -0
- package/dist/query/index.js +4 -0
- package/dist/query/index.js.map +1 -0
- package/dist/router/index.d.ts +36 -0
- package/dist/router/index.js +27 -0
- package/dist/router/index.js.map +1 -0
- package/dist/server/index.d.ts +53 -0
- package/dist/server/index.js +3 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/node.d.ts +35 -0
- package/dist/server/node.js +84 -0
- package/dist/server/node.js.map +1 -0
- package/dist/ui/index.d.ts +217 -0
- package/dist/ui/index.js +616 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/vite/index.d.ts +15 -0
- package/dist/vite/index.js +5 -0
- package/dist/vite/index.js.map +1 -0
- package/package.json +108 -0
- package/registry/blocks/sales-overview.tsx +37 -0
- package/registry/ui/data-table.tsx +115 -0
- package/theme.css +101 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ApiModule } from './index.js';
|
|
2
|
+
|
|
3
|
+
/** A parsed path segment of a page or API route. */
|
|
4
|
+
type Segment = {
|
|
5
|
+
kind: "static";
|
|
6
|
+
value: string;
|
|
7
|
+
} | {
|
|
8
|
+
kind: "param";
|
|
9
|
+
name: string;
|
|
10
|
+
} | {
|
|
11
|
+
kind: "catchall";
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** A statically-imported API route for the production server. */
|
|
16
|
+
interface ProdApiRoute {
|
|
17
|
+
routePath: string;
|
|
18
|
+
segments: Segment[];
|
|
19
|
+
module: ApiModule;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Start the production Node server: API routes first, then static client
|
|
23
|
+
* assets, then SPA fallback to index.html. Runtime-agnostic Hono keeps the door
|
|
24
|
+
* open for future Bun/Deno/Workers adapters.
|
|
25
|
+
*/
|
|
26
|
+
declare function startNodeServer(opts: {
|
|
27
|
+
apiRoutes: ProdApiRoute[];
|
|
28
|
+
/** Absolute path to the built client directory (dist/client). */
|
|
29
|
+
clientDir: string;
|
|
30
|
+
port?: number;
|
|
31
|
+
}): void;
|
|
32
|
+
/** Resolve a path relative to this module (used by generated entry). */
|
|
33
|
+
declare function resolveFromEntry(entryUrl: string, ...segments: string[]): string;
|
|
34
|
+
|
|
35
|
+
export { type ProdApiRoute, resolveFromEntry, startNodeServer };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { sortApiRoutes, matchApiRoute, dispatchApi } from '../chunk-73J5ZD4C.js';
|
|
2
|
+
import '../chunk-B7LLBNLV.js';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { Hono } from 'hono';
|
|
7
|
+
import { serve } from '@hono/node-server';
|
|
8
|
+
|
|
9
|
+
// @squadbase/vantage — generated build. Do not edit.
|
|
10
|
+
var MIME = {
|
|
11
|
+
".html": "text/html; charset=utf-8",
|
|
12
|
+
".js": "text/javascript; charset=utf-8",
|
|
13
|
+
".mjs": "text/javascript; charset=utf-8",
|
|
14
|
+
".css": "text/css; charset=utf-8",
|
|
15
|
+
".json": "application/json; charset=utf-8",
|
|
16
|
+
".svg": "image/svg+xml",
|
|
17
|
+
".png": "image/png",
|
|
18
|
+
".jpg": "image/jpeg",
|
|
19
|
+
".jpeg": "image/jpeg",
|
|
20
|
+
".gif": "image/gif",
|
|
21
|
+
".webp": "image/webp",
|
|
22
|
+
".ico": "image/x-icon",
|
|
23
|
+
".woff": "font/woff",
|
|
24
|
+
".woff2": "font/woff2",
|
|
25
|
+
".map": "application/json; charset=utf-8"
|
|
26
|
+
};
|
|
27
|
+
function startNodeServer(opts) {
|
|
28
|
+
const { clientDir } = opts;
|
|
29
|
+
const indexHtml = path.join(clientDir, "index.html");
|
|
30
|
+
const env = { ...process.env };
|
|
31
|
+
const routes = sortApiRoutes(
|
|
32
|
+
opts.apiRoutes.map((r) => ({
|
|
33
|
+
routePath: r.routePath,
|
|
34
|
+
segments: r.segments,
|
|
35
|
+
hasCatchall: r.segments.some((s) => s.kind === "catchall"),
|
|
36
|
+
staticCount: r.segments.filter((s) => s.kind === "static").length,
|
|
37
|
+
load: async () => r.module
|
|
38
|
+
}))
|
|
39
|
+
);
|
|
40
|
+
const app = new Hono();
|
|
41
|
+
const apiHandler = async (c) => {
|
|
42
|
+
const url = new URL(c.req.url);
|
|
43
|
+
const match = matchApiRoute(routes, url.pathname);
|
|
44
|
+
if (!match) return Response.json({ error: "Not Found", path: url.pathname }, { status: 404 });
|
|
45
|
+
const mod = await match.route.load();
|
|
46
|
+
return dispatchApi(mod, c.req.raw, match.params, env);
|
|
47
|
+
};
|
|
48
|
+
app.all("/api", apiHandler);
|
|
49
|
+
app.all("/api/*", apiHandler);
|
|
50
|
+
app.get("/*", (c) => {
|
|
51
|
+
const url = new URL(c.req.url);
|
|
52
|
+
const filePath = safeJoin(clientDir, url.pathname);
|
|
53
|
+
if (filePath && fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
|
|
54
|
+
const ext = path.extname(filePath);
|
|
55
|
+
const body = fs.readFileSync(filePath);
|
|
56
|
+
return new Response(body, { headers: { "content-type": MIME[ext] ?? "application/octet-stream" } });
|
|
57
|
+
}
|
|
58
|
+
if (fs.existsSync(indexHtml)) {
|
|
59
|
+
return new Response(fs.readFileSync(indexHtml), { headers: { "content-type": MIME[".html"] } });
|
|
60
|
+
}
|
|
61
|
+
return new Response("Not Found", { status: 404 });
|
|
62
|
+
});
|
|
63
|
+
const port = opts.port ?? Number(process.env.PORT ?? 3e3);
|
|
64
|
+
serve({ fetch: app.fetch, port }, (info) => {
|
|
65
|
+
console.log(`[vantage] server listening on http://localhost:${info.port}`);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function safeJoin(root, urlPath) {
|
|
69
|
+
const decoded = decodeURIComponent(urlPath.split("?")[0]);
|
|
70
|
+
const joined = path.join(root, decoded);
|
|
71
|
+
const normalizedRoot = path.resolve(root);
|
|
72
|
+
const normalizedJoined = path.resolve(joined);
|
|
73
|
+
if (normalizedJoined !== normalizedRoot && !normalizedJoined.startsWith(normalizedRoot + path.sep)) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
return normalizedJoined;
|
|
77
|
+
}
|
|
78
|
+
function resolveFromEntry(entryUrl, ...segments) {
|
|
79
|
+
return path.resolve(path.dirname(fileURLToPath(entryUrl)), ...segments);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export { resolveFromEntry, startNodeServer };
|
|
83
|
+
//# sourceMappingURL=node.js.map
|
|
84
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/server/node.ts"],"names":[],"mappings":"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","file":"node.js","sourcesContent":["import fs from \"node:fs\"\nimport path from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport { Hono } from \"hono\"\nimport { serve } from \"@hono/node-server\"\nimport type { Segment } from \"../core/types.js\"\nimport { dispatchApi, matchApiRoute, sortApiRoutes } from \"./dispatch.js\"\nimport type { ApiModule } from \"./index.js\"\n\n/** A statically-imported API route for the production server. */\nexport interface ProdApiRoute {\n routePath: string\n segments: Segment[]\n module: ApiModule\n}\n\nconst MIME: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"text/javascript; charset=utf-8\",\n \".mjs\": \"text/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".svg\": \"image/svg+xml\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".map\": \"application/json; charset=utf-8\",\n}\n\n/**\n * Start the production Node server: API routes first, then static client\n * assets, then SPA fallback to index.html. Runtime-agnostic Hono keeps the door\n * open for future Bun/Deno/Workers adapters.\n */\nexport function startNodeServer(opts: {\n apiRoutes: ProdApiRoute[]\n /** Absolute path to the built client directory (dist/client). */\n clientDir: string\n port?: number\n}): void {\n const { clientDir } = opts\n const indexHtml = path.join(clientDir, \"index.html\")\n const env = { ...process.env }\n\n const routes = sortApiRoutes(\n opts.apiRoutes.map((r) => ({\n routePath: r.routePath,\n segments: r.segments,\n hasCatchall: r.segments.some((s) => s.kind === \"catchall\"),\n staticCount: r.segments.filter((s) => s.kind === \"static\").length,\n load: async () => r.module,\n })),\n )\n\n const app = new Hono()\n\n const apiHandler = async (c: { req: { url: string; raw: Request } }) => {\n const url = new URL(c.req.url)\n const match = matchApiRoute(routes, url.pathname)\n if (!match) return Response.json({ error: \"Not Found\", path: url.pathname }, { status: 404 })\n const mod = await match.route.load()\n return dispatchApi(mod, c.req.raw, match.params, env)\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n app.all(\"/api\", apiHandler as any)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n app.all(\"/api/*\", apiHandler as any)\n\n // Static assets + SPA fallback.\n app.get(\"/*\", (c) => {\n const url = new URL(c.req.url)\n const filePath = safeJoin(clientDir, url.pathname)\n if (filePath && fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {\n const ext = path.extname(filePath)\n const body = fs.readFileSync(filePath)\n return new Response(body, { headers: { \"content-type\": MIME[ext] ?? \"application/octet-stream\" } })\n }\n if (fs.existsSync(indexHtml)) {\n return new Response(fs.readFileSync(indexHtml), { headers: { \"content-type\": MIME[\".html\"]! } })\n }\n return new Response(\"Not Found\", { status: 404 })\n })\n\n const port = opts.port ?? Number(process.env.PORT ?? 3000)\n serve({ fetch: app.fetch, port }, (info) => {\n // eslint-disable-next-line no-console\n console.log(`[vantage] server listening on http://localhost:${info.port}`)\n })\n}\n\n/** Prevent path traversal outside the client dir. */\nfunction safeJoin(root: string, urlPath: string): string | null {\n const decoded = decodeURIComponent(urlPath.split(\"?\")[0]!)\n const joined = path.join(root, decoded)\n const normalizedRoot = path.resolve(root)\n const normalizedJoined = path.resolve(joined)\n if (normalizedJoined !== normalizedRoot && !normalizedJoined.startsWith(normalizedRoot + path.sep)) {\n return null\n }\n return normalizedJoined\n}\n\n/** Resolve a path relative to this module (used by generated entry). */\nexport function resolveFromEntry(entryUrl: string, ...segments: string[]): string {\n return path.resolve(path.dirname(fileURLToPath(entryUrl)), ...segments)\n}\n"]}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ButtonHTMLAttributes, InputHTMLAttributes, SelectHTMLAttributes, HTMLAttributes, ReactNode, TdHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
/** Join class values, dropping falsy entries. Small, dependency-free. */
|
|
5
|
+
type ClassValue = string | number | false | null | undefined;
|
|
6
|
+
declare function cn(...classes: ClassValue[]): string;
|
|
7
|
+
|
|
8
|
+
type ButtonVariant = "default" | "secondary" | "outline" | "ghost" | "destructive";
|
|
9
|
+
type ButtonSize = "sm" | "default" | "lg" | "icon";
|
|
10
|
+
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
11
|
+
variant?: ButtonVariant;
|
|
12
|
+
size?: ButtonSize;
|
|
13
|
+
}
|
|
14
|
+
declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
15
|
+
|
|
16
|
+
declare const Input: react.ForwardRefExoticComponent<InputHTMLAttributes<HTMLInputElement> & react.RefAttributes<HTMLInputElement>>;
|
|
17
|
+
interface SelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
|
|
18
|
+
options?: {
|
|
19
|
+
label: string;
|
|
20
|
+
value: string;
|
|
21
|
+
}[];
|
|
22
|
+
}
|
|
23
|
+
declare const Select: react.ForwardRefExoticComponent<SelectProps & react.RefAttributes<HTMLSelectElement>>;
|
|
24
|
+
interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
|
|
25
|
+
label?: string;
|
|
26
|
+
}
|
|
27
|
+
declare const Checkbox: react.ForwardRefExoticComponent<CheckboxProps & react.RefAttributes<HTMLInputElement>>;
|
|
28
|
+
|
|
29
|
+
type Div = HTMLAttributes<HTMLDivElement>;
|
|
30
|
+
declare function Card({ className, ...props }: Div): react.JSX.Element;
|
|
31
|
+
declare function CardHeader({ className, ...props }: Div): react.JSX.Element;
|
|
32
|
+
declare function CardTitle({ className, ...props }: HTMLAttributes<HTMLHeadingElement>): react.JSX.Element;
|
|
33
|
+
declare function CardDescription({ className, ...props }: HTMLAttributes<HTMLParagraphElement>): react.JSX.Element;
|
|
34
|
+
declare function CardContent({ className, ...props }: Div): react.JSX.Element;
|
|
35
|
+
declare function CardFooter({ className, ...props }: Div): react.JSX.Element;
|
|
36
|
+
|
|
37
|
+
interface TabsProps {
|
|
38
|
+
defaultValue: string;
|
|
39
|
+
value?: string;
|
|
40
|
+
onValueChange?: (v: string) => void;
|
|
41
|
+
className?: string;
|
|
42
|
+
children: ReactNode;
|
|
43
|
+
}
|
|
44
|
+
declare function Tabs({ defaultValue, value, onValueChange, className, children }: TabsProps): react.JSX.Element;
|
|
45
|
+
declare function TabsList({ className, children }: {
|
|
46
|
+
className?: string;
|
|
47
|
+
children: ReactNode;
|
|
48
|
+
}): react.JSX.Element;
|
|
49
|
+
declare function TabsTrigger({ value, children }: {
|
|
50
|
+
value: string;
|
|
51
|
+
children: ReactNode;
|
|
52
|
+
}): react.JSX.Element;
|
|
53
|
+
declare function TabsContent({ value, className, children }: {
|
|
54
|
+
value: string;
|
|
55
|
+
className?: string;
|
|
56
|
+
children: ReactNode;
|
|
57
|
+
}): react.JSX.Element | null;
|
|
58
|
+
|
|
59
|
+
declare function Table({ className, ...props }: HTMLAttributes<HTMLTableElement>): react.JSX.Element;
|
|
60
|
+
declare function TableHeader(props: HTMLAttributes<HTMLTableSectionElement>): react.JSX.Element;
|
|
61
|
+
declare function TableBody(props: HTMLAttributes<HTMLTableSectionElement>): react.JSX.Element;
|
|
62
|
+
declare function TableRow({ className, ...props }: HTMLAttributes<HTMLTableRowElement>): react.JSX.Element;
|
|
63
|
+
declare function TableHead({ className, ...props }: HTMLAttributes<HTMLTableCellElement>): react.JSX.Element;
|
|
64
|
+
declare function TableCell({ className, ...props }: TdHTMLAttributes<HTMLTableCellElement>): react.JSX.Element;
|
|
65
|
+
interface Column<T> {
|
|
66
|
+
key: string;
|
|
67
|
+
header: string;
|
|
68
|
+
render?: (row: T) => ReactNode;
|
|
69
|
+
sortable?: boolean;
|
|
70
|
+
align?: "left" | "right" | "center";
|
|
71
|
+
accessor?: (row: T) => string | number;
|
|
72
|
+
}
|
|
73
|
+
interface DataTableProps<T> {
|
|
74
|
+
columns: Column<T>[];
|
|
75
|
+
data: T[];
|
|
76
|
+
pageSize?: number;
|
|
77
|
+
getRowId?: (row: T, index: number) => string;
|
|
78
|
+
empty?: ReactNode;
|
|
79
|
+
className?: string;
|
|
80
|
+
}
|
|
81
|
+
declare function DataTable<T extends Record<string, unknown>>({ columns, data, pageSize, getRowId, empty, className, }: DataTableProps<T>): react.JSX.Element;
|
|
82
|
+
interface PaginationProps {
|
|
83
|
+
page: number;
|
|
84
|
+
pageCount: number;
|
|
85
|
+
total?: number;
|
|
86
|
+
onPageChange: (page: number) => void;
|
|
87
|
+
}
|
|
88
|
+
declare function Pagination({ page, pageCount, total, onPageChange }: PaginationProps): react.JSX.Element;
|
|
89
|
+
|
|
90
|
+
interface MetricCardProps {
|
|
91
|
+
label: string;
|
|
92
|
+
value: ReactNode;
|
|
93
|
+
delta?: number;
|
|
94
|
+
deltaLabel?: string;
|
|
95
|
+
icon?: ReactNode;
|
|
96
|
+
className?: string;
|
|
97
|
+
}
|
|
98
|
+
/** A KPI tile: label, big value, and an optional trend delta. */
|
|
99
|
+
declare function MetricCard({ label, value, delta, deltaLabel, icon, className }: MetricCardProps): react.JSX.Element;
|
|
100
|
+
|
|
101
|
+
interface FilterBarProps extends HTMLAttributes<HTMLDivElement> {
|
|
102
|
+
children: ReactNode;
|
|
103
|
+
}
|
|
104
|
+
/** A responsive row of filter controls. */
|
|
105
|
+
declare function FilterBar({ className, children, ...props }: FilterBarProps): react.JSX.Element;
|
|
106
|
+
declare function FilterField({ label, children }: {
|
|
107
|
+
label: string;
|
|
108
|
+
children: ReactNode;
|
|
109
|
+
}): react.JSX.Element;
|
|
110
|
+
|
|
111
|
+
interface DashboardShellProps {
|
|
112
|
+
title?: ReactNode;
|
|
113
|
+
description?: ReactNode;
|
|
114
|
+
actions?: ReactNode;
|
|
115
|
+
nav?: ReactNode;
|
|
116
|
+
children: ReactNode;
|
|
117
|
+
className?: string;
|
|
118
|
+
}
|
|
119
|
+
/** Page-level layout: sticky header with title/actions, then content. */
|
|
120
|
+
declare function DashboardShell({ title, description, actions, nav, children, className }: DashboardShellProps): react.JSX.Element;
|
|
121
|
+
|
|
122
|
+
declare function Loading({ label, className }: {
|
|
123
|
+
label?: string;
|
|
124
|
+
className?: string;
|
|
125
|
+
}): react.JSX.Element;
|
|
126
|
+
declare function Empty({ title, description, icon, action, className, }: {
|
|
127
|
+
title?: string;
|
|
128
|
+
description?: string;
|
|
129
|
+
icon?: ReactNode;
|
|
130
|
+
action?: ReactNode;
|
|
131
|
+
className?: string;
|
|
132
|
+
}): react.JSX.Element;
|
|
133
|
+
declare function ErrorState({ title, message, action, className, }: {
|
|
134
|
+
title?: string;
|
|
135
|
+
message?: ReactNode;
|
|
136
|
+
action?: ReactNode;
|
|
137
|
+
className?: string;
|
|
138
|
+
}): react.JSX.Element;
|
|
139
|
+
|
|
140
|
+
interface DatePickerProps {
|
|
141
|
+
value?: string;
|
|
142
|
+
onChange?: (value: string) => void;
|
|
143
|
+
min?: string;
|
|
144
|
+
max?: string;
|
|
145
|
+
className?: string;
|
|
146
|
+
id?: string;
|
|
147
|
+
}
|
|
148
|
+
/** Single date field (native, no external dependency). */
|
|
149
|
+
declare function DatePicker({ value, onChange, min, max, className, id }: DatePickerProps): react.JSX.Element;
|
|
150
|
+
interface DateRange {
|
|
151
|
+
from: string;
|
|
152
|
+
to: string;
|
|
153
|
+
}
|
|
154
|
+
interface DateRangePickerProps {
|
|
155
|
+
value?: DateRange;
|
|
156
|
+
onChange?: (value: DateRange) => void;
|
|
157
|
+
className?: string;
|
|
158
|
+
}
|
|
159
|
+
/** Two coupled date fields representing an inclusive range. */
|
|
160
|
+
declare function DateRangePicker({ value, onChange, className }: DateRangePickerProps): react.JSX.Element;
|
|
161
|
+
|
|
162
|
+
interface Series {
|
|
163
|
+
key: string;
|
|
164
|
+
label?: string;
|
|
165
|
+
color?: string;
|
|
166
|
+
}
|
|
167
|
+
declare function ChartContainer({ children, className, height, }: {
|
|
168
|
+
children: ReactNode;
|
|
169
|
+
className?: string;
|
|
170
|
+
height?: number;
|
|
171
|
+
}): react.JSX.Element;
|
|
172
|
+
declare function ChartLegend({ series }: {
|
|
173
|
+
series: Series[];
|
|
174
|
+
}): react.JSX.Element;
|
|
175
|
+
declare function ChartTooltip({ children, className }: {
|
|
176
|
+
children: ReactNode;
|
|
177
|
+
className?: string;
|
|
178
|
+
}): react.JSX.Element;
|
|
179
|
+
interface BaseChartProps<T> {
|
|
180
|
+
data: T[];
|
|
181
|
+
categoryKey: string;
|
|
182
|
+
series: Series[];
|
|
183
|
+
height?: number;
|
|
184
|
+
className?: string;
|
|
185
|
+
}
|
|
186
|
+
/** Minimal dependency-free grouped bar chart. */
|
|
187
|
+
declare function BarChart<T extends Record<string, unknown>>({ data, categoryKey, series, height, className, }: BaseChartProps<T>): react.JSX.Element;
|
|
188
|
+
/** Minimal dependency-free multi-series line chart. */
|
|
189
|
+
declare function LineChart<T extends Record<string, unknown>>({ data, categoryKey, series, height, className, }: BaseChartProps<T>): react.JSX.Element;
|
|
190
|
+
|
|
191
|
+
interface DialogProps {
|
|
192
|
+
open: boolean;
|
|
193
|
+
onClose: () => void;
|
|
194
|
+
title?: ReactNode;
|
|
195
|
+
description?: ReactNode;
|
|
196
|
+
children?: ReactNode;
|
|
197
|
+
footer?: ReactNode;
|
|
198
|
+
className?: string;
|
|
199
|
+
}
|
|
200
|
+
/** A lightweight modal dialog (no external UI dependency). */
|
|
201
|
+
declare function Dialog({ open, onClose, title, description, children, footer, className }: DialogProps): react.JSX.Element | null;
|
|
202
|
+
|
|
203
|
+
interface DropdownItem {
|
|
204
|
+
label: ReactNode;
|
|
205
|
+
onSelect?: () => void;
|
|
206
|
+
disabled?: boolean;
|
|
207
|
+
}
|
|
208
|
+
interface DropdownMenuProps {
|
|
209
|
+
trigger: ReactNode;
|
|
210
|
+
items: DropdownItem[];
|
|
211
|
+
align?: "start" | "end";
|
|
212
|
+
className?: string;
|
|
213
|
+
}
|
|
214
|
+
/** A simple click-to-open dropdown menu with outside-click dismissal. */
|
|
215
|
+
declare function DropdownMenu({ trigger, items, align, className }: DropdownMenuProps): react.JSX.Element;
|
|
216
|
+
|
|
217
|
+
export { BarChart, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChartContainer, ChartLegend, ChartTooltip, Checkbox, type CheckboxProps, type ClassValue, type Column, DashboardShell, type DashboardShellProps, DataTable, type DataTableProps, DatePicker, type DatePickerProps, type DateRange, DateRangePicker, type DateRangePickerProps, Dialog, type DialogProps, type DropdownItem, DropdownMenu, type DropdownMenuProps, Empty, ErrorState, FilterBar, type FilterBarProps, FilterField, Input, LineChart, Loading, MetricCard, type MetricCardProps, Pagination, type PaginationProps, Select, type SelectProps, type Series, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, type TabsProps, TabsTrigger, cn };
|