{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "chart",
  "type": "registry:ui",
  "title": "Chart",
  "description": "Chart primitives for Tile UI.",
  "devDependencies": [
    "sass"
  ],
  "registryDependencies": [
    "@tile-ui/core",
    "@tile-ui/styles"
  ],
  "files": [
    {
      "path": "packages/react/src/components/chart/chart.tsx",
      "type": "registry:ui",
      "target": "components/ui/chart/chart.tsx",
      "content": "import React, { createContext, useContext, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport {\n\tCHART_INITIAL_DIMENSION,\n\tbuildChartThemeCss,\n\tchartStyleKeys,\n\tcomputeChartLayout,\n\tfindChartNearestIndex,\n\tgetChartAreaPathD,\n\tgetChartBaselineY,\n\tgetChartBarRects,\n\tgetChartLegendItems,\n\tgetChartPathD,\n\tgetChartTooltipEntries,\n\tgetChartTooltipPosition,\n} from '../lib/core';\nimport type { ChartConfig, ChartDatum, ChartLayout, ChartLegendItem, ChartSeriesItem, ChartTooltipEntry, ChartType } from '../lib/core';\nimport styles from './chart.module.scss';\n\ninterface ChartContextValue {\n\tconfig: ChartConfig;\n\tlayout: ChartLayout;\n\tdata: ChartDatum[];\n\tactiveIndex: number | null;\n}\n\nconst ChartContext = createContext<ChartContextValue | null>(null);\n\n/**\n * 读取 ChartContainer 提供的图表上下文\n */\nfunction useChart(): ChartContextValue {\n\tconst context = useContext(ChartContext);\n\tif (!context) {\n\t\tthrow new Error('useChart 必须在 <ChartContainer /> 内使用');\n\t}\n\treturn context;\n}\n\n/**\n * 生成主题相关的 CSS 变量 (--color-<key>)\n */\nexport interface ChartStyleProps {\n\tid: string;\n\tconfig: ChartConfig;\n}\n\nconst ChartStyle = React.forwardRef<HTMLStyleElement, ChartStyleProps>(({ id, config }, ref) => {\n\tconst css = useMemo(() => buildChartThemeCss(id, config), [id, config]);\n\n\tif (!css) {\n\t\treturn null;\n\t}\n\n\treturn <style ref={ref} dangerouslySetInnerHTML={{ __html: css }} />;\n});\nChartStyle.displayName = 'ChartStyle';\n\nexport interface ChartContainerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n\t/** 图表可访问名称，同时保留在容器并转发至 SVG。 */\n\t'aria-label'?: string;\n\t/** 引用外部可访问名称，同时转发至 SVG。 */\n\t'aria-labelledby'?: string;\n\t/** 引用外部可访问描述，同时转发至 SVG。 */\n\t'aria-describedby'?: string;\n\t/** SVG 标题，同时保留为容器 title 属性。 */\n\ttitle?: string;\n\tconfig: ChartConfig;\n\tdata?: ChartDatum[];\n\txKey?: string;\n\tseries?: ChartSeriesItem[];\n\ttype?: ChartType;\n\tinitialDimension?: { width: number; height: number };\n\tshowLegend?: boolean;\n\tshowTooltip?: boolean;\n\tshowGrid?: boolean;\n\tshowAxis?: boolean;\n\tchildren?: (state: ChartContextValue) => React.ReactNode;\n}\n\nconst ChartContainer = React.forwardRef<HTMLDivElement, ChartContainerProps>(\n\t(\n\t\t{\n\t\t\tclassName = '',\n\t\t\ttitle,\n\t\t\t'aria-label': ariaLabel,\n\t\t\t'aria-labelledby': ariaLabelledBy,\n\t\t\t'aria-describedby': ariaDescribedBy,\n\t\t\ttabIndex,\n\t\t\tonKeyDown,\n\t\t\tconfig,\n\t\t\tdata = [],\n\t\t\txKey = 'x',\n\t\t\tseries,\n\t\t\ttype = 'line',\n\t\t\tinitialDimension,\n\t\t\tshowLegend = true,\n\t\t\tshowTooltip = true,\n\t\t\tshowGrid = true,\n\t\t\tshowAxis = true,\n\t\t\tchildren,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst uniqueId = useId();\n\t\tconst chartId = `chart-${uniqueId.replace(/:/g, '')}`;\n\t\tconst containerRef = useRef<HTMLDivElement | null>(null);\n\t\tconst [size, setSize] = useState(initialDimension ?? CHART_INITIAL_DIMENSION);\n\t\tconst [activeIndex, setActiveIndex] = useState<number | null>(null);\n\t\tconst [keyboardActive, setKeyboardActive] = useState(false);\n\t\tconst [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });\n\n\t\tuseEffect(() => {\n\t\t\tconst element = containerRef.current;\n\t\t\tif (!element) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst observer = new ResizeObserver((entries) => {\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tconst { width } = entry.contentRect;\n\t\t\t\t\tif (width > 0) {\n\t\t\t\t\t\t// 高度固定：容器高度由 SVG 内容撑开，若跟随容器高度会形成正反馈循环导致无限放大\n\t\t\t\t\t\tsetSize((prev) => ({ ...prev, width }));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tobserver.observe(element);\n\n\t\t\treturn () => observer.disconnect();\n\t\t}, []);\n\n\t\tconst layout = useMemo(\n\t\t\t() => computeChartLayout({ config, data, series: series ?? [], xKey, type, width: size.width, height: size.height, cssVariableScope: chartId }),\n\t\t\t[config, data, series, xKey, type, size, chartId],\n\t\t);\n\n\t\tconst contextValue = useMemo<ChartContextValue>(() => ({ config, layout, data, activeIndex }), [config, layout, data, activeIndex]);\n\n\t\tfunction setRef(element: HTMLDivElement | null) {\n\t\t\tcontainerRef.current = element;\n\t\t\tif (typeof ref === 'function') {\n\t\t\t\tref(element);\n\t\t\t} else if (ref) {\n\t\t\t\tref.current = element;\n\t\t\t}\n\t\t}\n\n\t\tfunction handleMouseMove(event: React.MouseEvent<SVGSVGElement>) {\n\t\t\tconst svg = event.currentTarget;\n\t\t\tconst rect = svg.getBoundingClientRect();\n\t\t\tconst x = ((event.clientX - rect.left) / rect.width) * layout.width;\n\t\t\tconst y = ((event.clientY - rect.top) / rect.height) * layout.height;\n\t\t\tsetKeyboardActive(false);\n\t\t\tsetMousePosition({ x, y });\n\t\t\tsetActiveIndex(findChartNearestIndex(layout, x));\n\t\t}\n\n\t\tfunction handleMouseLeave() {\n\t\t\tsetActiveIndex(null);\n\t\t}\n\n\t\tfunction handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {\n\t\t\tonKeyDown?.(event);\n\t\t\tif (event.defaultPrevented || tabIndex === undefined || tabIndex < 0 || event.target !== event.currentTarget) return;\n\t\t\tif (event.key === 'Escape') {\n\t\t\t\tsetKeyboardActive(false);\n\t\t\t\tsetActiveIndex(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return;\n\t\t\tconst count = layout.xLabels.length;\n\t\t\tif (count === 0) return;\n\t\t\tevent.preventDefault();\n\t\t\tsetKeyboardActive(true);\n\t\t\tsetActiveIndex((current) => {\n\t\t\t\tif (current === null) return event.key === 'ArrowLeft' ? count - 1 : 0;\n\t\t\t\treturn Math.min(count - 1, Math.max(0, current + (event.key === 'ArrowLeft' ? -1 : 1)));\n\t\t\t});\n\t\t}\n\n\t\tconst entries = useMemo(() => getChartTooltipEntries(layout, config, data, activeIndex), [layout, config, data, activeIndex]);\n\t\tconst legendItems = useMemo(() => getChartLegendItems(layout), [layout]);\n\t\tconst tooltipX = activeIndex !== null ? (layout.xTickX[activeIndex] ?? 0) : 0;\n\t\tconst tooltipLabel = activeIndex !== null ? layout.xLabels[activeIndex] : null;\n\t\tconst svgLabel = ariaLabel ?? (ariaLabelledBy ? undefined : (title ?? 'Chart'));\n\t\tconst statusText = keyboardActive && activeIndex !== null ? [tooltipLabel, ...entries.map((entry) => `${entry.name} ${entry.value.toLocaleString()}`)].join(', ') : '';\n\n\t\treturn (\n\t\t\t<ChartContext.Provider value={contextValue}>\n\t\t\t\t<div\n\t\t\t\t\tref={setRef}\n\t\t\t\t\tdata-slot=\"chart\"\n\t\t\t\t\tdata-chart={chartId}\n\t\t\t\t\tdata-active-index={activeIndex ?? undefined}\n\t\t\t\t\tclassName={`${styles[chartStyleKeys.root]} ${className}`}\n\t\t\t\t\ttitle={title}\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\t\t\taria-describedby={ariaDescribedBy}\n\t\t\t\t\ttabIndex={tabIndex}\n\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t{...props}>\n\t\t\t\t\t<ChartStyle id={chartId} config={config} />\n\t\t\t\t\t<svg\n\t\t\t\t\t\tclassName={styles[chartStyleKeys.surface]}\n\t\t\t\t\t\twidth={layout.width}\n\t\t\t\t\t\theight={layout.height}\n\t\t\t\t\t\tviewBox={`0 0 ${layout.width} ${layout.height}`}\n\t\t\t\t\t\trole=\"img\"\n\t\t\t\t\t\taria-label={svgLabel}\n\t\t\t\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\t\t\t\taria-describedby={ariaDescribedBy}\n\t\t\t\t\t\tonMouseMove={handleMouseMove}\n\t\t\t\t\t\tonMouseLeave={handleMouseLeave}>\n\t\t\t\t\t\t{title && <title>{title}</title>}\n\t\t\t\t\t\t{showGrid &&\n\t\t\t\t\t\t\tlayout.yTickY.map((y, index) => (\n\t\t\t\t\t\t\t\t<line\n\t\t\t\t\t\t\t\t\tkey={`y-${index}`}\n\t\t\t\t\t\t\t\t\tclassName={styles[chartStyleKeys.gridLine]}\n\t\t\t\t\t\t\t\t\tx1={layout.padding.left}\n\t\t\t\t\t\t\t\t\tx2={layout.width - layout.padding.right}\n\t\t\t\t\t\t\t\t\ty1={y}\n\t\t\t\t\t\t\t\t\ty2={y}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t{showGrid &&\n\t\t\t\t\t\t\tlayout.xTickX.map((x, index) => (\n\t\t\t\t\t\t\t\t<line\n\t\t\t\t\t\t\t\t\tkey={`x-${index}`}\n\t\t\t\t\t\t\t\t\tclassName={styles[chartStyleKeys.gridLine]}\n\t\t\t\t\t\t\t\t\tx1={x}\n\t\t\t\t\t\t\t\t\tx2={x}\n\t\t\t\t\t\t\t\t\ty1={layout.padding.top}\n\t\t\t\t\t\t\t\t\ty2={layout.height - layout.padding.bottom}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t{showAxis &&\n\t\t\t\t\t\t\tlayout.xLabels.map((label, index) => (\n\t\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t\tkey={`label-${index}`}\n\t\t\t\t\t\t\t\t\tx={layout.xTickX[index]}\n\t\t\t\t\t\t\t\t\ty={layout.height - layout.padding.bottom / 2}\n\t\t\t\t\t\t\t\t\ttextAnchor=\"middle\"\n\t\t\t\t\t\t\t\t\tdominantBaseline=\"middle\"\n\t\t\t\t\t\t\t\t\tfontSize=\"10\">\n\t\t\t\t\t\t\t\t\t{String(label)}\n\t\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t{layout.series.map((item, seriesIndex) => {\n\t\t\t\t\t\t\tif (item.type === 'bar') {\n\t\t\t\t\t\t\t\tconst rects = getChartBarRects(layout, seriesIndex, layout.series.filter((s) => s.type === 'bar').length);\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<g key={item.key} data-series={item.key} data-type={item.type}>\n\t\t\t\t\t\t\t\t\t\t{rects.map((rect) => (\n\t\t\t\t\t\t\t\t\t\t\t<rect key={rect.index} data-index={rect.index} x={rect.x} y={rect.y} width={rect.width} height={rect.height} fill={item.color} rx={2} />\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst path = item.type === 'area' ? getChartAreaPathD(item.points, getChartBaselineY(layout)) : getChartPathD(item.points);\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<g key={item.key} data-series={item.key} data-type={item.type}>\n\t\t\t\t\t\t\t\t\t{item.type === 'area' && <path data-area d={path} fill={item.color} fillOpacity={0.2} />}\n\t\t\t\t\t\t\t\t\t<path d={getChartPathD(item.points)} fill=\"none\" stroke={item.color} strokeWidth={2} strokeLinejoin=\"round\" strokeLinecap=\"round\" />\n\t\t\t\t\t\t\t\t\t{item.points.map((point) => (\n\t\t\t\t\t\t\t\t\t\t<circle key={point.index} data-index={point.index} cx={point.x} cy={point.y} r={2.5} fill={item.color} />\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t\t{showTooltip && activeIndex !== null && (\n\t\t\t\t\t\t\t<line\n\t\t\t\t\t\t\t\tx1={tooltipX}\n\t\t\t\t\t\t\t\tx2={tooltipX}\n\t\t\t\t\t\t\t\ty1={layout.padding.top}\n\t\t\t\t\t\t\t\ty2={layout.height - layout.padding.bottom}\n\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\tstrokeDasharray=\"3 3\"\n\t\t\t\t\t\t\t\topacity={0.4}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</svg>\n\t\t\t\t\t{showTooltip && activeIndex !== null && (\n\t\t\t\t\t\t<ChartTooltipContent\n\t\t\t\t\t\t\tactive\n\t\t\t\t\t\t\tpayload={entries}\n\t\t\t\t\t\t\tlabel={tooltipLabel}\n\t\t\t\t\t\t\tclassName={styles[chartStyleKeys.tooltip]}\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\t\t\t...getChartTooltipPosition(layout, mousePosition.x, mousePosition.y),\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{showLegend && <ChartLegendContent payload={legendItems} />}\n\t\t\t\t\t<div\n\t\t\t\t\t\tdata-slot=\"chart-status\"\n\t\t\t\t\t\trole=\"status\"\n\t\t\t\t\t\taria-live=\"polite\"\n\t\t\t\t\t\taria-atomic=\"true\"\n\t\t\t\t\t\tstyle={{ position: 'absolute', width: 1, height: 1, padding: 0, margin: -1, overflow: 'hidden', clipPath: 'inset(50%)', whiteSpace: 'nowrap', border: 0 }}>\n\t\t\t\t\t\t{statusText}\n\t\t\t\t\t</div>\n\t\t\t\t\t{children?.(contextValue)}\n\t\t\t\t</div>\n\t\t\t</ChartContext.Provider>\n\t\t);\n\t},\n);\nChartContainer.displayName = 'ChartContainer';\n\nexport interface ChartTooltipContentProps extends React.HTMLAttributes<HTMLDivElement> {\n\tactive?: boolean;\n\tpayload?: ChartTooltipEntry[];\n\tlabel?: React.ReactNode;\n\tindicator?: 'line' | 'dot' | 'dashed';\n\thideLabel?: boolean;\n\thideIndicator?: boolean;\n\tlabelFormatter?: (value: React.ReactNode, payload: ChartTooltipEntry[]) => React.ReactNode;\n\tformatter?: (value: number, name: string, item: ChartTooltipEntry, index: number) => React.ReactNode;\n\tcolor?: string;\n\tnameKey?: string;\n\tlabelKey?: string;\n\tlabelClassName?: string;\n}\n\nconst ChartTooltipContent = React.forwardRef<HTMLDivElement, ChartTooltipContentProps>(\n\t(\n\t\t{ active, payload, className = '', indicator = 'dot', hideLabel = false, hideIndicator = false, label, labelFormatter, labelClassName = '', formatter, color, ...props },\n\t\tref,\n\t) => {\n\t\tconst { config } = useChart();\n\t\tconst items = payload ?? [];\n\n\t\tif (!active || items.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst labelNode = !hideLabel && label != null && (\n\t\t\t<div className={`${styles[chartStyleKeys.tooltipLabel]} ${labelClassName}`}>{labelFormatter ? labelFormatter(label, items) : String(label)}</div>\n\t\t);\n\n\t\treturn (\n\t\t\t<div ref={ref} className={className} {...props}>\n\t\t\t\t{labelNode}\n\t\t\t\t<div className={styles[chartStyleKeys.tooltipGrid]}>\n\t\t\t\t\t{items.map((item, index) => {\n\t\t\t\t\t\tconst itemConfig = config[item.dataKey];\n\t\t\t\t\t\tconst indicatorColor = color ?? item.color;\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div key={index} className={styles[chartStyleKeys.tooltipItem]} data-indicator={indicator}>\n\t\t\t\t\t\t\t\t{!hideIndicator && (\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclassName={styles[chartStyleKeys.tooltipIndicator]}\n\t\t\t\t\t\t\t\t\t\tdata-indicator={indicator}\n\t\t\t\t\t\t\t\t\t\tstyle={{ backgroundColor: indicatorColor, borderColor: indicatorColor }}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<div className={styles[chartStyleKeys.tooltipItemName]}>{itemConfig?.label ?? item.name}</div>\n\t\t\t\t\t\t\t\t{formatter && item.value !== undefined ? (\n\t\t\t\t\t\t\t\t\tformatter(item.value, item.name, item, index)\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<div className={styles[chartStyleKeys.tooltipItemValue]}>\n\t\t\t\t\t\t\t\t\t\t{typeof item.value === 'number' ? item.value.toLocaleString() : String(item.value)}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t},\n);\nChartTooltipContent.displayName = 'ChartTooltipContent';\n\nexport interface ChartLegendContentProps extends React.HTMLAttributes<HTMLDivElement> {\n\tpayload?: ChartLegendItem[];\n\thideIcon?: boolean;\n\tverticalAlign?: 'top' | 'bottom';\n}\n\nconst ChartLegendContent = React.forwardRef<HTMLDivElement, ChartLegendContentProps>(({ className = '', payload, hideIcon = false, verticalAlign = 'bottom', ...props }, ref) => {\n\tconst items = payload ?? [];\n\n\tif (items.length === 0) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div ref={ref} data-align={verticalAlign} className={`${styles[chartStyleKeys.legend]} ${className}`} {...props}>\n\t\t\t{items.map((item, index) => (\n\t\t\t\t<div key={index} className={styles[chartStyleKeys.legendItem]}>\n\t\t\t\t\t{!hideIcon && <span className={styles[chartStyleKeys.legendSwatch]} style={{ backgroundColor: item.color }} />}\n\t\t\t\t\t{item.name}\n\t\t\t\t</div>\n\t\t\t))}\n\t\t</div>\n\t);\n});\nChartLegendContent.displayName = 'ChartLegendContent';\n\nexport interface ChartTooltipProps {\n\tclassName?: string;\n\tchildren?: (state: { active: boolean; payload: ChartTooltipEntry[]; label: React.ReactNode }) => React.ReactNode;\n}\n\nconst ChartTooltip = ({ className = '', children }: ChartTooltipProps) => {\n\tconst { layout, config, data, activeIndex } = useChart();\n\tconst entries = getChartTooltipEntries(layout, config, data, activeIndex);\n\tconst label = activeIndex !== null ? layout.xLabels[activeIndex] : null;\n\n\tif (children) {\n\t\treturn <>{children({ active: activeIndex !== null, payload: entries, label })}</>;\n\t}\n\n\treturn <ChartTooltipContent className={className} active={activeIndex !== null} payload={entries} label={label} />;\n};\nChartTooltip.displayName = 'ChartTooltip';\n\nexport interface ChartLegendProps extends Omit<ChartLegendContentProps, 'payload'> {}\n\nconst ChartLegend = (props: ChartLegendProps) => {\n\tconst { layout } = useChart();\n\treturn <ChartLegendContent {...props} payload={getChartLegendItems(layout)} />;\n};\nChartLegend.displayName = 'ChartLegend';\n\nexport { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent, ChartStyle };\nexport default ChartContainer;\n"
    },
    {
      "path": "packages/styles/scss/components/chart.module.scss",
      "type": "registry:file",
      "target": "components/ui/chart/chart.module.scss",
      "content": "@use '../../../styles/variables/colors' as *;\n\n// 图表根容器\n.root {\n\tposition: relative;\n\tdisplay: flex;\n\twidth: 100%;\n\taspect-ratio: 16 / 9;\n\tflex-direction: column;\n\tjustify-content: center;\n\tfont-size: var(--tile-chart-font-size, $text-xs);\n\tcolor: var(--tile-chart-muted-foreground, $muted-foreground);\n}\n\n// 绘图画布\n.surface {\n\toverflow: visible;\n\n\ttext {\n\t\tfill: var(--tile-chart-muted-foreground, $muted-foreground);\n\t}\n}\n\n// 网格线\n.gridLine {\n\tstroke: var(--tile-chart-grid-color, $border);\n\tstroke-opacity: var(--tile-chart-grid-opacity, 0.5);\n\tstroke-dasharray: var(--tile-chart-grid-dasharray, 4 4);\n}\n\n// 坐标轴线\n.axisLine {\n\tstroke: var(--tile-chart-axis-color, $border);\n}\n\n// 图例容器\n.legend {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: $spacing-4;\n\tpadding-top: $spacing-3;\n\n\t&[data-align='top'] {\n\t\tpadding-top: 0;\n\t\tpadding-bottom: $spacing-3;\n\t}\n}\n\n// 图例条目\n.legendItem {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: $spacing-1_5;\n\tcolor: var(--tile-chart-muted-foreground, $muted-foreground);\n}\n\n// 图例色块\n.legendSwatch {\n\twidth: 0.5rem;\n\theight: 0.5rem;\n\tflex-shrink: 0;\n\tborder-radius: $radius-xs;\n}\n\n// Tooltip 容器\n.tooltip {\n\tpointer-events: none;\n\tdisplay: grid;\n\tmin-width: 8rem;\n\talign-items: start;\n\tgap: $spacing-1_5;\n\tborder: 1px solid var(--tile-chart-tooltip-border, color-mix(in srgb, $border 50%, transparent));\n\tborder-radius: var(--tile-chart-tooltip-radius, $radius);\n\tbackground-color: var(--tile-chart-tooltip-background, $popover);\n\tpadding: $spacing-1_5 $spacing-2_5;\n\tcolor: var(--tile-chart-tooltip-foreground, $popover-foreground);\n\tfont-size: var(--tile-chart-font-size, $text-xs);\n\tbox-shadow: var(--tile-chart-tooltip-shadow, $shadow-lg);\n}\n\n// Tooltip 标签\n.tooltipLabel {\n\tfont-weight: $font-medium;\n}\n\n// Tooltip 条目网格\n.tooltipGrid {\n\tdisplay: grid;\n\tgap: $spacing-1_5;\n}\n\n// Tooltip 单条条目\n.tooltipItem {\n\tdisplay: flex;\n\twidth: 100%;\n\tflex-wrap: wrap;\n\talign-items: stretch;\n\tgap: $spacing-2;\n\n\t&[data-indicator='dot'] {\n\t\talign-items: center;\n\t}\n}\n\n// Tooltip 条目名称\n.tooltipItemName {\n\tcolor: var(--tile-chart-muted-foreground, $muted-foreground);\n}\n\n// Tooltip 条目数值\n.tooltipItemValue {\n\tfont-family: $font-mono;\n\tfont-weight: $font-medium;\n\tcolor: var(--tile-chart-foreground, $foreground);\n\tfont-variant-numeric: tabular-nums;\n}\n\n// Tooltip 指示器\n.tooltipIndicator {\n\tflex-shrink: 0;\n\tborder-radius: $radius-xs;\n\n\t&[data-indicator='dot'] {\n\t\twidth: 0.625rem;\n\t\theight: 0.625rem;\n\t}\n\n\t&[data-indicator='line'] {\n\t\twidth: 0.25rem;\n\t\theight: 1rem;\n\t}\n\n\t&[data-indicator='dashed'] {\n\t\twidth: 0;\n\t\tborder: 1.5px dashed currentColor;\n\t\tbackground: transparent;\n\t}\n}\n"
    },
    {
      "path": "packages/react/src/components/chart/index.ts",
      "type": "registry:ui",
      "target": "components/ui/chart/index.ts",
      "content": "export {\n\tChartContainer,\n\tChartTooltip,\n\tChartTooltipContent,\n\tChartLegend,\n\tChartLegendContent,\n\tChartStyle,\n\ttype ChartContainerProps,\n\ttype ChartTooltipProps,\n\ttype ChartTooltipContentProps,\n\ttype ChartLegendProps,\n\ttype ChartLegendContentProps,\n\ttype ChartStyleProps,\n} from './chart';\n"
    }
  ]
}
