From 67f9acfb50b382e2fe0c1b433f0ebc049ba95142 Mon Sep 17 00:00:00 2001 From: Cohan Carpentier Date: Tue, 23 Jul 2024 15:13:58 -0400 Subject: [PATCH] feat: add charts --- README.md | 2 +- chart.tsx | 316 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- styles/globals.css | 14 +- 4 files changed, 332 insertions(+), 3 deletions(-) create mode 100644 chart.tsx diff --git a/README.md b/README.md index d992c3f..305d807 100644 --- a/README.md +++ b/README.md @@ -18,4 +18,4 @@ https://www.npmjs.com/package/@risc0/ui | Statements | Branches | Functions | Lines | | --------------------------- | ----------------------- | ------------------------- | ----------------- | -| ![Statements](https://img.shields.io/badge/statements-42.75%25-red.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-71.83%25-red.svg?style=flat) | ![Functions](https://img.shields.io/badge/functions-52.94%25-red.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-42.75%25-red.svg?style=flat) | +| ![Statements](https://img.shields.io/badge/statements-37.43%25-red.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-70.83%25-red.svg?style=flat) | ![Functions](https://img.shields.io/badge/functions-51.42%25-red.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-37.43%25-red.svg?style=flat) | diff --git a/chart.tsx b/chart.tsx new file mode 100644 index 0000000..0d78c44 --- /dev/null +++ b/chart.tsx @@ -0,0 +1,316 @@ +"use client"; + +import { + type CSSProperties, + type ComponentProps, + type ComponentType, + type ReactNode, + createContext, + forwardRef, + useContext, + useId, + useMemo, +} from "react"; +import * as RechartsPrimitive from "recharts"; +import { cn } from "./cn"; + +// Format: { THEME_NAME: CSS_SELECTOR } +const THEMES = { light: "", dark: ".dark" } as const; + +export type ChartConfig = { + [k in string]: { + label?: ReactNode; + icon?: ComponentType; + } & ({ color?: string; theme?: never } | { color?: never; theme: Record }); +}; + +type ChartContextProps = { + config: ChartConfig; +}; + +const ChartContext = createContext(null); + +function useChart() { + const context = useContext(ChartContext); + + if (!context) { + throw new Error("useChart must be used within a "); + } + + return context; +} + +const ChartContainer = forwardRef< + HTMLDivElement, + ComponentProps<"div"> & { + config: ChartConfig; + children: ComponentProps["children"]; + } +>(({ id, className, children, config, ...props }, ref) => { + const uniqueId = useId(); + const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`; + + return ( + +
+ + {children} +
+
+ ); +}); + +const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => { + const colorConfig = Object.entries(config).filter(([_, config]) => config.theme || config.color); + + if (!colorConfig.length) { + return null; + } + + return ( +