Chart
roi-ui/chartFreeItem
Composable chart components for building any type of data visualization with Recharts primitives.
Install it
npx shadcn@latest add https://roiui.com/r/chart.jsonSource
1"use client";23import {4 type ComponentProps,5 type ComponentType,6 type CSSProperties,7 createContext,8 type ReactNode,9 useContext,10 useId,11 useMemo,12} from "react";13import { Legend, ResponsiveContainer, Tooltip } from "recharts";1415import styles from "./chart.module.css";1617const THEMES = { light: "", dark: ".dark" } as const;1819export type ChartConfig = {20 [k in string]: {21 label?: ReactNode;22 icon?: ComponentType;23 } & ({ color?: string; theme?: never } | { color?: never; theme: Record<keyof typeof THEMES, string> });24};2526type ChartContextProps = {27 config: ChartConfig;28};2930const ChartContext = createContext<ChartContextProps | null>(null);3132function useChart() {33 const context = useContext(ChartContext);3435 if (!context) {36 throw new Error("useChart must be used within a <ChartContainer />");37 }3839 return context;40}4142function ChartContainer({43 id,44 className,45 children,46 config,47 ...props48}: ComponentProps<"div"> & {49 config: ChartConfig;50 children: ComponentProps<typeof ResponsiveContainer>["children"];51}) {52 const uniqueId = useId();53 const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;5455 return (56 <ChartContext.Provider value={{ config }}>57 <div {...props} className={`${styles.chartContainer} ${className || ""}`} data-chart={chartId} data-slot="chart">58 <ChartStyle config={config} id={chartId} />59 <ResponsiveContainer>{children}</ResponsiveContainer>60 </div>61 </ChartContext.Provider>62 );63}6465const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {66 const colorConfig = Object.entries(config).filter(([, itemConfig]) => itemConfig.theme || itemConfig.color);6768 if (!colorConfig.length) {69 return null;70 }7172 return (73 <style74 // biome-ignore lint/security/noDangerouslySetInnerHtml: Safe - content is generated from config object, not user input75 dangerouslySetInnerHTML={{76 __html: Object.entries(THEMES)77 .map(78 ([theme, prefix]) => `79${prefix} [data-chart=${id}] {80${colorConfig81 .map(([key, itemConfig]) => {82 const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] || itemConfig.color;83 return color ? ` --color-${key}: ${color};` : null;84 })85 .join("\n")}86}87`88 )89 .join("\n"),90 }}91 />92 );93};9495const ChartTooltip = Tooltip;9697// Helper to get indicator style class98function getIndicatorStyleClass(indicator: "line" | "dot" | "dashed"): string {99 if (indicator === "dot") {100// … truncated
What it pulls in
npm packages
Files it writes
More from Roi UI
All 123 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | Roi UI | Other | Free | no deps · 2 files | |
| Accordion (Tailwind)accordion-tailwind | Roi UI | Other | Free | no deps | |
| AI Chatai-chat | Roi UI | Other | Free | no deps · 2 files | |
| AI Chat (Tailwind)ai-chat-tailwind | Roi UI | Other | Free | no deps | |
| Alertalert | Roi UI | Other | Free | 1 dep · 2 files | |
| Alert Dialogalert-dialog | Roi UI | Other | Free | no deps · 2 files | |
| Alert Dialog (Tailwind)alert-dialog-tailwind | Roi UI | Other | Free | no deps | |
| Alert (Tailwind)alert-tailwind | Roi UI | Other | Free | 1 dep |
