@olympusoss/canvas 2.20.1 → 4.0.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/package.json +41 -177
- package/src/cn.ts +3 -0
- package/src/index.ts +12 -603
- package/src/theme.ts +41 -0
- package/src/tokens.ts +11 -0
- package/styles/base.css +17 -0
- package/styles/canvas.css +69 -52
- package/styles/components/alert.css +66 -0
- package/styles/components/app-shell.css +46 -0
- package/styles/components/avatar.css +15 -0
- package/styles/components/badge.css +83 -0
- package/styles/components/breadcrumb.css +35 -0
- package/styles/components/button-group.css +23 -0
- package/styles/components/button.css +107 -0
- package/styles/components/calendar.css +73 -0
- package/styles/components/card.css +58 -0
- package/styles/components/checkbox.css +55 -0
- package/styles/components/code-block.css +18 -0
- package/styles/components/combobox.css +75 -0
- package/styles/components/command.css +94 -0
- package/styles/components/data-table.css +142 -0
- package/styles/components/dialog.css +72 -0
- package/styles/components/dropdown.css +54 -0
- package/styles/components/empty-state.css +17 -0
- package/styles/components/field.css +27 -0
- package/styles/components/filter-panel.css +58 -0
- package/styles/components/form.css +27 -0
- package/styles/components/icon.css +8 -0
- package/styles/components/input-group.css +45 -0
- package/styles/components/input.css +56 -0
- package/styles/components/kbd.css +15 -0
- package/styles/components/page-header.css +52 -0
- package/styles/components/pagination.css +48 -0
- package/styles/components/popover.css +14 -0
- package/styles/components/radio.css +28 -0
- package/styles/components/row-menu.css +69 -0
- package/styles/components/section-card.css +49 -0
- package/styles/components/select.css +57 -0
- package/styles/components/separator.css +32 -0
- package/styles/components/sheet.css +70 -0
- package/styles/components/sidebar.css +146 -0
- package/styles/components/skeleton.css +32 -0
- package/styles/components/spinner.css +26 -0
- package/styles/components/stat-card.css +71 -0
- package/styles/components/stepper.css +63 -0
- package/styles/components/switch.css +45 -0
- package/styles/components/tabs.css +40 -0
- package/styles/components/textarea.css +31 -0
- package/styles/components/toast.css +95 -0
- package/styles/components/tooltip.css +53 -0
- package/styles/components/topbar.css +24 -0
- package/styles/components/typography.css +105 -0
- package/styles/patterns/backdrops.css +35 -0
- package/styles/patterns/density.css +66 -0
- package/styles/patterns/focus.css +38 -0
- package/styles/patterns/glass.css +85 -0
- package/styles/patterns/high-contrast.css +70 -0
- package/styles/patterns/reduced-motion.css +12 -0
- package/styles/patterns/scrollbar.css +10 -0
- package/styles/reset.css +89 -0
- package/styles/tokens/colors.css +106 -0
- package/styles/tokens/motion.css +33 -0
- package/styles/tokens/radius.css +10 -0
- package/styles/tokens/shadows.css +35 -0
- package/styles/tokens/spacing.css +19 -0
- package/styles/tokens/typography.css +6 -0
- package/styles/tokens/z-index.css +12 -0
- package/tsconfig.json +20 -21
- package/README.md +0 -60
- package/src/components/atoms/README.md +0 -11
- package/src/components/atoms/aspect-ratio.tsx +0 -32
- package/src/components/atoms/avatar.tsx +0 -98
- package/src/components/atoms/badge.tsx +0 -44
- package/src/components/atoms/brand-mark.tsx +0 -74
- package/src/components/atoms/button.tsx +0 -105
- package/src/components/atoms/checkbox.tsx +0 -63
- package/src/components/atoms/flex-box.tsx +0 -105
- package/src/components/atoms/icon.tsx +0 -34
- package/src/components/atoms/input.tsx +0 -92
- package/src/components/atoms/label.tsx +0 -41
- package/src/components/atoms/logo.tsx +0 -89
- package/src/components/atoms/progress.tsx +0 -55
- package/src/components/atoms/radio-group.tsx +0 -122
- package/src/components/atoms/scroll-area.tsx +0 -106
- package/src/components/atoms/section.tsx +0 -48
- package/src/components/atoms/separator.tsx +0 -45
- package/src/components/atoms/skeleton.tsx +0 -17
- package/src/components/atoms/slider.tsx +0 -93
- package/src/components/atoms/spinner.tsx +0 -47
- package/src/components/atoms/switch.tsx +0 -60
- package/src/components/atoms/textarea.tsx +0 -78
- package/src/components/atoms/toggle.tsx +0 -80
- package/src/components/charts/activity-heatmap.tsx +0 -186
- package/src/components/charts/axes.tsx +0 -21
- package/src/components/charts/chart-container.tsx +0 -254
- package/src/components/charts/chart-legend.tsx +0 -67
- package/src/components/charts/chart-tooltip.tsx +0 -161
- package/src/components/charts/chart-types.tsx +0 -49
- package/src/components/charts/containers.tsx +0 -11
- package/src/components/charts/data.tsx +0 -16
- package/src/components/charts/details.tsx +0 -25
- package/src/components/charts/dot-pulse.tsx +0 -61
- package/src/components/charts/gauge.tsx +0 -106
- package/src/components/charts/grids.tsx +0 -8
- package/src/components/charts/index.ts +0 -62
- package/src/components/charts/labeled-bar-list.tsx +0 -85
- package/src/components/charts/metric-breakdown.tsx +0 -316
- package/src/components/charts/references.tsx +0 -8
- package/src/components/charts/service-health-list.tsx +0 -85
- package/src/components/charts/sparkline-area.tsx +0 -80
- package/src/components/charts/sparkline.tsx +0 -52
- package/src/components/charts/stacked-bar.tsx +0 -104
- package/src/components/charts/text.tsx +0 -10
- package/src/components/charts/world-heat-map-inner.tsx +0 -317
- package/src/components/charts/world-heat-map.tsx +0 -184
- package/src/components/molecules/README.md +0 -12
- package/src/components/molecules/action-bar.tsx +0 -73
- package/src/components/molecules/activity-item.tsx +0 -74
- package/src/components/molecules/alert.tsx +0 -86
- package/src/components/molecules/animated-background.tsx +0 -92
- package/src/components/molecules/auth-shell.tsx +0 -95
- package/src/components/molecules/brand-lockup.tsx +0 -48
- package/src/components/molecules/breadcrumb.tsx +0 -157
- package/src/components/molecules/button-group.tsx +0 -104
- package/src/components/molecules/calendar.tsx +0 -217
- package/src/components/molecules/card.tsx +0 -102
- package/src/components/molecules/client-brand.tsx +0 -95
- package/src/components/molecules/code-block.tsx +0 -86
- package/src/components/molecules/countdown-button.tsx +0 -92
- package/src/components/molecules/empty-state.tsx +0 -56
- package/src/components/molecules/error-state.tsx +0 -42
- package/src/components/molecules/field-display.tsx +0 -35
- package/src/components/molecules/input-otp.tsx +0 -74
- package/src/components/molecules/launcher-card.tsx +0 -152
- package/src/components/molecules/loading-state.tsx +0 -36
- package/src/components/molecules/notification-item.tsx +0 -67
- package/src/components/molecules/notification-list.tsx +0 -45
- package/src/components/molecules/number-badge.tsx +0 -53
- package/src/components/molecules/or-separator.tsx +0 -38
- package/src/components/molecules/page-header.tsx +0 -88
- package/src/components/molecules/page-tabs.tsx +0 -94
- package/src/components/molecules/pagination.tsx +0 -150
- package/src/components/molecules/password-input.tsx +0 -83
- package/src/components/molecules/password-strength-meter.tsx +0 -104
- package/src/components/molecules/phone-input.tsx +0 -200
- package/src/components/molecules/search-bar.tsx +0 -64
- package/src/components/molecules/secret-field.tsx +0 -158
- package/src/components/molecules/section-card.tsx +0 -91
- package/src/components/molecules/social-buttons.tsx +0 -165
- package/src/components/molecules/stat-card.tsx +0 -100
- package/src/components/molecules/status-badge.tsx +0 -42
- package/src/components/molecules/stepper.tsx +0 -96
- package/src/components/molecules/table.tsx +0 -157
- package/src/components/molecules/terminal.tsx +0 -74
- package/src/components/molecules/toggle-group.tsx +0 -145
- package/src/components/molecules/tooltip.tsx +0 -155
- package/src/components/molecules/user-avatar-chip.tsx +0 -71
- package/src/components/organisms/README.md +0 -14
- package/src/components/organisms/accordion.tsx +0 -154
- package/src/components/organisms/alert-dialog.tsx +0 -277
- package/src/components/organisms/carousel.tsx +0 -244
- package/src/components/organisms/collapsible.tsx +0 -69
- package/src/components/organisms/command.tsx +0 -144
- package/src/components/organisms/context-menu.tsx +0 -339
- package/src/components/organisms/dashboard-grid.tsx +0 -369
- package/src/components/organisms/data-table.tsx +0 -330
- package/src/components/organisms/dialog.tsx +0 -312
- package/src/components/organisms/drawer.tsx +0 -123
- package/src/components/organisms/dropdown-menu.tsx +0 -440
- package/src/components/organisms/editors/code-editor.tsx +0 -144
- package/src/components/organisms/editors/index.ts +0 -4
- package/src/components/organisms/editors/markdown-editor.tsx +0 -153
- package/src/components/organisms/editors/markdown-renderer.ts +0 -27
- package/src/components/organisms/editors/prose-canvas-classes.ts +0 -45
- package/src/components/organisms/editors/rich-text-editor.tsx +0 -126
- package/src/components/organisms/editors/toolbar/md-toolbar.tsx +0 -129
- package/src/components/organisms/editors/toolbar/rte-toolbar.tsx +0 -211
- package/src/components/organisms/editors/toolbar/toolbar-shell.tsx +0 -45
- package/src/components/organisms/editors/use-codemirror-theme.ts +0 -61
- package/src/components/organisms/error-boundary.tsx +0 -61
- package/src/components/organisms/form.tsx +0 -174
- package/src/components/organisms/hover-card.tsx +0 -115
- package/src/components/organisms/menubar.tsx +0 -498
- package/src/components/organisms/navbar.tsx +0 -104
- package/src/components/organisms/navigation-menu.tsx +0 -235
- package/src/components/organisms/popover.tsx +0 -149
- package/src/components/organisms/resizable.tsx +0 -58
- package/src/components/organisms/schema-form.tsx +0 -232
- package/src/components/organisms/select.tsx +0 -309
- package/src/components/organisms/sheet.tsx +0 -265
- package/src/components/organisms/sidebar.tsx +0 -1040
- package/src/components/organisms/sonner.tsx +0 -96
- package/src/components/organisms/tabs.tsx +0 -133
- package/src/components/organisms/theme-provider.tsx +0 -101
- package/src/hooks/use-mobile.tsx +0 -19
- package/src/lib/portal-container.tsx +0 -35
- package/src/lib/utils.ts +0 -6
- package/src/native.ts +0 -23
- package/src/tokens/colors.ts +0 -91
- package/src/tokens/index.ts +0 -3
- package/src/tokens/spacing.ts +0 -55
- package/src/tokens/typography.ts +0 -27
- package/styles/dashboard-grid.css +0 -47
- package/styles/fonts/Roboto-VariableFont_wdth_wght.ttf +0 -0
- package/styles/glass.css +0 -171
- package/styles/leaflet.css +0 -13
- package/styles/tokens.css +0 -317
- package/tailwind.config.ts +0 -70
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import * as RechartsPrimitive from "recharts";
|
|
5
|
-
|
|
6
|
-
import { cn } from "../../lib/utils";
|
|
7
|
-
import { getPayloadConfigFromPayload, useChart } from "./chart-container";
|
|
8
|
-
|
|
9
|
-
const ChartTooltip = RechartsPrimitive.Tooltip;
|
|
10
|
-
|
|
11
|
-
const ChartTooltipContent = React.forwardRef<
|
|
12
|
-
HTMLDivElement,
|
|
13
|
-
React.ComponentProps<typeof RechartsPrimitive.Tooltip> &
|
|
14
|
-
React.ComponentProps<"div"> & {
|
|
15
|
-
hideLabel?: boolean;
|
|
16
|
-
hideIndicator?: boolean;
|
|
17
|
-
indicator?: "line" | "dot" | "dashed";
|
|
18
|
-
nameKey?: string;
|
|
19
|
-
labelKey?: string;
|
|
20
|
-
}
|
|
21
|
-
>(
|
|
22
|
-
(
|
|
23
|
-
{
|
|
24
|
-
active,
|
|
25
|
-
payload,
|
|
26
|
-
className,
|
|
27
|
-
indicator = "dot",
|
|
28
|
-
hideLabel = false,
|
|
29
|
-
hideIndicator = false,
|
|
30
|
-
label,
|
|
31
|
-
labelFormatter,
|
|
32
|
-
labelClassName,
|
|
33
|
-
formatter,
|
|
34
|
-
color,
|
|
35
|
-
nameKey,
|
|
36
|
-
labelKey,
|
|
37
|
-
},
|
|
38
|
-
ref,
|
|
39
|
-
) => {
|
|
40
|
-
const { config } = useChart();
|
|
41
|
-
|
|
42
|
-
const tooltipLabel = React.useMemo(() => {
|
|
43
|
-
if (hideLabel || !payload?.length) {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const [item] = payload;
|
|
48
|
-
/* c8 ignore next -- the || chain prefers labelKey when set; the remaining fallbacks are recharts-internal edge cases */
|
|
49
|
-
const key = `${labelKey || item?.dataKey || item?.name || "value"}`;
|
|
50
|
-
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
51
|
-
const value =
|
|
52
|
-
!labelKey && typeof label === "string"
|
|
53
|
-
? config[label as keyof typeof config]?.label || label
|
|
54
|
-
: itemConfig?.label;
|
|
55
|
-
|
|
56
|
-
if (labelFormatter) {
|
|
57
|
-
return (
|
|
58
|
-
<div className={cn("font-medium", labelClassName)}>{labelFormatter(value, payload)}</div>
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/* c8 ignore next 3 -- defensive fallback: value is always truthy when this branch is reached in practice */
|
|
63
|
-
if (!value) {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return <div className={cn("font-medium", labelClassName)}>{value}</div>;
|
|
68
|
-
}, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);
|
|
69
|
-
|
|
70
|
-
if (!active || !payload?.length) {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const nestLabel = payload.length === 1 && indicator !== "dot";
|
|
75
|
-
|
|
76
|
-
return (
|
|
77
|
-
<div
|
|
78
|
-
ref={ref}
|
|
79
|
-
className={cn(
|
|
80
|
-
"grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
|
|
81
|
-
className,
|
|
82
|
-
)}
|
|
83
|
-
>
|
|
84
|
-
{!nestLabel ? tooltipLabel : null}
|
|
85
|
-
<div className="grid gap-1.5">
|
|
86
|
-
{payload
|
|
87
|
-
.filter((item) => item.type !== "none")
|
|
88
|
-
.map((item, index) => {
|
|
89
|
-
/* c8 ignore next -- prefers nameKey when provided; remaining fallbacks are recharts-internal edge cases */
|
|
90
|
-
const key = `${nameKey || item.name || item.dataKey || "value"}`;
|
|
91
|
-
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
92
|
-
/* c8 ignore next -- defers to explicit color prop; remaining fallbacks cover recharts-internal edge cases */
|
|
93
|
-
const indicatorColor = color || item.payload.fill || item.color;
|
|
94
|
-
|
|
95
|
-
return (
|
|
96
|
-
<div
|
|
97
|
-
key={item.dataKey}
|
|
98
|
-
className={cn(
|
|
99
|
-
"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
|
|
100
|
-
indicator === "dot" && "items-center",
|
|
101
|
-
)}
|
|
102
|
-
>
|
|
103
|
-
{formatter && item?.value !== undefined && item.name ? (
|
|
104
|
-
formatter(item.value, item.name, item, index, item.payload)
|
|
105
|
-
) : (
|
|
106
|
-
<>
|
|
107
|
-
{itemConfig?.icon ? (
|
|
108
|
-
<itemConfig.icon />
|
|
109
|
-
) : (
|
|
110
|
-
!hideIndicator && (
|
|
111
|
-
<div
|
|
112
|
-
className={cn(
|
|
113
|
-
"shrink-0 rounded-[2px] border-[var(--color-border)] bg-[var(--color-bg)]",
|
|
114
|
-
{
|
|
115
|
-
"h-2.5 w-2.5": indicator === "dot",
|
|
116
|
-
"w-1": indicator === "line",
|
|
117
|
-
"w-0 border-[1.5px] border-dashed bg-transparent":
|
|
118
|
-
indicator === "dashed",
|
|
119
|
-
"my-0.5": nestLabel && indicator === "dashed",
|
|
120
|
-
},
|
|
121
|
-
)}
|
|
122
|
-
style={
|
|
123
|
-
{
|
|
124
|
-
"--color-bg": indicatorColor,
|
|
125
|
-
"--color-border": indicatorColor,
|
|
126
|
-
} as React.CSSProperties
|
|
127
|
-
}
|
|
128
|
-
/>
|
|
129
|
-
)
|
|
130
|
-
)}
|
|
131
|
-
<div
|
|
132
|
-
className={cn(
|
|
133
|
-
"flex flex-1 justify-between leading-none",
|
|
134
|
-
nestLabel ? "items-end" : "items-center",
|
|
135
|
-
)}
|
|
136
|
-
>
|
|
137
|
-
<div className="grid gap-1.5">
|
|
138
|
-
{nestLabel ? tooltipLabel : null}
|
|
139
|
-
<span className="text-muted-foreground">
|
|
140
|
-
{itemConfig?.label || item.name}
|
|
141
|
-
</span>
|
|
142
|
-
</div>
|
|
143
|
-
{item.value && (
|
|
144
|
-
<span className="font-mono font-medium tabular-nums text-foreground">
|
|
145
|
-
{item.value.toLocaleString()}
|
|
146
|
-
</span>
|
|
147
|
-
)}
|
|
148
|
-
</div>
|
|
149
|
-
</>
|
|
150
|
-
)}
|
|
151
|
-
</div>
|
|
152
|
-
);
|
|
153
|
-
})}
|
|
154
|
-
</div>
|
|
155
|
-
</div>
|
|
156
|
-
);
|
|
157
|
-
},
|
|
158
|
-
);
|
|
159
|
-
ChartTooltipContent.displayName = "ChartTooltip";
|
|
160
|
-
|
|
161
|
-
export { ChartTooltip, ChartTooltipContent };
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type * as React from "react";
|
|
4
|
-
import * as RechartsPrimitive from "recharts";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Chart-type wrappers. Each wraps a Recharts top-level chart component with
|
|
8
|
-
* sensible default `margin` so axis labels don't clip. Children pass through
|
|
9
|
-
* UNWRAPPED — Recharts uses `findAllByType` on its direct children to detect
|
|
10
|
-
* `<Line>` / `<XAxis>` / `<CartesianGrid>` etc., so any extra wrapper element
|
|
11
|
-
* (Context.Provider, fragment-only-on-render, etc.) breaks chart rendering.
|
|
12
|
-
*
|
|
13
|
-
* The auto-palette context is established by `<ChartContainer>` instead, so
|
|
14
|
-
* data primitives still cycle through `--chart-N` colours when no fill /
|
|
15
|
-
* stroke is supplied.
|
|
16
|
-
*
|
|
17
|
-
* Margin defaults are merged with any user-supplied margin (user wins on
|
|
18
|
-
* conflict). Everything else is straight pass-through.
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
const DEFAULT_MARGIN = { top: 12, right: 12, bottom: 4, left: 0 } as const;
|
|
22
|
-
|
|
23
|
-
function withDefaults<P extends { children?: React.ReactNode; margin?: object }>(
|
|
24
|
-
Comp: React.ComponentType<P>,
|
|
25
|
-
): React.FC<P> {
|
|
26
|
-
const Wrapped = ({ children, margin, ...rest }: P) => {
|
|
27
|
-
const merged = { ...DEFAULT_MARGIN, ...(margin ?? {}) };
|
|
28
|
-
const props = { ...rest, margin: merged } as any;
|
|
29
|
-
return <Comp {...props}>{children}</Comp>;
|
|
30
|
-
};
|
|
31
|
-
/* c8 ignore next -- defensive: every recharts top-level chart component ships with a `displayName`; the `?? Comp.name ?? "Anonymous"` fallback chain only fires for hand-rolled non-recharts wrappers */
|
|
32
|
-
Wrapped.displayName = `Chart(${(Comp as { displayName?: string }).displayName ?? Comp.name ?? "Anonymous"})`;
|
|
33
|
-
return Wrapped;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export const LineChart = withDefaults(RechartsPrimitive.LineChart);
|
|
37
|
-
export const BarChart = withDefaults(RechartsPrimitive.BarChart);
|
|
38
|
-
export const AreaChart = withDefaults(RechartsPrimitive.AreaChart);
|
|
39
|
-
export const ComposedChart = withDefaults(RechartsPrimitive.ComposedChart);
|
|
40
|
-
export const PieChart = withDefaults(RechartsPrimitive.PieChart);
|
|
41
|
-
export const ScatterChart = withDefaults(RechartsPrimitive.ScatterChart);
|
|
42
|
-
export const RadarChart = withDefaults(RechartsPrimitive.RadarChart);
|
|
43
|
-
export const RadialBarChart = withDefaults(RechartsPrimitive.RadialBarChart);
|
|
44
|
-
export const FunnelChart = withDefaults(RechartsPrimitive.FunnelChart);
|
|
45
|
-
export const SunburstChart = withDefaults(RechartsPrimitive.SunburstChart);
|
|
46
|
-
|
|
47
|
-
// Treemap and Sankey have a different children shape — pure pass-throughs.
|
|
48
|
-
export const Treemap = RechartsPrimitive.Treemap;
|
|
49
|
-
export const Sankey = RechartsPrimitive.Sankey;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Container-level Recharts primitives. Pure pass-throughs.
|
|
5
|
-
* `ResponsiveContainer` is also re-rendered internally by `<ChartContainer>`,
|
|
6
|
-
* but consumers might want to use it directly for non-canvas-themed charts.
|
|
7
|
-
*
|
|
8
|
-
* NOTE: re-exported via `export { … }` (not `export const = …`) so TypeScript
|
|
9
|
-
* doesn't have to name internal Recharts prop types in the d.ts emit.
|
|
10
|
-
*/
|
|
11
|
-
export { Brush, Layer, ResponsiveContainer, Surface } from "recharts";
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Data-primitive re-exports. These are direct pass-throughs of the Recharts
|
|
5
|
-
* primitives — wrapping them in our own function components breaks Recharts'
|
|
6
|
-
* `findAllByType` introspection (it looks for `child.type === Bar` etc., and
|
|
7
|
-
* a wrapper's `type` is our function, not Bar). The earlier wrapped version
|
|
8
|
-
* crashed Recharts with "Cannot read properties of undefined (reading
|
|
9
|
-
* 'yAxisId')" because the chart-type couldn't find our axes / data.
|
|
10
|
-
*
|
|
11
|
-
* Auto-palette cycling happens inside `<ChartContainer>` via a deep
|
|
12
|
-
* `React.cloneElement` walk that injects `fill`/`stroke` defaults when the
|
|
13
|
-
* consumer didn't supply one. The wrapped types remain the real Recharts
|
|
14
|
-
* classes, so axis detection / chart-type child resolution keep working.
|
|
15
|
-
*/
|
|
16
|
-
export { Area, Bar, Funnel, Line, Pie, Radar, RadialBar, Scatter } from "recharts";
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Detail-level Recharts primitives. Pure pass-throughs — no theming
|
|
5
|
-
* opportunity, but re-exported here so consumers can import the entire
|
|
6
|
-
* Recharts surface from canvas.
|
|
7
|
-
*
|
|
8
|
-
* `Cell` and `Customized` are aliased to `ChartCell` / `ChartCustomized` to
|
|
9
|
-
* avoid likely future collisions with canvas-domain primitives.
|
|
10
|
-
*
|
|
11
|
-
* Re-exported via `export { … }` (not `export const = …`) so TypeScript
|
|
12
|
-
* doesn't have to name internal Recharts prop types in the d.ts emit.
|
|
13
|
-
*/
|
|
14
|
-
export {
|
|
15
|
-
Cell as ChartCell,
|
|
16
|
-
Cross,
|
|
17
|
-
Curve,
|
|
18
|
-
Customized as ChartCustomized,
|
|
19
|
-
Dot,
|
|
20
|
-
ErrorBar,
|
|
21
|
-
Polygon,
|
|
22
|
-
Rectangle,
|
|
23
|
-
Sector,
|
|
24
|
-
Trapezoid,
|
|
25
|
-
} from "recharts";
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../../lib/utils";
|
|
4
|
-
|
|
5
|
-
export interface DotPulseProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
6
|
-
/** Number of active (pulsing) dots. Clamped to `[0, total]`. */
|
|
7
|
-
count: number;
|
|
8
|
-
/** Total number of dots rendered. Default `5`. */
|
|
9
|
-
total?: number;
|
|
10
|
-
/**
|
|
11
|
-
* CSS variable name (without leading `--`) used for active dot fill.
|
|
12
|
-
* Default `chart-1`. The variable should resolve to an HSL triplet.
|
|
13
|
-
*/
|
|
14
|
-
colorVar?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Pure-CSS severity indicator: a row of small circles where the first `count`
|
|
19
|
-
* dots pulse with color and the rest are muted. Designed for `<StatCard>`
|
|
20
|
-
* slots where no time-series data exists (e.g. lockout counts).
|
|
21
|
-
*/
|
|
22
|
-
export const DotPulse = React.forwardRef<HTMLDivElement, DotPulseProps>(
|
|
23
|
-
({ count, total = 5, colorVar = "chart-1", className, ...props }, ref) => {
|
|
24
|
-
const active = Math.max(0, Math.min(total, count));
|
|
25
|
-
const color = `hsl(var(--${colorVar}))`;
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<div
|
|
29
|
-
ref={ref}
|
|
30
|
-
className={cn("flex items-center gap-2", className)}
|
|
31
|
-
role="presentation"
|
|
32
|
-
{...props}
|
|
33
|
-
>
|
|
34
|
-
{Array.from({ length: total }, (_, i) => {
|
|
35
|
-
const isActive = i < active;
|
|
36
|
-
return (
|
|
37
|
-
<span
|
|
38
|
-
key={i}
|
|
39
|
-
className={cn("inline-block size-2 rounded-full", !isActive && "bg-muted")}
|
|
40
|
-
style={
|
|
41
|
-
isActive
|
|
42
|
-
? {
|
|
43
|
-
background: color,
|
|
44
|
-
animation: `canvas-dot-pulse 1.5s ease-in-out infinite`,
|
|
45
|
-
animationDelay: `${i * 0.15}s`,
|
|
46
|
-
}
|
|
47
|
-
: undefined
|
|
48
|
-
}
|
|
49
|
-
aria-hidden
|
|
50
|
-
/>
|
|
51
|
-
);
|
|
52
|
-
})}
|
|
53
|
-
<style>{`@keyframes canvas-dot-pulse {
|
|
54
|
-
0%, 100% { transform: scale(1); opacity: 1; }
|
|
55
|
-
50% { transform: scale(1.4); opacity: 0.5; }
|
|
56
|
-
}`}</style>
|
|
57
|
-
</div>
|
|
58
|
-
);
|
|
59
|
-
},
|
|
60
|
-
);
|
|
61
|
-
DotPulse.displayName = "DotPulse";
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../../lib/utils";
|
|
4
|
-
|
|
5
|
-
export interface GaugeProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
6
|
-
/** Percentage to fill (0–100). Values outside the range are clamped. */
|
|
7
|
-
value: number;
|
|
8
|
-
/** Pixel size (width = height). Default `160`. */
|
|
9
|
-
size?: number;
|
|
10
|
-
/** Pixel stroke width of the ring. Default `14`. */
|
|
11
|
-
strokeWidth?: number;
|
|
12
|
-
/**
|
|
13
|
-
* CSS variable name (without leading `--`) used for the filled arc. Default
|
|
14
|
-
* `chart-1`.
|
|
15
|
-
*/
|
|
16
|
-
colorVar?: string;
|
|
17
|
-
/**
|
|
18
|
-
* Center value text. Defaults to `"{value}%"`. Pass a custom node to render
|
|
19
|
-
* something richer (e.g. a unit label).
|
|
20
|
-
*/
|
|
21
|
-
valueLabel?: React.ReactNode;
|
|
22
|
-
/** Small label rendered below the centre value. Optional. */
|
|
23
|
-
caption?: React.ReactNode;
|
|
24
|
-
/** Accessible label describing the gauge. Default `"Gauge"`. */
|
|
25
|
-
"aria-label"?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Single-arc circular gauge with a centered value. Useful for adoption
|
|
30
|
-
* percentages, health scores, completion ratios, and similar 0–100 metrics.
|
|
31
|
-
* Renders a complete background ring plus a filled arc; the arc is animated
|
|
32
|
-
* via `transition-[stroke-dashoffset]` so consumers get smooth updates when
|
|
33
|
-
* `value` changes.
|
|
34
|
-
*/
|
|
35
|
-
export const Gauge = React.forwardRef<HTMLDivElement, GaugeProps>(
|
|
36
|
-
(
|
|
37
|
-
{
|
|
38
|
-
value,
|
|
39
|
-
size = 160,
|
|
40
|
-
strokeWidth = 14,
|
|
41
|
-
colorVar = "chart-1",
|
|
42
|
-
valueLabel,
|
|
43
|
-
caption,
|
|
44
|
-
className,
|
|
45
|
-
"aria-label": ariaLabel = "Gauge",
|
|
46
|
-
...props
|
|
47
|
-
},
|
|
48
|
-
ref,
|
|
49
|
-
) => {
|
|
50
|
-
const clamped = Math.max(0, Math.min(100, value));
|
|
51
|
-
const r = (size - strokeWidth) / 2;
|
|
52
|
-
const cx = size / 2;
|
|
53
|
-
const c = 2 * Math.PI * r;
|
|
54
|
-
const offset = c - (clamped / 100) * c;
|
|
55
|
-
const display = valueLabel ?? `${Math.round(clamped)}%`;
|
|
56
|
-
return (
|
|
57
|
-
<div
|
|
58
|
-
ref={ref}
|
|
59
|
-
role="meter"
|
|
60
|
-
aria-label={ariaLabel}
|
|
61
|
-
aria-valuenow={Math.round(clamped)}
|
|
62
|
-
aria-valuemin={0}
|
|
63
|
-
aria-valuemax={100}
|
|
64
|
-
className={cn("relative inline-flex flex-col items-center", className)}
|
|
65
|
-
style={{ width: size, height: caption ? "auto" : size }}
|
|
66
|
-
{...props}
|
|
67
|
-
>
|
|
68
|
-
<svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} aria-hidden>
|
|
69
|
-
<circle
|
|
70
|
-
cx={cx}
|
|
71
|
-
cy={cx}
|
|
72
|
-
r={r}
|
|
73
|
-
fill="none"
|
|
74
|
-
stroke="hsl(var(--muted))"
|
|
75
|
-
strokeWidth={strokeWidth}
|
|
76
|
-
/>
|
|
77
|
-
<circle
|
|
78
|
-
cx={cx}
|
|
79
|
-
cy={cx}
|
|
80
|
-
r={r}
|
|
81
|
-
fill="none"
|
|
82
|
-
stroke={`hsl(var(--${colorVar}))`}
|
|
83
|
-
strokeWidth={strokeWidth}
|
|
84
|
-
strokeDasharray={c}
|
|
85
|
-
strokeDashoffset={offset}
|
|
86
|
-
strokeLinecap="round"
|
|
87
|
-
transform={`rotate(-90 ${cx} ${cx})`}
|
|
88
|
-
className="transition-[stroke-dashoffset] duration-500"
|
|
89
|
-
/>
|
|
90
|
-
</svg>
|
|
91
|
-
<div
|
|
92
|
-
className="pointer-events-none absolute inset-x-0 flex flex-col items-center justify-center"
|
|
93
|
-
style={{ top: 0, height: size }}
|
|
94
|
-
>
|
|
95
|
-
<span className="font-mono text-3xl font-bold tabular-nums">{display}</span>
|
|
96
|
-
{caption && (
|
|
97
|
-
<span className="mt-1 text-[11px] uppercase tracking-[0.04em] text-muted-foreground">
|
|
98
|
-
{caption}
|
|
99
|
-
</span>
|
|
100
|
-
)}
|
|
101
|
-
</div>
|
|
102
|
-
</div>
|
|
103
|
-
);
|
|
104
|
-
},
|
|
105
|
-
);
|
|
106
|
-
Gauge.displayName = "Gauge";
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Grid re-exports — pure pass-throughs. Theming via CSS in `<ChartContainer>`
|
|
5
|
-
* (`[&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50` etc.).
|
|
6
|
-
* Wrapping breaks Recharts' child-by-type detection.
|
|
7
|
-
*/
|
|
8
|
-
export { CartesianGrid, PolarGrid } from "recharts";
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
// Container + style emitter (canvas-specific)
|
|
2
|
-
|
|
3
|
-
// Chrome — canvas-token defaults
|
|
4
|
-
export {
|
|
5
|
-
CartesianAxis,
|
|
6
|
-
PolarAngleAxis,
|
|
7
|
-
PolarRadiusAxis,
|
|
8
|
-
XAxis,
|
|
9
|
-
YAxis,
|
|
10
|
-
ZAxis,
|
|
11
|
-
} from "./axes";
|
|
12
|
-
export {
|
|
13
|
-
type ChartConfig,
|
|
14
|
-
ChartContainer,
|
|
15
|
-
ChartStyle,
|
|
16
|
-
useChart,
|
|
17
|
-
} from "./chart-container";
|
|
18
|
-
export { ChartLegend, ChartLegendContent } from "./chart-legend";
|
|
19
|
-
export { ChartTooltip, ChartTooltipContent } from "./chart-tooltip";
|
|
20
|
-
// Chart-type wrappers (`margin` defaults; auto-palette runs in ChartContainer)
|
|
21
|
-
export {
|
|
22
|
-
AreaChart,
|
|
23
|
-
BarChart,
|
|
24
|
-
ComposedChart,
|
|
25
|
-
FunnelChart,
|
|
26
|
-
LineChart,
|
|
27
|
-
PieChart,
|
|
28
|
-
RadarChart,
|
|
29
|
-
RadialBarChart,
|
|
30
|
-
Sankey,
|
|
31
|
-
ScatterChart,
|
|
32
|
-
SunburstChart,
|
|
33
|
-
Treemap,
|
|
34
|
-
} from "./chart-types";
|
|
35
|
-
// Container-level — pure pass-through
|
|
36
|
-
export { Brush, Layer, ResponsiveContainer, Surface } from "./containers";
|
|
37
|
-
// Data primitives (auto-cycle palette)
|
|
38
|
-
export { Area, Bar, Funnel, Line, Pie, Radar, RadialBar, Scatter } from "./data";
|
|
39
|
-
// Detail primitives — pure pass-through
|
|
40
|
-
export {
|
|
41
|
-
ChartCell,
|
|
42
|
-
ChartCustomized,
|
|
43
|
-
Cross,
|
|
44
|
-
Curve,
|
|
45
|
-
Dot,
|
|
46
|
-
ErrorBar,
|
|
47
|
-
Polygon,
|
|
48
|
-
Rectangle,
|
|
49
|
-
Sector,
|
|
50
|
-
Trapezoid,
|
|
51
|
-
} from "./details";
|
|
52
|
-
export { CartesianGrid, PolarGrid } from "./grids";
|
|
53
|
-
export { ReferenceArea, ReferenceDot, ReferenceLine } from "./references";
|
|
54
|
-
// Text + labels (Label aliased to avoid collision with canvas form Label)
|
|
55
|
-
export { ChartLabel, LabelList, Text } from "./text";
|
|
56
|
-
|
|
57
|
-
// Geographic — Leaflet-based heat-map (peer-optional `leaflet` + `react-leaflet`)
|
|
58
|
-
export {
|
|
59
|
-
WorldHeatMap,
|
|
60
|
-
type WorldHeatMapPoint,
|
|
61
|
-
type WorldHeatMapProps,
|
|
62
|
-
} from "./world-heat-map";
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../../lib/utils";
|
|
4
|
-
|
|
5
|
-
export interface LabeledBarListItem {
|
|
6
|
-
/** Row label. Used as the React key. */
|
|
7
|
-
label: React.ReactNode;
|
|
8
|
-
/** Numeric value rendered in the right cap; bar fill scales against the max. */
|
|
9
|
-
value: number;
|
|
10
|
-
/** Optional leading element — e.g. a flag, avatar, or `<Icon />`. */
|
|
11
|
-
leading?: React.ReactNode;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface LabeledBarListProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
15
|
-
/** Rows rendered top-to-bottom. */
|
|
16
|
-
items: LabeledBarListItem[];
|
|
17
|
-
/**
|
|
18
|
-
* CSS variable name (without leading `--`) used for the bar fill. Default
|
|
19
|
-
* `chart-1`.
|
|
20
|
-
*/
|
|
21
|
-
colorVar?: string;
|
|
22
|
-
/** Format the value rendered to the right of each label. Default `toLocaleString`. */
|
|
23
|
-
valueFormatter?: (value: number) => string;
|
|
24
|
-
/** Pixel height of the row's bar track. Default `4`. */
|
|
25
|
-
barHeight?: number;
|
|
26
|
-
/** Caption rendered below the list. */
|
|
27
|
-
caption?: React.ReactNode;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Vertical list of labeled rows with a horizontal progress bar per row. Useful
|
|
32
|
-
* for "top regions", "schema usage", "provider connections" — anywhere a small
|
|
33
|
-
* set of named values needs proportional comparison without a full chart.
|
|
34
|
-
*/
|
|
35
|
-
export const LabeledBarList = React.forwardRef<HTMLDivElement, LabeledBarListProps>(
|
|
36
|
-
(
|
|
37
|
-
{
|
|
38
|
-
items,
|
|
39
|
-
colorVar = "chart-1",
|
|
40
|
-
valueFormatter = (v) => v.toLocaleString(),
|
|
41
|
-
barHeight = 4,
|
|
42
|
-
caption,
|
|
43
|
-
className,
|
|
44
|
-
...props
|
|
45
|
-
},
|
|
46
|
-
ref,
|
|
47
|
-
) => {
|
|
48
|
-
const max = Math.max(1, ...items.map((it) => it.value));
|
|
49
|
-
return (
|
|
50
|
-
<div ref={ref} className={cn("w-full", className)} {...props}>
|
|
51
|
-
<ul className="flex flex-col gap-2.5">
|
|
52
|
-
{items.map((item, i) => {
|
|
53
|
-
const pct = Math.max(0, Math.min(100, (item.value / max) * 100));
|
|
54
|
-
return (
|
|
55
|
-
<li key={`${i}-${item.value}`} className="flex flex-col gap-1.5">
|
|
56
|
-
<div className="flex items-center gap-2 text-[13px]">
|
|
57
|
-
{item.leading && <span className="shrink-0">{item.leading}</span>}
|
|
58
|
-
<span className="flex-1 truncate">{item.label}</span>
|
|
59
|
-
<span className="font-mono text-xs text-muted-foreground tabular-nums">
|
|
60
|
-
{valueFormatter(item.value)}
|
|
61
|
-
</span>
|
|
62
|
-
</div>
|
|
63
|
-
<div
|
|
64
|
-
className="overflow-hidden rounded-full bg-muted"
|
|
65
|
-
style={{ height: barHeight }}
|
|
66
|
-
aria-hidden
|
|
67
|
-
>
|
|
68
|
-
<div
|
|
69
|
-
className="h-full rounded-full"
|
|
70
|
-
style={{
|
|
71
|
-
width: `${pct}%`,
|
|
72
|
-
background: `hsl(var(--${colorVar}))`,
|
|
73
|
-
}}
|
|
74
|
-
/>
|
|
75
|
-
</div>
|
|
76
|
-
</li>
|
|
77
|
-
);
|
|
78
|
-
})}
|
|
79
|
-
</ul>
|
|
80
|
-
{caption && <p className="mt-3 text-xs text-muted-foreground">{caption}</p>}
|
|
81
|
-
</div>
|
|
82
|
-
);
|
|
83
|
-
},
|
|
84
|
-
);
|
|
85
|
-
LabeledBarList.displayName = "LabeledBarList";
|