@kala-ui/react-app 0.1.0-beta.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/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/dist/components/app-shell/app-shell.d.ts +54 -0
- package/dist/components/app-shell/app-shell.js +91 -0
- package/dist/components/app-shell/index.d.ts +1 -0
- package/dist/components/app-shell/index.js +2 -0
- package/dist/components/charts/area-chart.d.ts +6 -0
- package/dist/components/charts/area-chart.js +172 -0
- package/dist/components/charts/bar-chart.d.ts +6 -0
- package/dist/components/charts/bar-chart.js +153 -0
- package/dist/components/charts/chart-skeleton.d.ts +36 -0
- package/dist/components/charts/chart-skeleton.js +13 -0
- package/dist/components/charts/chart.d.ts +25 -0
- package/dist/components/charts/chart.js +48 -0
- package/dist/components/charts/chart.types.d.ts +196 -0
- package/dist/components/charts/chart.types.js +6 -0
- package/dist/components/charts/donut-chart.d.ts +7 -0
- package/dist/components/charts/donut-chart.js +146 -0
- package/dist/components/charts/index.d.ts +14 -0
- package/dist/components/charts/index.js +15 -0
- package/dist/components/charts/line-chart.d.ts +6 -0
- package/dist/components/charts/line-chart.js +158 -0
- package/dist/components/charts/radial-bar-chart.d.ts +6 -0
- package/dist/components/charts/radial-bar-chart.js +115 -0
- package/dist/components/charts/theme-utils.d.ts +77 -0
- package/dist/components/charts/theme-utils.js +243 -0
- package/dist/components/charts/use-theme-aware-chart.d.ts +12 -0
- package/dist/components/charts/use-theme-aware-chart.js +68 -0
- package/dist/components/charts/utils.d.ts +56 -0
- package/dist/components/charts/utils.js +135 -0
- package/dist/components/data-table/column-filters.d.ts +14 -0
- package/dist/components/data-table/column-filters.js +51 -0
- package/dist/components/data-table/column-header-filter.d.ts +14 -0
- package/dist/components/data-table/column-header-filter.js +75 -0
- package/dist/components/data-table/data-table-body-rows.d.ts +23 -0
- package/dist/components/data-table/data-table-body-rows.js +43 -0
- package/dist/components/data-table/data-table-filter-chips.d.ts +14 -0
- package/dist/components/data-table/data-table-filter-chips.js +42 -0
- package/dist/components/data-table/data-table-header-row.d.ts +21 -0
- package/dist/components/data-table/data-table-header-row.js +35 -0
- package/dist/components/data-table/data-table-skeleton.d.ts +49 -0
- package/dist/components/data-table/data-table-skeleton.js +32 -0
- package/dist/components/data-table/data-table-toolbar.d.ts +18 -0
- package/dist/components/data-table/data-table-toolbar.js +25 -0
- package/dist/components/data-table/data-table.d.ts +23 -0
- package/dist/components/data-table/data-table.js +250 -0
- package/dist/components/data-table/data-table.types.d.ts +305 -0
- package/dist/components/data-table/data-table.types.js +6 -0
- package/dist/components/data-table/index.d.ts +6 -0
- package/dist/components/data-table/index.js +6 -0
- package/dist/components/data-table/pagination-nav.d.ts +15 -0
- package/dist/components/data-table/pagination-nav.js +23 -0
- package/dist/components/data-table/useTableState.d.ts +29 -0
- package/dist/components/data-table/useTableState.js +312 -0
- package/dist/components/dnd/dnd.d.ts +118 -0
- package/dist/components/dnd/dnd.js +128 -0
- package/dist/components/dnd/index.d.ts +1 -0
- package/dist/components/dnd/index.js +2 -0
- package/dist/components/footer/footer.d.ts +37 -0
- package/dist/components/footer/footer.js +8 -0
- package/dist/components/footer/index.d.ts +2 -0
- package/dist/components/footer/index.js +2 -0
- package/dist/components/header/header-skeleton.d.ts +54 -0
- package/dist/components/header/header-skeleton.js +23 -0
- package/dist/components/header/header.d.ts +40 -0
- package/dist/components/header/header.js +77 -0
- package/dist/components/header/header.types.d.ts +39 -0
- package/dist/components/header/header.types.js +2 -0
- package/dist/components/header/index.d.ts +4 -0
- package/dist/components/header/index.js +3 -0
- package/dist/components/metric-card/index.d.ts +2 -0
- package/dist/components/metric-card/index.js +3 -0
- package/dist/components/metric-card/metric-card-skeleton.d.ts +32 -0
- package/dist/components/metric-card/metric-card-skeleton.js +29 -0
- package/dist/components/metric-card/metric-card.d.ts +16 -0
- package/dist/components/metric-card/metric-card.js +55 -0
- package/dist/components/metric-card/metric-card.types.d.ts +14 -0
- package/dist/components/metric-card/metric-card.types.js +2 -0
- package/dist/components/nav-link/index.d.ts +1 -0
- package/dist/components/nav-link/index.js +2 -0
- package/dist/components/nav-link/nav-link.d.ts +26 -0
- package/dist/components/nav-link/nav-link.js +23 -0
- package/dist/components/navigation/index.d.ts +4 -0
- package/dist/components/navigation/index.js +3 -0
- package/dist/components/navigation/navigation-skeleton.d.ts +54 -0
- package/dist/components/navigation/navigation-skeleton.js +23 -0
- package/dist/components/navigation/navigation.d.ts +26 -0
- package/dist/components/navigation/navigation.js +44 -0
- package/dist/components/session-card/index.d.ts +2 -0
- package/dist/components/session-card/index.js +3 -0
- package/dist/components/session-card/session-card-skeleton.d.ts +31 -0
- package/dist/components/session-card/session-card-skeleton.js +28 -0
- package/dist/components/session-card/session-card.d.ts +27 -0
- package/dist/components/session-card/session-card.js +67 -0
- package/dist/components/sidebar/index.d.ts +3 -0
- package/dist/components/sidebar/index.js +3 -0
- package/dist/components/sidebar/sidebar-skeleton.d.ts +54 -0
- package/dist/components/sidebar/sidebar-skeleton.js +23 -0
- package/dist/components/sidebar/sidebar.d.ts +46 -0
- package/dist/components/sidebar/sidebar.js +69 -0
- package/dist/components/social-login-button/index.d.ts +1 -0
- package/dist/components/social-login-button/index.js +2 -0
- package/dist/components/social-login-button/social-login-button.d.ts +20 -0
- package/dist/components/social-login-button/social-login-button.js +57 -0
- package/dist/components/social-login-buttons/index.d.ts +1 -0
- package/dist/components/social-login-buttons/index.js +2 -0
- package/dist/components/social-login-buttons/social-login-buttons.d.ts +34 -0
- package/dist/components/social-login-buttons/social-login-buttons.js +18 -0
- package/dist/components/sparkline-chart/index.d.ts +2 -0
- package/dist/components/sparkline-chart/index.js +2 -0
- package/dist/components/sparkline-chart/sparkline-chart.d.ts +51 -0
- package/dist/components/sparkline-chart/sparkline-chart.js +134 -0
- package/dist/components/user-menu-dropdown/index.d.ts +1 -0
- package/dist/components/user-menu-dropdown/index.js +2 -0
- package/dist/components/user-menu-dropdown/user-menu-dropdown.d.ts +31 -0
- package/dist/components/user-menu-dropdown/user-menu-dropdown.js +27 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +19 -0
- package/dist/lib/active-path.d.ts +5 -0
- package/dist/lib/active-path.js +12 -0
- package/dist/styles/app.css +2125 -0
- package/package.json +164 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Base Chart Component
|
|
5
|
+
* React component for ApexCharts with built-in loading and empty states
|
|
6
|
+
*/
|
|
7
|
+
import { cn } from "@kala-ui/react/lib/utils";
|
|
8
|
+
import { lazy, Suspense } from "react";
|
|
9
|
+
import { ChartSkeleton } from "./chart-skeleton.js";
|
|
10
|
+
// apexcharts touches `window` at module scope, so importing it statically
|
|
11
|
+
// crashes any SSR framework on the first render — and the root barrel
|
|
12
|
+
// transitively imports every chart. Loaded lazily instead: the module only
|
|
13
|
+
// evaluates in the browser, and the tree stays SSR-safe.
|
|
14
|
+
const ReactApexChart = lazy(() => import("react-apexcharts"));
|
|
15
|
+
/**
|
|
16
|
+
* Get tooltip theme from DOM safely (SSR-compatible)
|
|
17
|
+
*/
|
|
18
|
+
function getTooltipTheme() {
|
|
19
|
+
if (typeof document === "undefined")
|
|
20
|
+
return "light";
|
|
21
|
+
return document.documentElement.classList.contains("dark") ? "dark" : "light";
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Base Chart Component - use this as the foundation for all charts
|
|
25
|
+
* Provides consistent styling, loading skeleton, and empty state
|
|
26
|
+
*/
|
|
27
|
+
export function Chart({ className, isLoading, isEmpty, emptyMessage = "No data available", skeletonConfig, skeleton, ...props }) {
|
|
28
|
+
// Render skeleton if loading
|
|
29
|
+
if (isLoading) {
|
|
30
|
+
if (skeleton) {
|
|
31
|
+
return _jsx(_Fragment, { children: skeleton });
|
|
32
|
+
}
|
|
33
|
+
return _jsx(ChartSkeleton, { ...(skeletonConfig || {}), className: className });
|
|
34
|
+
}
|
|
35
|
+
// Render empty state when no data
|
|
36
|
+
if (isEmpty) {
|
|
37
|
+
// Height may arrive as a number (px) or a CSS length string ("20rem",
|
|
38
|
+
// "50%") — appending px to a string double-unitizes it.
|
|
39
|
+
const configuredHeight = skeletonConfig?.height ?? props.height ?? 350;
|
|
40
|
+
const height = typeof configuredHeight === "number"
|
|
41
|
+
? `${configuredHeight}px`
|
|
42
|
+
: configuredHeight;
|
|
43
|
+
return (_jsxs("div", { className: cn("w-full flex flex-col items-center justify-center text-center rounded-lg border bg-card text-muted-foreground", className), style: { height }, children: [_jsxs("svg", { className: "mb-3 h-10 w-10 opacity-40", fill: "none", role: "img", "aria-label": "Chart empty state", stroke: "currentColor", viewBox: "0 0 24 24", children: [_jsx("title", { children: "No chart data" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 13h2v8H3zM9 9h2v12H9zM15 5h2v16h-2zM21 1h2v20h-2z" })] }), _jsx("p", { className: "text-sm", children: emptyMessage })] }));
|
|
44
|
+
}
|
|
45
|
+
return (_jsx("div", { className: cn("w-full", className), children: _jsx(Suspense, { fallback: skeleton ?? (_jsx(ChartSkeleton, { ...(skeletonConfig || {}), className: className })), children: _jsx(ReactApexChart, { ...props }) }) }));
|
|
46
|
+
}
|
|
47
|
+
export { ChartSkeleton } from "./chart-skeleton.js";
|
|
48
|
+
export { getTooltipTheme };
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chart Component Types
|
|
3
|
+
* Type definitions for ApexCharts-based chart components
|
|
4
|
+
*/
|
|
5
|
+
import type { ApexOptions } from "apexcharts";
|
|
6
|
+
/**
|
|
7
|
+
* Base chart props shared across all chart types
|
|
8
|
+
*/
|
|
9
|
+
export interface BaseChartProps {
|
|
10
|
+
/** Chart height in pixels */
|
|
11
|
+
height?: number;
|
|
12
|
+
/** Chart width (100% by default) */
|
|
13
|
+
width?: string | number;
|
|
14
|
+
/** Custom CSS classes */
|
|
15
|
+
className?: string;
|
|
16
|
+
/** Chart title */
|
|
17
|
+
title?: string;
|
|
18
|
+
/** Chart subtitle */
|
|
19
|
+
subtitle?: string;
|
|
20
|
+
/** Show/hide toolbar */
|
|
21
|
+
toolbar?: boolean;
|
|
22
|
+
/** Enable/disable animations */
|
|
23
|
+
animations?: boolean;
|
|
24
|
+
/** Custom ApexCharts options (merged with defaults) */
|
|
25
|
+
options?: Partial<ApexOptions>;
|
|
26
|
+
/** Show loading skeleton instead of chart */
|
|
27
|
+
isLoading?: boolean;
|
|
28
|
+
/** Message shown when data is empty (default: "No data available") */
|
|
29
|
+
emptyMessage?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Series data point for single value charts
|
|
33
|
+
*/
|
|
34
|
+
export interface ChartDataPoint {
|
|
35
|
+
/** X-axis value (date, category, etc.) */
|
|
36
|
+
x: string | number;
|
|
37
|
+
/** Y-axis value */
|
|
38
|
+
y: number;
|
|
39
|
+
/** Optional fill color for this point */
|
|
40
|
+
fillColor?: string;
|
|
41
|
+
/** Optional stroke color for this point */
|
|
42
|
+
strokeColor?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Series configuration for charts
|
|
46
|
+
*/
|
|
47
|
+
export interface ChartSeries {
|
|
48
|
+
/** Series name */
|
|
49
|
+
name: string;
|
|
50
|
+
/** Series data points */
|
|
51
|
+
data: number[] | ChartDataPoint[];
|
|
52
|
+
/** Series color (hex or CSS variable) */
|
|
53
|
+
color?: string;
|
|
54
|
+
/** Series type (for mixed charts) */
|
|
55
|
+
type?: "line" | "area" | "bar" | "column";
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Area Chart specific props
|
|
59
|
+
*/
|
|
60
|
+
export interface AreaChartProps extends BaseChartProps {
|
|
61
|
+
/** Chart series data */
|
|
62
|
+
series: ChartSeries[];
|
|
63
|
+
/** X-axis categories (if not using data points) */
|
|
64
|
+
categories?: string[];
|
|
65
|
+
/** Chart colors */
|
|
66
|
+
colors?: string[];
|
|
67
|
+
/** Curve style */
|
|
68
|
+
curve?: "smooth" | "straight" | "stepline";
|
|
69
|
+
/** Enable stacked mode */
|
|
70
|
+
stacked?: boolean;
|
|
71
|
+
/** Show data labels */
|
|
72
|
+
dataLabels?: boolean;
|
|
73
|
+
/** Y-axis label */
|
|
74
|
+
yAxisLabel?: string;
|
|
75
|
+
/** Reference lines (e.g., limits, targets) */
|
|
76
|
+
referenceLines?: ReferenceLine[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Line Chart specific props
|
|
80
|
+
*/
|
|
81
|
+
export interface LineChartProps extends BaseChartProps {
|
|
82
|
+
/** Chart series data */
|
|
83
|
+
series: ChartSeries[];
|
|
84
|
+
/** X-axis categories */
|
|
85
|
+
categories?: string[];
|
|
86
|
+
/** Chart colors */
|
|
87
|
+
colors?: string[];
|
|
88
|
+
/** Curve style */
|
|
89
|
+
curve?: "smooth" | "straight" | "stepline";
|
|
90
|
+
/** Line width */
|
|
91
|
+
strokeWidth?: number;
|
|
92
|
+
/** Show markers on data points */
|
|
93
|
+
markers?: boolean;
|
|
94
|
+
/** Y-axis label */
|
|
95
|
+
yAxisLabel?: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Bar Chart specific props
|
|
99
|
+
*/
|
|
100
|
+
export interface BarChartProps extends BaseChartProps {
|
|
101
|
+
/** Chart series data */
|
|
102
|
+
series: ChartSeries[];
|
|
103
|
+
/** X-axis categories */
|
|
104
|
+
categories: string[];
|
|
105
|
+
/** Chart colors */
|
|
106
|
+
colors?: string[];
|
|
107
|
+
/** Horizontal bars */
|
|
108
|
+
horizontal?: boolean;
|
|
109
|
+
/** Enable stacked mode */
|
|
110
|
+
stacked?: boolean;
|
|
111
|
+
/** Show data labels */
|
|
112
|
+
dataLabels?: boolean;
|
|
113
|
+
/** Bar width percentage */
|
|
114
|
+
barWidth?: number;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Donut/Pie Chart specific props
|
|
118
|
+
*/
|
|
119
|
+
export interface DonutChartProps extends BaseChartProps {
|
|
120
|
+
/** Chart labels */
|
|
121
|
+
labels: string[];
|
|
122
|
+
/** Chart data values */
|
|
123
|
+
series: number[];
|
|
124
|
+
/** Chart colors */
|
|
125
|
+
colors?: string[];
|
|
126
|
+
/** Show as donut (true) or pie (false) */
|
|
127
|
+
donut?: boolean;
|
|
128
|
+
/** Donut hole size (10-90) */
|
|
129
|
+
donutSize?: number;
|
|
130
|
+
/** Show data labels */
|
|
131
|
+
dataLabels?: boolean;
|
|
132
|
+
/** Show legend */
|
|
133
|
+
legend?: boolean;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Radial Bar Chart specific props
|
|
137
|
+
*/
|
|
138
|
+
export interface RadialBarChartProps extends BaseChartProps {
|
|
139
|
+
/** Series labels */
|
|
140
|
+
labels: string[];
|
|
141
|
+
/** Series values (percentages 0-100) */
|
|
142
|
+
series: number[];
|
|
143
|
+
/** Chart colors */
|
|
144
|
+
colors?: string[];
|
|
145
|
+
/** Show data labels */
|
|
146
|
+
dataLabels?: boolean;
|
|
147
|
+
/** Hollow size percentage */
|
|
148
|
+
hollowSize?: string;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Reference line configuration
|
|
152
|
+
*/
|
|
153
|
+
export interface ReferenceLine {
|
|
154
|
+
/** Y-axis value for the line */
|
|
155
|
+
value: number;
|
|
156
|
+
/** Line color */
|
|
157
|
+
color?: string;
|
|
158
|
+
/** Line style */
|
|
159
|
+
dashArray?: number;
|
|
160
|
+
/** Line label */
|
|
161
|
+
label?: string;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Theme configuration for charts
|
|
165
|
+
*/
|
|
166
|
+
export interface ChartTheme {
|
|
167
|
+
/** Color palette */
|
|
168
|
+
palette: "palette1" | "palette2" | "palette3" | "palette4" | "palette5";
|
|
169
|
+
/** Light or dark mode */
|
|
170
|
+
mode: "light" | "dark";
|
|
171
|
+
/** Monochrome colors */
|
|
172
|
+
monochrome?: {
|
|
173
|
+
enabled: boolean;
|
|
174
|
+
color: string;
|
|
175
|
+
shadeTo: "light" | "dark";
|
|
176
|
+
shadeIntensity: number;
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Chart Skeleton Configuration
|
|
181
|
+
* Configuration for chart loading states
|
|
182
|
+
*/
|
|
183
|
+
export interface ChartSkeletonConfig {
|
|
184
|
+
/** Height of the chart area (default: 350) */
|
|
185
|
+
height?: number;
|
|
186
|
+
/** Show legend skeleton (default: true) */
|
|
187
|
+
showLegend?: boolean;
|
|
188
|
+
/** Number of legend items to show (default: 4) */
|
|
189
|
+
legendCount?: number;
|
|
190
|
+
/** Show table skeleton below chart */
|
|
191
|
+
showTable?: boolean;
|
|
192
|
+
/** Number of table rows to show (default: 5) */
|
|
193
|
+
tableRows?: number;
|
|
194
|
+
/** Number of table columns to show (default: 3) */
|
|
195
|
+
tableColumns?: number;
|
|
196
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Donut/Pie Chart Component
|
|
3
|
+
* Circular charts for showing proportions and percentages
|
|
4
|
+
*/
|
|
5
|
+
import type { DonutChartProps } from "./chart.types";
|
|
6
|
+
export declare function DonutChart({ series, labels, colors, height, width, className, title, subtitle, animations, donut, donutSize, dataLabels, legend, isLoading, emptyMessage, options: customOptions, }: DonutChartProps): import("react").JSX.Element;
|
|
7
|
+
export declare function PieChart(props: DonutChartProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/**
|
|
3
|
+
* Donut/Pie Chart Component
|
|
4
|
+
* Circular charts for showing proportions and percentages
|
|
5
|
+
*/
|
|
6
|
+
"use client";
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
import { cn } from "@kala-ui/react/lib/utils";
|
|
9
|
+
import { useMemo } from "react";
|
|
10
|
+
import { Chart, getTooltipTheme } from "./chart.js";
|
|
11
|
+
import { useThemeAwareChart } from "./use-theme-aware-chart.js";
|
|
12
|
+
import { getDefaultChartOptions } from "./utils.js";
|
|
13
|
+
export function DonutChart({ series, labels, colors, height = 350, width = "100%", className, title, subtitle, animations = true, donut = true, donutSize = 65, dataLabels = true, legend = true, isLoading, emptyMessage, options: customOptions, }) {
|
|
14
|
+
const { colors: themeColors } = useThemeAwareChart();
|
|
15
|
+
const isEmpty = !isLoading && (series.length === 0 || labels.length === 0);
|
|
16
|
+
const chartOptions = useMemo(() => {
|
|
17
|
+
const baseOptions = getDefaultChartOptions();
|
|
18
|
+
// Use theme-aware colors if not provided
|
|
19
|
+
const chartColors = colors || themeColors.mixed;
|
|
20
|
+
const options = {
|
|
21
|
+
...baseOptions,
|
|
22
|
+
chart: {
|
|
23
|
+
...baseOptions.chart,
|
|
24
|
+
type: donut ? "donut" : "pie",
|
|
25
|
+
animations: {
|
|
26
|
+
enabled: animations,
|
|
27
|
+
speed: 800,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
colors: chartColors,
|
|
31
|
+
labels,
|
|
32
|
+
dataLabels: {
|
|
33
|
+
enabled: dataLabels,
|
|
34
|
+
style: {
|
|
35
|
+
fontSize: "14px",
|
|
36
|
+
fontWeight: 600,
|
|
37
|
+
colors: ["var(--primary-foreground)"],
|
|
38
|
+
},
|
|
39
|
+
dropShadow: {
|
|
40
|
+
enabled: false,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
plotOptions: {
|
|
44
|
+
pie: {
|
|
45
|
+
...(donut && {
|
|
46
|
+
donut: {
|
|
47
|
+
size: `${donutSize}%`,
|
|
48
|
+
labels: {
|
|
49
|
+
show: true,
|
|
50
|
+
name: {
|
|
51
|
+
show: true,
|
|
52
|
+
fontSize: "16px",
|
|
53
|
+
fontWeight: 600,
|
|
54
|
+
color: "var(--foreground)",
|
|
55
|
+
},
|
|
56
|
+
value: {
|
|
57
|
+
show: true,
|
|
58
|
+
fontSize: "24px",
|
|
59
|
+
fontWeight: 700,
|
|
60
|
+
color: "var(--foreground)",
|
|
61
|
+
formatter: (value) => parseInt(value, 10).toLocaleString(),
|
|
62
|
+
},
|
|
63
|
+
total: {
|
|
64
|
+
show: true,
|
|
65
|
+
label: "Total",
|
|
66
|
+
fontSize: "14px",
|
|
67
|
+
color: "var(--muted-foreground)",
|
|
68
|
+
formatter: (w) => {
|
|
69
|
+
return w.globals.seriesTotals
|
|
70
|
+
.reduce((a, b) => a + b, 0)
|
|
71
|
+
.toLocaleString();
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
legend: {
|
|
80
|
+
show: legend,
|
|
81
|
+
position: "bottom",
|
|
82
|
+
horizontalAlign: "center",
|
|
83
|
+
labels: {
|
|
84
|
+
colors: "var(--foreground)",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
tooltip: {
|
|
88
|
+
theme: getTooltipTheme(),
|
|
89
|
+
y: {
|
|
90
|
+
formatter: (value) => value.toLocaleString(),
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
responsive: [
|
|
94
|
+
{
|
|
95
|
+
breakpoint: 480,
|
|
96
|
+
options: {
|
|
97
|
+
chart: {
|
|
98
|
+
height: 300,
|
|
99
|
+
},
|
|
100
|
+
legend: {
|
|
101
|
+
position: "bottom",
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
...(title && {
|
|
107
|
+
title: {
|
|
108
|
+
text: title,
|
|
109
|
+
style: {
|
|
110
|
+
fontSize: "16px",
|
|
111
|
+
fontWeight: "600",
|
|
112
|
+
color: "var(--foreground)",
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
}),
|
|
116
|
+
...(subtitle && {
|
|
117
|
+
subtitle: {
|
|
118
|
+
text: subtitle,
|
|
119
|
+
style: {
|
|
120
|
+
fontSize: "12px",
|
|
121
|
+
color: "var(--muted-foreground)",
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
}),
|
|
125
|
+
...customOptions,
|
|
126
|
+
};
|
|
127
|
+
return options;
|
|
128
|
+
}, [
|
|
129
|
+
colors,
|
|
130
|
+
themeColors,
|
|
131
|
+
labels,
|
|
132
|
+
donut,
|
|
133
|
+
donutSize,
|
|
134
|
+
dataLabels,
|
|
135
|
+
legend,
|
|
136
|
+
animations,
|
|
137
|
+
title,
|
|
138
|
+
subtitle,
|
|
139
|
+
customOptions,
|
|
140
|
+
]);
|
|
141
|
+
return (_jsx(Chart, { className: cn("w-full", className), options: chartOptions, series: series, type: donut ? "donut" : "pie", height: height, width: width, isLoading: isLoading, isEmpty: isEmpty, emptyMessage: emptyMessage }));
|
|
142
|
+
}
|
|
143
|
+
// Convenience alias for Pie charts
|
|
144
|
+
export function PieChart(props) {
|
|
145
|
+
return _jsx(DonutChart, { ...props, donut: false });
|
|
146
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Charts Package
|
|
3
|
+
* ApexCharts-based chart components for data visualization
|
|
4
|
+
*/
|
|
5
|
+
export { AreaChart } from "./area-chart";
|
|
6
|
+
export { BarChart } from "./bar-chart";
|
|
7
|
+
export { Chart, ChartSkeleton } from "./chart";
|
|
8
|
+
export * from "./chart.types";
|
|
9
|
+
export { DonutChart, PieChart } from "./donut-chart";
|
|
10
|
+
export { LineChart } from "./line-chart";
|
|
11
|
+
export { RadialBarChart } from "./radial-bar-chart";
|
|
12
|
+
export * from "./theme-utils";
|
|
13
|
+
export { useThemeAwareChart } from "./use-theme-aware-chart";
|
|
14
|
+
export * from "./utils";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/**
|
|
3
|
+
* Charts Package
|
|
4
|
+
* ApexCharts-based chart components for data visualization
|
|
5
|
+
*/
|
|
6
|
+
export { AreaChart } from "./area-chart.js";
|
|
7
|
+
export { BarChart } from "./bar-chart.js";
|
|
8
|
+
export { Chart, ChartSkeleton } from "./chart.js";
|
|
9
|
+
export * from "./chart.types.js";
|
|
10
|
+
export { DonutChart, PieChart } from "./donut-chart.js";
|
|
11
|
+
export { LineChart } from "./line-chart.js";
|
|
12
|
+
export { RadialBarChart } from "./radial-bar-chart.js";
|
|
13
|
+
export * from "./theme-utils.js";
|
|
14
|
+
export { useThemeAwareChart } from "./use-theme-aware-chart.js";
|
|
15
|
+
export * from "./utils.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Line Chart Component
|
|
3
|
+
* Clean line charts for trends and time series data
|
|
4
|
+
*/
|
|
5
|
+
import type { LineChartProps } from "./chart.types";
|
|
6
|
+
export declare function LineChart({ series, categories, colors, height, width, className, title, subtitle, toolbar, animations, curve, strokeWidth, markers, yAxisLabel, isLoading, emptyMessage, options: customOptions, }: LineChartProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/**
|
|
3
|
+
* Line Chart Component
|
|
4
|
+
* Clean line charts for trends and time series data
|
|
5
|
+
*/
|
|
6
|
+
"use client";
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
import { cn } from "@kala-ui/react/lib/utils";
|
|
9
|
+
import { useMemo } from "react";
|
|
10
|
+
import { Chart, getTooltipTheme } from "./chart.js";
|
|
11
|
+
import { useThemeAwareChart } from "./use-theme-aware-chart.js";
|
|
12
|
+
import { getDefaultChartOptions } from "./utils.js";
|
|
13
|
+
/**
|
|
14
|
+
* Check if series data is empty (no series or all series have empty data arrays)
|
|
15
|
+
*/
|
|
16
|
+
function isSeriesEmpty(series) {
|
|
17
|
+
if (series.length === 0)
|
|
18
|
+
return true;
|
|
19
|
+
return series.every((s) => !s.data || (Array.isArray(s.data) && s.data.length === 0));
|
|
20
|
+
}
|
|
21
|
+
export function LineChart({ series, categories, colors, height = 350, width = "100%", className, title, subtitle, toolbar = false, animations = true, curve = "smooth", strokeWidth = 2, markers = true, yAxisLabel, isLoading, emptyMessage, options: customOptions, }) {
|
|
22
|
+
const { colors: themeColors } = useThemeAwareChart();
|
|
23
|
+
const isEmpty = !isLoading && isSeriesEmpty(series);
|
|
24
|
+
const chartOptions = useMemo(() => {
|
|
25
|
+
const baseOptions = getDefaultChartOptions();
|
|
26
|
+
// Use theme-aware colors if not provided
|
|
27
|
+
const chartColors = colors || themeColors.mixed;
|
|
28
|
+
const options = {
|
|
29
|
+
...baseOptions,
|
|
30
|
+
chart: {
|
|
31
|
+
...baseOptions.chart,
|
|
32
|
+
type: "line",
|
|
33
|
+
toolbar: {
|
|
34
|
+
show: toolbar,
|
|
35
|
+
tools: {
|
|
36
|
+
download: true,
|
|
37
|
+
selection: true,
|
|
38
|
+
zoom: true,
|
|
39
|
+
zoomin: true,
|
|
40
|
+
zoomout: true,
|
|
41
|
+
pan: true,
|
|
42
|
+
reset: true,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
animations: {
|
|
46
|
+
enabled: animations,
|
|
47
|
+
speed: 800,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
colors: chartColors,
|
|
51
|
+
dataLabels: {
|
|
52
|
+
enabled: false,
|
|
53
|
+
},
|
|
54
|
+
stroke: {
|
|
55
|
+
curve,
|
|
56
|
+
width: strokeWidth,
|
|
57
|
+
},
|
|
58
|
+
markers: {
|
|
59
|
+
size: markers ? 4 : 0,
|
|
60
|
+
strokeWidth: 2,
|
|
61
|
+
strokeOpacity: 0.9,
|
|
62
|
+
strokeColors: chartColors,
|
|
63
|
+
fillOpacity: 1,
|
|
64
|
+
hover: {
|
|
65
|
+
size: 6,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
xaxis: {
|
|
69
|
+
categories,
|
|
70
|
+
labels: {
|
|
71
|
+
style: {
|
|
72
|
+
colors: "var(--muted-foreground)",
|
|
73
|
+
fontSize: "12px",
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
axisBorder: {
|
|
77
|
+
color: "var(--border)",
|
|
78
|
+
},
|
|
79
|
+
axisTicks: {
|
|
80
|
+
color: "var(--border)",
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
yaxis: {
|
|
84
|
+
...(yAxisLabel && {
|
|
85
|
+
title: {
|
|
86
|
+
text: yAxisLabel,
|
|
87
|
+
style: {
|
|
88
|
+
color: "var(--muted-foreground)",
|
|
89
|
+
fontSize: "12px",
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
}),
|
|
93
|
+
labels: {
|
|
94
|
+
style: {
|
|
95
|
+
colors: "var(--muted-foreground)",
|
|
96
|
+
fontSize: "12px",
|
|
97
|
+
},
|
|
98
|
+
formatter: (value) => value.toLocaleString(),
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
grid: {
|
|
102
|
+
borderColor: "var(--border)",
|
|
103
|
+
strokeDashArray: 3,
|
|
104
|
+
},
|
|
105
|
+
tooltip: {
|
|
106
|
+
theme: getTooltipTheme(),
|
|
107
|
+
x: {
|
|
108
|
+
show: true,
|
|
109
|
+
},
|
|
110
|
+
y: {
|
|
111
|
+
formatter: (value) => value.toLocaleString(),
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
legend: {
|
|
115
|
+
position: "top",
|
|
116
|
+
horizontalAlign: "right",
|
|
117
|
+
labels: {
|
|
118
|
+
colors: "var(--foreground)",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
...(title && {
|
|
122
|
+
title: {
|
|
123
|
+
text: title,
|
|
124
|
+
style: {
|
|
125
|
+
fontSize: "16px",
|
|
126
|
+
fontWeight: "600",
|
|
127
|
+
color: "var(--foreground)",
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
}),
|
|
131
|
+
...(subtitle && {
|
|
132
|
+
subtitle: {
|
|
133
|
+
text: subtitle,
|
|
134
|
+
style: {
|
|
135
|
+
fontSize: "12px",
|
|
136
|
+
color: "var(--muted-foreground)",
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
}),
|
|
140
|
+
...customOptions,
|
|
141
|
+
};
|
|
142
|
+
return options;
|
|
143
|
+
}, [
|
|
144
|
+
colors,
|
|
145
|
+
themeColors,
|
|
146
|
+
categories,
|
|
147
|
+
curve,
|
|
148
|
+
strokeWidth,
|
|
149
|
+
markers,
|
|
150
|
+
yAxisLabel,
|
|
151
|
+
toolbar,
|
|
152
|
+
animations,
|
|
153
|
+
title,
|
|
154
|
+
subtitle,
|
|
155
|
+
customOptions,
|
|
156
|
+
]);
|
|
157
|
+
return (_jsx(Chart, { className: cn("w-full", className), options: chartOptions, series: series, type: "line", height: height, width: width, isLoading: isLoading, isEmpty: isEmpty, emptyMessage: emptyMessage }));
|
|
158
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Radial Bar Chart Component
|
|
3
|
+
* Circular progress bars for showing percentages and completion rates
|
|
4
|
+
*/
|
|
5
|
+
import type { RadialBarChartProps } from "./chart.types";
|
|
6
|
+
export declare function RadialBarChart({ series, labels, colors, height, width, className, title, subtitle, animations, dataLabels, hollowSize, isLoading, emptyMessage, options: customOptions, }: RadialBarChartProps): import("react").JSX.Element;
|