@acronis-platform/ui-react 0.57.1 → 0.60.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/dist/components/ui/area-chart/area-chart.js +177 -0
- package/dist/components/ui/area-chart/area-chart.js.map +1 -0
- package/dist/components/ui/bar-chart/bar-chart.js +184 -78
- package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
- package/dist/components/ui/button-icon-input/button-icon-input.js +36 -0
- package/dist/components/ui/button-icon-input/button-icon-input.js.map +1 -0
- package/dist/components/ui/button-menu/button-menu.js +1 -1
- package/dist/components/ui/button-menu/button-menu.js.map +1 -1
- package/dist/components/ui/calendar/calendar.js +17 -15
- package/dist/components/ui/calendar/calendar.js.map +1 -1
- package/dist/components/ui/card-filter/card-filter.js +40 -27
- package/dist/components/ui/card-filter/card-filter.js.map +1 -1
- package/dist/components/ui/carousel-dialog/carousel-dialog.js +87 -0
- package/dist/components/ui/carousel-dialog/carousel-dialog.js.map +1 -0
- package/dist/components/ui/category-bar/category-bar.js +126 -0
- package/dist/components/ui/category-bar/category-bar.js.map +1 -0
- package/dist/components/ui/chart/chart-format.js +40 -0
- package/dist/components/ui/chart/chart-format.js.map +1 -0
- package/dist/components/ui/chart/chart.js.map +1 -1
- package/dist/components/ui/chart-state/chart-state.js +42 -0
- package/dist/components/ui/chart-state/chart-state.js.map +1 -0
- package/dist/components/ui/chip/chip.js +13 -13
- package/dist/components/ui/chip/chip.js.map +1 -1
- package/dist/components/ui/composed-chart/composed-chart.js +135 -0
- package/dist/components/ui/composed-chart/composed-chart.js.map +1 -0
- package/dist/components/ui/confidence-cone/confidence-cone.js +223 -0
- package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -0
- package/dist/components/ui/date-range-picker/date-range-picker.js +21 -21
- package/dist/components/ui/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/ui/dialog/dialog.js +248 -76
- package/dist/components/ui/dialog/dialog.js.map +1 -1
- package/dist/components/ui/dialog-footer-carousel/dialog-footer-carousel.js +57 -0
- package/dist/components/ui/dialog-footer-carousel/dialog-footer-carousel.js.map +1 -0
- package/dist/components/ui/dialog-footer-default/dialog-footer-default.js +26 -0
- package/dist/components/ui/dialog-footer-default/dialog-footer-default.js.map +1 -0
- package/dist/components/ui/dialog-welcome/dialog-welcome.js +272 -0
- package/dist/components/ui/dialog-welcome/dialog-welcome.js.map +1 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.js +21 -21
- package/dist/components/ui/dropdown-menu/dropdown-menu.js.map +1 -1
- package/dist/components/ui/filter-search/filter-search.js +91 -90
- package/dist/components/ui/filter-search/filter-search.js.map +1 -1
- package/dist/components/ui/funnel-chart/funnel-chart.js +87 -0
- package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -0
- package/dist/components/ui/histogram/histogram.js +136 -0
- package/dist/components/ui/histogram/histogram.js.map +1 -0
- package/dist/components/ui/input/input.js.map +1 -1
- package/dist/components/ui/input-otp/input-otp.js +104 -0
- package/dist/components/ui/input-otp/input-otp.js.map +1 -0
- package/dist/components/ui/input-password/input-password.js +120 -0
- package/dist/components/ui/input-password/input-password.js.map +1 -0
- package/dist/components/ui/input-text/input-text.js +9 -9
- package/dist/components/ui/input-text/input-text.js.map +1 -1
- package/dist/components/ui/line-chart/line-chart.js +234 -0
- package/dist/components/ui/line-chart/line-chart.js.map +1 -0
- package/dist/components/ui/link/link.js +5 -5
- package/dist/components/ui/link/link.js.map +1 -1
- package/dist/components/ui/loading/loading.js +79 -0
- package/dist/components/ui/loading/loading.js.map +1 -0
- package/dist/components/ui/meter/meter.js +93 -0
- package/dist/components/ui/meter/meter.js.map +1 -0
- package/dist/components/ui/metric/metric.js +185 -0
- package/dist/components/ui/metric/metric.js.map +1 -0
- package/dist/components/ui/pie-chart/pie-chart.js +113 -0
- package/dist/components/ui/pie-chart/pie-chart.js.map +1 -0
- package/dist/components/ui/popover/popover.js +57 -27
- package/dist/components/ui/popover/popover.js.map +1 -1
- package/dist/components/ui/radar-chart/radar-chart.js +74 -0
- package/dist/components/ui/radar-chart/radar-chart.js.map +1 -0
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +69 -0
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -0
- package/dist/components/ui/sankey-chart/sankey-chart.js +192 -0
- package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -0
- package/dist/components/ui/scatter-chart/scatter-chart.js +130 -0
- package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -0
- package/dist/components/ui/search/search.js +16 -16
- package/dist/components/ui/search/search.js.map +1 -1
- package/dist/components/ui/sheet/sheet-details.js +16 -16
- package/dist/components/ui/sheet/sheet-details.js.map +1 -1
- package/dist/components/ui/spinner/spinner.js.map +1 -1
- package/dist/components/ui/timeline/timeline.js +175 -0
- package/dist/components/ui/timeline/timeline.js.map +1 -0
- package/dist/components/ui/toolbar/toolbar.js +82 -92
- package/dist/components/ui/toolbar/toolbar.js.map +1 -1
- package/dist/components/ui/treemap/treemap.js +83 -0
- package/dist/components/ui/treemap/treemap.js.map +1 -0
- package/dist/components/ui/trend-indicator/trend-indicator.js +97 -0
- package/dist/components/ui/trend-indicator/trend-indicator.js.map +1 -0
- package/dist/index.js +461 -400
- package/dist/index.js.map +1 -1
- package/dist/lib/breakpoints.js +9 -6
- package/dist/lib/breakpoints.js.map +1 -1
- package/dist/node_modules/.pnpm/embla-carousel-react@8.6.0_react@19.2.6/node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js +25 -0
- package/dist/node_modules/.pnpm/embla-carousel-react@8.6.0_react@19.2.6/node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js.map +1 -0
- package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js +36 -0
- package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js.map +1 -0
- package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js +1205 -0
- package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js.map +1 -0
- package/dist/react.js +461 -400
- package/dist/react.js.map +1 -1
- package/dist/src/components/ui/area-chart/area-chart.d.ts +34 -0
- package/dist/src/components/ui/area-chart/index.d.ts +1 -0
- package/dist/src/components/ui/avatar/avatar.d.ts +1 -1
- package/dist/src/components/ui/bar-chart/bar-chart.d.ts +30 -5
- package/dist/src/components/ui/bar-chart/index.d.ts +1 -1
- package/dist/src/components/ui/button-icon-input/button-icon-input.d.ts +21 -0
- package/dist/src/components/ui/button-icon-input/index.d.ts +1 -0
- package/dist/src/components/ui/card-filter/card-filter.d.ts +5 -0
- package/dist/src/components/ui/carousel-dialog/carousel-dialog.d.ts +28 -0
- package/dist/src/components/ui/carousel-dialog/index.d.ts +1 -0
- package/dist/src/components/ui/category-bar/category-bar.d.ts +51 -0
- package/dist/src/components/ui/category-bar/index.d.ts +1 -0
- package/dist/src/components/ui/chart/__tests__/chart-format.test.d.ts +1 -0
- package/dist/src/components/ui/chart/chart-format.d.ts +111 -0
- package/dist/src/components/ui/chart/chart.d.ts +2 -0
- package/dist/src/components/ui/chart/index.d.ts +3 -1
- package/dist/src/components/ui/chart-state/chart-state.d.ts +11 -0
- package/dist/src/components/ui/chart-state/index.d.ts +1 -0
- package/dist/src/components/ui/composed-chart/composed-chart.d.ts +33 -0
- package/dist/src/components/ui/composed-chart/index.d.ts +1 -0
- package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +62 -0
- package/dist/src/components/ui/confidence-cone/index.d.ts +1 -0
- package/dist/src/components/ui/dialog/dialog.d.ts +105 -9
- package/dist/src/components/ui/dialog/dialog.docs.d.ts +82 -5
- package/dist/src/components/ui/dialog/index.d.ts +1 -1
- package/dist/src/components/ui/dialog-footer-carousel/dialog-footer-carousel.d.ts +9 -0
- package/dist/src/components/ui/dialog-footer-carousel/index.d.ts +1 -0
- package/dist/src/components/ui/dialog-footer-default/dialog-footer-default.d.ts +11 -0
- package/dist/src/components/ui/dialog-footer-default/index.d.ts +1 -0
- package/dist/src/components/ui/dialog-welcome/dialog-welcome.d.ts +54 -0
- package/dist/src/components/ui/dialog-welcome/dialog-welcome.docs.d.ts +55 -0
- package/dist/src/components/ui/dialog-welcome/index.d.ts +1 -0
- package/dist/src/components/ui/filter-search/filter-search.d.ts +1 -1
- package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +39 -0
- package/dist/src/components/ui/funnel-chart/index.d.ts +1 -0
- package/dist/src/components/ui/histogram/histogram.d.ts +40 -0
- package/dist/src/components/ui/histogram/index.d.ts +1 -0
- package/dist/src/components/ui/input-otp/index.d.ts +1 -0
- package/dist/src/components/ui/input-otp/input-otp.d.ts +23 -0
- package/dist/src/components/ui/input-password/index.d.ts +1 -0
- package/dist/src/components/ui/input-password/input-password.d.ts +21 -0
- package/dist/src/components/ui/line-chart/index.d.ts +1 -0
- package/dist/src/components/ui/line-chart/line-chart.d.ts +68 -0
- package/dist/src/components/ui/loading/index.d.ts +1 -0
- package/dist/src/components/ui/loading/loading.d.ts +13 -0
- package/dist/src/components/ui/meter/index.d.ts +1 -0
- package/dist/src/components/ui/meter/meter.d.ts +25 -0
- package/dist/src/components/ui/metric/index.d.ts +1 -0
- package/dist/src/components/ui/metric/metric.d.ts +37 -0
- package/dist/src/components/ui/pie-chart/index.d.ts +1 -0
- package/dist/src/components/ui/pie-chart/pie-chart.d.ts +54 -0
- package/dist/src/components/ui/popover/index.d.ts +1 -1
- package/dist/src/components/ui/popover/popover.d.ts +13 -1
- package/dist/src/components/ui/radar-chart/index.d.ts +1 -0
- package/dist/src/components/ui/radar-chart/radar-chart.d.ts +40 -0
- package/dist/src/components/ui/radial-bar-chart/index.d.ts +1 -0
- package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +45 -0
- package/dist/src/components/ui/sankey-chart/index.d.ts +2 -0
- package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +69 -0
- package/dist/src/components/ui/scatter-chart/index.d.ts +1 -0
- package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +35 -0
- package/dist/src/components/ui/stack/stack.d.ts +1 -1
- package/dist/src/components/ui/timeline/index.d.ts +1 -0
- package/dist/src/components/ui/timeline/timeline.d.ts +41 -0
- package/dist/src/components/ui/treemap/index.d.ts +1 -0
- package/dist/src/components/ui/treemap/treemap.d.ts +44 -0
- package/dist/src/components/ui/trend-indicator/index.d.ts +1 -0
- package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +32 -0
- package/dist/src/index.d.ts +27 -2
- package/dist/ui-react.css +1 -1
- package/package.json +5 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"category-bar.js","sources":["../../../../src/components/ui/category-bar/category-bar.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\nimport { ChartStyle, type ChartConfig } from '../chart';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip';\n\n// A category bar: a single horizontal bar split into proportional colored\n// segments — one part-to-whole across a handful of categories, in one row\n// (onboarding stages, certification status, a rating scale). Unlike `Meter`\n// (one value per row, stacked into a bar list), all segments share the same bar.\n// It's a plain flex composition, not a recharts chart: each segment's width is\n// `value / total`, so exact proportions and the count/% legend are direct DOM,\n// with no axes/grid to hide. Segment colors are caller-supplied via `config`\n// (existing semantic `--ui-*` tokens); there is no chart palette tier yet.\n//\n// Colors are consumed through the same `--color-<key>` bridge the recharts\n// charts use: `ChartStyle` emits one custom property per config entry, so a\n// `theme: { light, dark }` entry works as well as a flat `color` — reading\n// `config[key].color` directly would render a themed config colorless. The\n// tooltip is portaled out of the bar's DOM, so its popup carries its own\n// `data-chart` scope + `ChartStyle` to keep the bridge resolvable there.\n\nconst defaultFormat = (value: number) => value.toLocaleString();\n\n// Track height only — the flex/rounded/overflow chrome is static.\nconst categoryBarVariants = cva('flex w-full overflow-hidden rounded-full bg-input', {\n variants: {\n size: {\n sm: 'h-1.5',\n md: 'h-2.5',\n lg: 'h-4',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nexport interface CategoryBarSegment {\n /** Key into `config` for this segment's label + color. */\n key: string;\n /** The segment's value — its width is this over the sum of all values. */\n value: number;\n}\n\n/** The resolved segment passed to a custom `tooltipContent` renderer. */\nexport interface CategoryBarTooltipContext extends CategoryBarSegment {\n /** Resolved `config` label (falls back to the key); may be any `ReactNode`. */\n label: React.ReactNode;\n /** Share of the total as a rounded percentage (0–100). */\n percent: number;\n /**\n * CSS color reference for the segment — the `var(--color-<key>)` bridge, which\n * resolves the config entry's `color` or its per-theme `theme` value. Usable\n * anywhere a CSS color is (e.g. a `style` background); not a literal value.\n */\n color: string;\n}\n\nexport interface CategoryBarProps\n extends Omit<React.ComponentProps<'div'>, 'children'>,\n VariantProps<typeof categoryBarVariants> {\n /** Ordered segments (left → right). Widths are proportional to `value`. */\n data: ReadonlyArray<CategoryBarSegment>;\n /** Maps each segment `key` to a `label` and `color` (an existing `--ui-*` token). */\n config: ChartConfig;\n /** Show the legend below the bar (color dot + label + value + %). */\n showLegend?: boolean;\n /** Show a hover tooltip per segment (dot + label + value + %). */\n showTooltip?: boolean;\n /**\n * Custom tooltip content per segment — replaces the default (dot + label +\n * `value · %`) inside the same card. Ignored when `showTooltip` is false.\n */\n tooltipContent?: (segment: CategoryBarTooltipContext) => React.ReactNode;\n /** Format the numeric value (legend + tooltip). Defaults to `toLocaleString()`. */\n valueFormatter?: (value: number) => string;\n /** Render the tooltip for this segment index initially open (VR/testing). */\n defaultOpenIndex?: number;\n /**\n * Accessible summary of the whole bar. Defaults to a `label value` list built\n * from the data; pass a fuller sentence for screen readers if you have one.\n */\n 'aria-label'?: string;\n}\n\nconst CategoryBar = React.forwardRef<HTMLDivElement, CategoryBarProps>(\n (\n {\n className,\n data,\n config,\n size,\n showLegend = false,\n showTooltip = true,\n tooltipContent,\n valueFormatter = defaultFormat,\n defaultOpenIndex,\n 'aria-label': ariaLabel,\n ...props\n },\n ref\n ) => {\n const uniqueId = React.useId();\n const chartId = `chart-${uniqueId.replace(/:/g, '')}`;\n\n const total = data.reduce((sum, seg) => sum + seg.value, 0);\n const labelFor = (key: string): React.ReactNode => config[key]?.label ?? key;\n // The aria-label has to be a plain string, so a rich (element) label can't\n // be used there — fall back to the key rather than stringifying it into\n // \"[object Object]\".\n const labelTextFor = (key: string) => {\n const label = config[key]?.label;\n return typeof label === 'string' || typeof label === 'number'\n ? String(label)\n : key;\n };\n const colorOf = (key: string) => `var(--color-${key})`;\n const pctOf = (value: number) =>\n total > 0 ? Math.round((value / total) * 100) : 0;\n\n // A locale-neutral fallback: \"<label> <value>\" pairs. Consumers can pass a\n // fuller `aria-label` sentence.\n const summary =\n ariaLabel ??\n data\n .map((seg) => `${labelTextFor(seg.key)} ${valueFormatter(seg.value)}`)\n .join(', ');\n\n return (\n <div\n ref={ref}\n data-chart={chartId}\n className={cn('flex w-full flex-col gap-3', className)}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <div className={categoryBarVariants({ size })} role=\"img\" aria-label={summary}>\n {data.map((seg, index) => {\n const color = colorOf(seg.key);\n // flex-grow proportional to value with a zero basis → widths are\n // exactly value/total; a zero-value segment collapses.\n const segment = (\n <div\n key={seg.key}\n className=\"h-full min-w-0\"\n style={{ flex: `${seg.value} 0 0%`, backgroundColor: color }}\n />\n );\n\n if (!showTooltip) return segment;\n\n return (\n <Tooltip key={seg.key} defaultOpen={index === defaultOpenIndex}>\n <TooltipTrigger render={segment} />\n <TooltipContent\n // The popup is portaled out of the bar, so it needs its own\n // `data-chart` scope for the `--color-*` bridge to resolve.\n data-chart={chartId}\n className={cn(\n 'border border-border bg-background text-foreground shadow-md',\n !tooltipContent && 'flex items-center gap-2'\n )}\n >\n <ChartStyle id={chartId} config={config} />\n {tooltipContent ? (\n tooltipContent({\n key: seg.key,\n value: seg.value,\n label: labelFor(seg.key),\n percent: pctOf(seg.value),\n color,\n })\n ) : (\n <>\n <span\n className=\"size-2.5 shrink-0 rounded-full\"\n style={{ backgroundColor: color }}\n />\n <span className=\"font-semibold\">{labelFor(seg.key)}</span>\n <span className=\"text-muted-foreground tabular-nums\">\n {valueFormatter(seg.value)} · {pctOf(seg.value)}%\n </span>\n </>\n )}\n </TooltipContent>\n </Tooltip>\n );\n })}\n </div>\n\n {showLegend && (\n <ul className=\"flex flex-wrap justify-between gap-x-6 gap-y-3\">\n {data.map((seg) => (\n <li key={seg.key} className=\"flex flex-col gap-1.5\">\n <span className=\"flex items-center gap-1.5 text-sm leading-none text-muted-foreground\">\n <span\n className=\"size-2.5 shrink-0 rounded-full\"\n style={{ backgroundColor: colorOf(seg.key) }}\n />\n {labelFor(seg.key)}\n </span>\n <span className=\"flex items-baseline gap-1.5 leading-none tabular-nums\">\n <span className=\"text-base font-semibold text-foreground\">\n {valueFormatter(seg.value)}\n </span>\n <span className=\"text-sm text-muted-foreground\">\n {pctOf(seg.value)}%\n </span>\n </span>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n }\n);\nCategoryBar.displayName = 'CategoryBar';\n\nexport { CategoryBar, categoryBarVariants };\n"],"names":["defaultFormat","value","categoryBarVariants","cva","CategoryBar","React","className","data","config","size","showLegend","showTooltip","tooltipContent","valueFormatter","defaultOpenIndex","ariaLabel","props","ref","chartId","total","sum","seg","labelFor","key","_a","labelTextFor","label","colorOf","pctOf","summary","jsxs","cn","jsx","ChartStyle","index","color","segment","Tooltip","TooltipTrigger","TooltipContent","Fragment"],"mappings":";;;;;;AAyBA,MAAMA,IAAgB,CAACC,MAAkBA,EAAM,eAAA,GAGzCC,IAAsBC,EAAI,qDAAqD;AAAA,EACnF,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA;AAAA,EACN;AAAA,EAEF,iBAAiB;AAAA,IACf,MAAM;AAAA,EAAA;AAEV,CAAC,GAkDKC,IAAcC,EAAM;AAAA,EACxB,CACE;AAAA,IACE,WAAAC;AAAA,IACA,MAAAC;AAAA,IACA,QAAAC;AAAA,IACA,MAAAC;AAAA,IACA,YAAAC,IAAa;AAAA,IACb,aAAAC,IAAc;AAAA,IACd,gBAAAC;AAAA,IACA,gBAAAC,IAAiBb;AAAA,IACjB,kBAAAc;AAAA,IACA,cAAcC;AAAA,IACd,GAAGC;AAAA,EAAA,GAELC,MACG;AAEH,UAAMC,IAAU,SADCb,EAAM,MAAA,EACW,QAAQ,MAAM,EAAE,CAAC,IAE7Cc,IAAQZ,EAAK,OAAO,CAACa,GAAKC,MAAQD,IAAMC,EAAI,OAAO,CAAC,GACpDC,IAAW,CAACC,MAAA;;AAAiC,eAAAC,IAAAhB,EAAOe,CAAG,MAAV,gBAAAC,EAAa,UAASD;AAAA,OAInEE,IAAe,CAACF,MAAgB;;AACpC,YAAMG,KAAQF,IAAAhB,EAAOe,CAAG,MAAV,gBAAAC,EAAa;AAC3B,aAAO,OAAOE,KAAU,YAAY,OAAOA,KAAU,WACjD,OAAOA,CAAK,IACZH;AAAA,IACN,GACMI,IAAU,CAACJ,MAAgB,eAAeA,CAAG,KAC7CK,IAAQ,CAAC3B,MACbkB,IAAQ,IAAI,KAAK,MAAOlB,IAAQkB,IAAS,GAAG,IAAI,GAI5CU,IACJd,KACAR,EACG,IAAI,CAACc,MAAQ,GAAGI,EAAaJ,EAAI,GAAG,CAAC,IAAIR,EAAeQ,EAAI,KAAK,CAAC,EAAE,EACpE,KAAK,IAAI;AAEd,WACE,gBAAAS;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAAb;AAAA,QACA,cAAYC;AAAA,QACZ,WAAWa,EAAG,8BAA8BzB,CAAS;AAAA,QACpD,GAAGU;AAAA,QAEJ,UAAA;AAAA,UAAA,gBAAAgB,EAACC,GAAA,EAAW,IAAIf,GAAS,QAAAV,EAAA,CAAgB;AAAA,4BACxC,OAAA,EAAI,WAAWN,EAAoB,EAAE,MAAAO,GAAM,GAAG,MAAK,OAAM,cAAYoB,GACnE,UAAAtB,EAAK,IAAI,CAACc,GAAKa,MAAU;AACxB,kBAAMC,IAAQR,EAAQN,EAAI,GAAG,GAGvBe,IACJ,gBAAAJ;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAU;AAAA,gBACV,OAAO,EAAE,MAAM,GAAGX,EAAI,KAAK,SAAS,iBAAiBc,EAAA;AAAA,cAAM;AAAA,cAFtDd,EAAI;AAAA,YAAA;AAMb,mBAAKV,IAGH,gBAAAmB,EAACO,GAAA,EAAsB,aAAaH,MAAUpB,GAC5C,UAAA;AAAA,cAAA,gBAAAkB,EAACM,GAAA,EAAe,QAAQF,EAAA,CAAS;AAAA,cACjC,gBAAAN;AAAA,gBAACS;AAAA,gBAAA;AAAA,kBAGC,cAAYrB;AAAA,kBACZ,WAAWa;AAAA,oBACT;AAAA,oBACA,CAACnB,KAAkB;AAAA,kBAAA;AAAA,kBAGrB,UAAA;AAAA,oBAAA,gBAAAoB,EAACC,GAAA,EAAW,IAAIf,GAAS,QAAAV,EAAA,CAAgB;AAAA,oBACxCI,IACCA,EAAe;AAAA,sBACb,KAAKS,EAAI;AAAA,sBACT,OAAOA,EAAI;AAAA,sBACX,OAAOC,EAASD,EAAI,GAAG;AAAA,sBACvB,SAASO,EAAMP,EAAI,KAAK;AAAA,sBACxB,OAAAc;AAAA,oBAAA,CACD,IAED,gBAAAL,EAAAU,GAAA,EACE,UAAA;AAAA,sBAAA,gBAAAR;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BACC,WAAU;AAAA,0BACV,OAAO,EAAE,iBAAiBG,EAAA;AAAA,wBAAM;AAAA,sBAAA;AAAA,wCAEjC,QAAA,EAAK,WAAU,iBAAiB,UAAAb,EAASD,EAAI,GAAG,GAAE;AAAA,sBACnD,gBAAAS,EAAC,QAAA,EAAK,WAAU,sCACb,UAAA;AAAA,wBAAAjB,EAAeQ,EAAI,KAAK;AAAA,wBAAE;AAAA,wBAAIO,EAAMP,EAAI,KAAK;AAAA,wBAAE;AAAA,sBAAA,EAAA,CAClD;AAAA,oBAAA,EAAA,CACF;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YAEJ,EAAA,GAhCYA,EAAI,GAiClB,IApCuBe;AAAA,UAsC3B,CAAC,EAAA,CACH;AAAA,UAEC1B,KACC,gBAAAsB,EAAC,MAAA,EAAG,WAAU,kDACX,UAAAzB,EAAK,IAAI,CAACc,MACT,gBAAAS,EAAC,MAAA,EAAiB,WAAU,yBAC1B,UAAA;AAAA,YAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,wEACd,UAAA;AAAA,cAAA,gBAAAE;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO,EAAE,iBAAiBL,EAAQN,EAAI,GAAG,EAAA;AAAA,gBAAE;AAAA,cAAA;AAAA,cAE5CC,EAASD,EAAI,GAAG;AAAA,YAAA,GACnB;AAAA,YACA,gBAAAS,EAAC,QAAA,EAAK,WAAU,yDACd,UAAA;AAAA,cAAA,gBAAAE,EAAC,UAAK,WAAU,2CACb,UAAAnB,EAAeQ,EAAI,KAAK,GAC3B;AAAA,cACA,gBAAAS,EAAC,QAAA,EAAK,WAAU,iCACb,UAAA;AAAA,gBAAAF,EAAMP,EAAI,KAAK;AAAA,gBAAE;AAAA,cAAA,EAAA,CACpB;AAAA,YAAA,EAAA,CACF;AAAA,UAAA,KAfOA,EAAI,GAgBb,CACD,EAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AACAjB,EAAY,cAAc;"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
function i(t) {
|
|
2
|
+
switch (t) {
|
|
3
|
+
case "auto":
|
|
4
|
+
return ["auto", "auto"];
|
|
5
|
+
case "zero":
|
|
6
|
+
return [0, "auto"];
|
|
7
|
+
case "dataMin-dataMax":
|
|
8
|
+
return ["dataMin", "dataMax"];
|
|
9
|
+
default:
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const r = (t) => {
|
|
14
|
+
if (typeof t == "string" && t.trim() === "") return null;
|
|
15
|
+
const n = typeof t == "number" ? t : Number(t);
|
|
16
|
+
return Number.isFinite(n) ? n : null;
|
|
17
|
+
}, u = (t) => {
|
|
18
|
+
const n = r(t);
|
|
19
|
+
return n === null ? String(t) : new Intl.NumberFormat("en", {
|
|
20
|
+
notation: "compact",
|
|
21
|
+
maximumFractionDigits: 1
|
|
22
|
+
}).format(n);
|
|
23
|
+
}, c = (t) => {
|
|
24
|
+
const n = r(t);
|
|
25
|
+
return n === null ? String(t) : `${n}%`;
|
|
26
|
+
};
|
|
27
|
+
function m(t, n = "en") {
|
|
28
|
+
const a = new Intl.NumberFormat(n, t);
|
|
29
|
+
return (o) => {
|
|
30
|
+
const e = r(o);
|
|
31
|
+
return e === null ? String(o) : a.format(e);
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
m as createTickFormatter,
|
|
36
|
+
u as formatCompactNumber,
|
|
37
|
+
c as formatPercent,
|
|
38
|
+
i as resolveAxisDomain
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=chart-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-format.js","sources":["../../../../src/components/ui/chart/chart-format.ts"],"sourcesContent":["// Shared axis helpers for the cartesian chart components (BarChart, LineChart,\n// AreaChart, ComposedChart, ScatterChart, ConfidenceCone, Histogram). Three\n// concerns live here so every chart formats + toggles axes the same way rather\n// than each reimplementing it:\n//\n// 1. `CartesianChartProps` — the common axis knobs each cartesian chart mixes\n// into its own props (show/hide either axis, per-axis tick formatting).\n// 2. A small set of tick formatters (+ a factory) callers pass to\n// `xTickFormatter` / `yTickFormatter`.\n// 3. `resolveAxisDomain` — maps the `yAxisDomain` preset to a recharts\n// `domain`, shared so all 7 charts can't drift apart on it.\n//\n// These format only the axis *tick labels*; series colors and tokens are\n// unaffected. Formatters coerce to a number and pass non-numeric values through\n// untouched (a category axis stays readable if a formatter is applied to it).\n\nimport type { AxisDomainItem } from 'recharts';\n\nimport type { ChartTooltipContentType } from './chart';\n\n/** A recharts-compatible tick formatter: `(value, index) => label`. */\nexport type TickFormatter = (value: number | string, index?: number) => string;\n\n/**\n * Props shared by every cartesian chart (Bar, Line, Area, Composed, Scatter,\n * ConfidenceCone, Histogram) — chrome toggles, axis titles/units, tick\n * formatting/visibility, and grid trim. All optional. `showLegend` and `xUnit`\n * are deliberately *not* here: `showLegend` doesn't apply to `Histogram` and\n * `xUnit` only to charts with a numeric X axis, so they stay per-component.\n */\nexport interface CartesianChartProps {\n /** Render the CartesianGrid. Defaults to `true`. */\n showGrid?: boolean;\n /** Render the hover tooltip. Defaults to `true`. */\n showTooltip?: boolean;\n /**\n * Replace the default tooltip. Pass a configured `ChartTooltipContent` (from\n * this library) — e.g. with a `formatter` / `labelFormatter` — to customize it\n * without composing recharts yourself. Ignored when `showTooltip` is false.\n */\n tooltipContent?: ChartTooltipContentType;\n /** Title rendered beneath the X axis. */\n xAxisLabel?: string;\n /** Title rendered beside the Y axis (rotated). */\n yAxisLabel?: string;\n /**\n * Unit suffix appended to the Y axis's tick values (recharts `unit`) — applies\n * when the Y axis is the numeric one. `BarChart` with\n * `orientation=\"horizontal\"` puts the values on X instead; use `xUnit` there.\n */\n yUnit?: string;\n /** Show the X axis (its ticks + title). Defaults to `true`. */\n showXAxis?: boolean;\n /** Show the Y axis (its ticks + title). Defaults to `true`. */\n showYAxis?: boolean;\n /** Format each X-axis tick value — e.g. `formatCompactNumber` or a `createTickFormatter(...)`. */\n xTickFormatter?: TickFormatter;\n /** Format each Y-axis tick value — e.g. `formatCompactNumber` or a `createTickFormatter(...)`. */\n yTickFormatter?: TickFormatter;\n /**\n * Rotate the X-axis tick labels by this many degrees. A negative angle (e.g.\n * `-45`) tilts them up toward the right; the tick anchor + axis height adjust\n * to keep long labels readable.\n */\n xAxisAngle?: number;\n /**\n * X-axis tick density — a recharts placement strategy, or a fixed number of\n * ticks to *skip* between two rendered ones (recharts `interval`: `0` shows\n * every tick, `1` every other one, `2` every third, …).\n */\n xAxisInterval?:\n | number\n | 'preserveStart'\n | 'preserveEnd'\n | 'preserveStartEnd'\n | 'equidistantPreserveStart';\n /**\n * Desired number of ticks on the value axis (recharts `tickCount`; a hint, not\n * exact). Applies to whichever axis holds the values — Y for most charts, X for\n * `BarChart` with `orientation=\"horizontal\"`.\n */\n yAxisTickCount?: number;\n /**\n * Value-axis domain preset. Applies to whichever axis holds the values — Y for\n * most charts, X for `BarChart` with `orientation=\"horizontal\"`.\n *\n * - `auto` — fit the data at both ends; the axis need not include 0.\n * - `zero` — anchor the axis at 0. This is also recharts' behavior when the\n * prop is omitted, so it's the explicit form of the default.\n * - `dataMin-dataMax` — tight to the data, with no padding.\n */\n yAxisDomain?: 'auto' | 'dataMin-dataMax' | 'zero';\n /** Draw grid lines dashed instead of solid. */\n gridDashed?: boolean;\n /** Show horizontal grid lines. Defaults to each chart's own default when unset. */\n gridHorizontal?: boolean;\n /** Show vertical grid lines. Defaults to each chart's own default when unset. */\n gridVertical?: boolean;\n}\n\n/**\n * Map a `yAxisDomain` preset to a recharts `domain`. Shared by all 7 cartesian\n * charts, and applied to whichever axis holds the values (X for horizontal bars).\n *\n * `undefined` (no preset) is left to recharts, whose default is `[0, 'auto']` —\n * i.e. already zero-anchored. That's why `auto` has to be spelled out as\n * `['auto', 'auto']`: passing `undefined` for it would silently anchor at 0 and\n * make the preset indistinguishable from `zero`.\n */\nexport function resolveAxisDomain(\n preset: 'auto' | 'dataMin-dataMax' | 'zero' | undefined\n): Readonly<[AxisDomainItem, AxisDomainItem]> | undefined {\n switch (preset) {\n case 'auto':\n return ['auto', 'auto'];\n case 'zero':\n return [0, 'auto'];\n case 'dataMin-dataMax':\n return ['dataMin', 'dataMax'];\n default:\n return undefined;\n }\n}\n\nconst toNumber = (value: number | string): number | null => {\n // `Number('')` and `Number(' ')` are 0, not NaN — so blank strings have to be\n // rejected before the finite check, or an empty tick label would render \"0\".\n if (typeof value === 'string' && value.trim() === '') return null;\n const n = typeof value === 'number' ? value : Number(value);\n return Number.isFinite(n) ? n : null;\n};\n\n/**\n * Compact thousands/millions: `1234 → \"1.2K\"`, `1_500_000 → \"1.5M\"`. Non-numeric\n * values (including blank strings) pass through unchanged. Use for large-count\n * axes (revenue, users, …).\n *\n * Formats in `en`. For another locale use\n * `createTickFormatter({ notation: 'compact', maximumFractionDigits: 1 }, locale)`.\n */\nexport const formatCompactNumber: TickFormatter = (value) => {\n const n = toNumber(value);\n if (n === null) return String(value);\n return new Intl.NumberFormat('en', {\n notation: 'compact',\n maximumFractionDigits: 1,\n }).format(n);\n};\n\n/**\n * Append a percent sign to an already-scaled value: `41.8 → \"41.8%\"`. (The value\n * is treated as a percentage, not a 0–1 fraction.) Non-numeric values (including\n * blank strings) pass through.\n *\n * Appends a bare `%`, which is not how every locale writes it. For locale-correct\n * output on values that really are fractions, use\n * `createTickFormatter({ style: 'percent' }, locale)`.\n */\nexport const formatPercent: TickFormatter = (value) => {\n const n = toNumber(value);\n if (n === null) return String(value);\n return `${n}%`;\n};\n\n/**\n * Build a tick formatter from `Intl.NumberFormat` options — the escape hatch for\n * currency, fixed decimals, or a specific locale. E.g.\n * `createTickFormatter({ style: 'currency', currency: 'USD', notation: 'compact' })`\n * → `146500 → \"$147K\"`. Non-numeric values pass through unchanged.\n */\nexport function createTickFormatter(\n options: Intl.NumberFormatOptions,\n locale = 'en'\n): TickFormatter {\n const nf = new Intl.NumberFormat(locale, options);\n return (value) => {\n const n = toNumber(value);\n return n === null ? String(value) : nf.format(n);\n };\n}\n"],"names":["resolveAxisDomain","preset","toNumber","value","formatCompactNumber","formatPercent","createTickFormatter","options","locale","nf","n"],"mappings":"AA6GO,SAASA,EACdC,GACwD;AACxD,UAAQA,GAAA;AAAA,IACN,KAAK;AACH,aAAO,CAAC,QAAQ,MAAM;AAAA,IACxB,KAAK;AACH,aAAO,CAAC,GAAG,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,CAAC,WAAW,SAAS;AAAA,IAC9B;AACE;AAAA,EAAO;AAEb;AAEA,MAAMC,IAAW,CAACC,MAA0C;AAG1D,MAAI,OAAOA,KAAU,YAAYA,EAAM,KAAA,MAAW,GAAI,QAAO;AAC7D,QAAM,IAAI,OAAOA,KAAU,WAAWA,IAAQ,OAAOA,CAAK;AAC1D,SAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAClC,GAUaC,IAAqC,CAACD,MAAU;AAC3D,QAAM,IAAID,EAASC,CAAK;AACxB,SAAI,MAAM,OAAa,OAAOA,CAAK,IAC5B,IAAI,KAAK,aAAa,MAAM;AAAA,IACjC,UAAU;AAAA,IACV,uBAAuB;AAAA,EAAA,CACxB,EAAE,OAAO,CAAC;AACb,GAWaE,IAA+B,CAACF,MAAU;AACrD,QAAM,IAAID,EAASC,CAAK;AACxB,SAAI,MAAM,OAAa,OAAOA,CAAK,IAC5B,GAAG,CAAC;AACb;AAQO,SAASG,EACdC,GACAC,IAAS,MACM;AACf,QAAMC,IAAK,IAAI,KAAK,aAAaD,GAAQD,CAAO;AAChD,SAAO,CAACJ,MAAU;AAChB,UAAMO,IAAIR,EAASC,CAAK;AACxB,WAAOO,MAAM,OAAO,OAAOP,CAAK,IAAIM,EAAG,OAAOC,CAAC;AAAA,EACjD;AACF;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart.js","sources":["../../../../src/components/ui/chart/chart.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport * as RechartsPrimitive from 'recharts';\nimport type { LegendPayload } from 'recharts/types/component/DefaultLegendContent';\nimport {\n NameType,\n Payload,\n ValueType,\n} from 'recharts/types/component/DefaultTooltipContent';\nimport type { Props as LegendProps } from 'recharts/types/component/Legend';\nimport { TooltipContentProps } from 'recharts/types/component/Tooltip';\n\nimport { cn } from '@/lib/utils';\n\n// Format: { THEME_NAME: CSS_SELECTOR }. ui-react flips light/dark via the\n// `[data-theme]` attribute (the tokens resolve `light-dark()` through\n// `color-scheme`), not the legacy `.dark` class — so per-series `theme` colors\n// scope their dark value under `[data-theme='dark']`.\nconst THEMES = { light: '', dark: \"[data-theme='dark']\" } as const;\n\nexport type ChartConfig = {\n [k in string]: {\n label?: React.ReactNode;\n icon?: React.ComponentType;\n } & (\n | { color?: string; theme?: never }\n | { color?: never; theme: Record<keyof typeof THEMES, string> }\n );\n};\n\ntype ChartContextProps = {\n config: ChartConfig;\n};\n\nexport type ChartTooltipContentProps = Partial<\n TooltipContentProps<ValueType, NameType>\n> & {\n className?: string;\n hideLabel?: boolean;\n hideIndicator?: boolean;\n indicator?: 'line' | 'dot' | 'dashed';\n nameKey?: string;\n labelKey?: string;\n labelFormatter?: (\n label: TooltipContentProps<number, string>['label'],\n payload: TooltipContentProps<number, string>['payload']\n ) => React.ReactNode;\n formatter?: (\n value: number | string,\n name: string,\n item: Payload<number | string, string>,\n index: number,\n payload: ReadonlyArray<Payload<number | string, string>>\n ) => React.ReactNode;\n labelClassName?: string;\n color?: string;\n};\n\nexport type ChartLegendContentProps = {\n className?: string;\n hideIcon?: boolean;\n verticalAlign?: LegendProps['verticalAlign'];\n payload?: LegendPayload[];\n nameKey?: string;\n};\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null);\n\nfunction useChart() {\n const context = React.useContext(ChartContext);\n\n if (!context) {\n throw new Error('useChart must be used within a <ChartContainer />');\n }\n\n return context;\n}\n\nexport interface ChartContainerProps extends React.ComponentProps<'div'> {\n config: ChartConfig;\n children: React.ComponentProps<\n typeof RechartsPrimitive.ResponsiveContainer\n >['children'];\n}\n\nfunction ChartContainer({\n id,\n className,\n children,\n config,\n ...props\n}: ChartContainerProps) {\n const uniqueId = React.useId();\n const chartId = `chart-${id || uniqueId.replace(/:/g, '')}`;\n\n return (\n <ChartContext.Provider value={{ config }}>\n <div\n id={id}\n data-slot=\"chart\"\n data-chart={chartId}\n className={cn(\n \"[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden\",\n className\n )}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <RechartsPrimitive.ResponsiveContainer>\n {children}\n </RechartsPrimitive.ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n );\n}\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(\n ([, config]) => config.theme || config.color\n );\n\n if (!colorConfig.length) {\n return null;\n }\n\n // Rendered as a text child (not dangerouslySetInnerHTML): React sets it via\n // textContent, which the browser does not HTML-parse, so a `</style>` in a\n // config color can't break out of the tag.\n return (\n <style>\n {Object.entries(THEMES)\n .map(\n ([theme, prefix]) => `\n ${prefix} [data-chart=${id}] {\n ${colorConfig\n .map(([key, itemConfig]) => {\n const color =\n itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||\n itemConfig.color;\n return color ? ` --color-${key}: ${color};` : null;\n })\n .join('\\n')}\n }\n `\n )\n .join('\\n')}\n </style>\n );\n};\n\nconst ChartTooltip = RechartsPrimitive.Tooltip;\n\nfunction ChartTooltipContent({\n active,\n payload,\n label,\n className,\n indicator = 'dot',\n hideLabel = false,\n hideIndicator = false,\n labelFormatter,\n formatter,\n labelClassName,\n color,\n nameKey,\n labelKey,\n}: ChartTooltipContentProps) {\n const { config } = useChart();\n\n const tooltipLabel = React.useMemo(() => {\n if (hideLabel || !payload?.length) {\n return null;\n }\n\n const [item] = payload;\n const key = `${labelKey || item?.dataKey || item?.name || 'value'}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const value = (() => {\n const v =\n !labelKey && typeof label === 'string'\n ? (config[label as keyof typeof config]?.label ?? label)\n : itemConfig?.label;\n\n return typeof v === 'string' || typeof v === 'number' ? v : undefined;\n })();\n\n if (labelFormatter) {\n return (\n <div className={cn('font-medium', labelClassName)}>\n {labelFormatter(value, payload)}\n </div>\n );\n }\n\n if (!value) {\n return null;\n }\n\n return <div className={cn('font-medium', labelClassName)}>{value}</div>;\n }, [\n label,\n labelFormatter,\n payload,\n hideLabel,\n labelClassName,\n config,\n labelKey,\n ]);\n\n if (!active || !payload?.length) {\n return null;\n }\n\n const nestLabel = payload.length === 1 && indicator !== 'dot';\n\n return (\n <div\n className={cn(\n 'grid min-w-[8rem] items-start gap-1.5 rounded-[var(--ui-tooltip-container-border-radius)] border border-border bg-background px-[var(--ui-tooltip-container-padding-x)] py-[var(--ui-tooltip-container-padding-y)] text-xs text-foreground shadow-md',\n className\n )}\n >\n {!nestLabel ? tooltipLabel : null}\n <div className=\"grid gap-1.5\">\n {payload.map((item, index) => {\n const key = `${nameKey || item.name || item.dataKey || 'value'}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const indicatorColor = color || item.payload.fill || item.color;\n\n return (\n <div\n key={key}\n className={cn(\n 'flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground',\n indicator === 'dot' && 'items-center'\n )}\n >\n {formatter && item?.value !== undefined && item.name ? (\n formatter(item.value, item.name, item, index, payload)\n ) : (\n <>\n {itemConfig?.icon ? (\n <itemConfig.icon />\n ) : (\n !hideIndicator && (\n <div\n className={cn(\n 'shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)',\n {\n 'h-2.5 w-2.5': indicator === 'dot',\n 'h-4 w-1': indicator === 'line',\n 'h-4 w-0 border-[1.5px] border-dashed bg-transparent':\n indicator === 'dashed',\n 'my-0.5': nestLabel && indicator === 'dashed',\n }\n )}\n style={\n {\n '--color-bg': indicatorColor,\n '--color-border': indicatorColor,\n } as React.CSSProperties\n }\n />\n )\n )}\n <div\n className={cn(\n 'flex flex-1 justify-between leading-none',\n nestLabel ? 'items-end' : 'items-center'\n )}\n >\n <div className=\"grid gap-1.5\">\n {nestLabel ? tooltipLabel : null}\n <span className=\"text-muted-foreground\">\n {itemConfig?.label || item.name}\n </span>\n </div>\n {item.value != null && (\n <span className=\"font-medium tabular-nums text-foreground\">\n {item.value.toLocaleString()}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nconst ChartLegend = RechartsPrimitive.Legend;\n\nfunction ChartLegendContent({\n className,\n hideIcon = false,\n payload,\n verticalAlign = 'bottom',\n nameKey,\n}: ChartLegendContentProps) {\n const { config } = useChart();\n\n if (!payload?.length) {\n return null;\n }\n\n return (\n <div\n className={cn(\n 'flex items-center justify-center gap-4',\n verticalAlign === 'top' ? 'pb-3' : 'pt-3',\n className\n )}\n >\n {payload.map((item) => {\n const key = `${nameKey || item.dataKey || 'value'}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n\n return (\n <div\n key={item.value}\n className={cn(\n 'flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground'\n )}\n >\n {itemConfig?.icon && !hideIcon ? (\n <itemConfig.icon />\n ) : (\n <div\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n style={{\n backgroundColor: item.color,\n }}\n />\n )}\n {itemConfig?.label}\n </div>\n );\n })}\n </div>\n );\n}\n\n// Helper to extract item config from a payload.\nfunction getPayloadConfigFromPayload(\n config: ChartConfig,\n payload: unknown,\n key: string\n) {\n if (typeof payload !== 'object' || payload === null) {\n return undefined;\n }\n\n const payloadPayload =\n 'payload' in payload &&\n typeof payload.payload === 'object' &&\n payload.payload !== null\n ? payload.payload\n : undefined;\n\n let configLabelKey: string = key;\n\n if (\n key in payload &&\n typeof payload[key as keyof typeof payload] === 'string'\n ) {\n configLabelKey = payload[key as keyof typeof payload] as string;\n } else if (\n payloadPayload &&\n key in payloadPayload &&\n typeof payloadPayload[key as keyof typeof payloadPayload] === 'string'\n ) {\n configLabelKey = payloadPayload[\n key as keyof typeof payloadPayload\n ] as string;\n }\n\n return configLabelKey in config\n ? config[configLabelKey]\n : config[key as keyof typeof config];\n}\n\nexport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n};\n"],"names":["THEMES","ChartContext","React","useChart","context","ChartContainer","id","className","children","config","props","uniqueId","chartId","jsxs","cn","jsx","ChartStyle","RechartsPrimitive","colorConfig","theme","prefix","key","itemConfig","color","_a","ChartTooltip","ChartTooltipContent","active","payload","label","indicator","hideLabel","hideIndicator","labelFormatter","formatter","labelClassName","nameKey","labelKey","tooltipLabel","item","getPayloadConfigFromPayload","value","v","nestLabel","index","indicatorColor","Fragment","ChartLegend","ChartLegendContent","hideIcon","verticalAlign","payloadPayload","configLabelKey"],"mappings":";;;;AAmBA,MAAMA,IAAS,EAAE,OAAO,IAAI,MAAM,sBAAA,GAgD5BC,IAAeC,EAAM,cAAwC,IAAI;AAEvE,SAASC,IAAW;AAClB,QAAMC,IAAUF,EAAM,WAAWD,CAAY;AAE7C,MAAI,CAACG;AACH,UAAM,IAAI,MAAM,mDAAmD;AAGrE,SAAOA;AACT;AASA,SAASC,EAAe;AAAA,EACtB,IAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,GAAGC;AACL,GAAwB;AACtB,QAAMC,IAAWT,EAAM,MAAA,GACjBU,IAAU,SAASN,KAAMK,EAAS,QAAQ,MAAM,EAAE,CAAC;AAEzD,2BACGV,EAAa,UAAb,EAAsB,OAAO,EAAE,QAAAQ,KAC9B,UAAA,gBAAAI;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,IAAAP;AAAA,MACA,aAAU;AAAA,MACV,cAAYM;AAAA,MACZ,WAAWE;AAAA,QACT;AAAA,QACAP;AAAA,MAAA;AAAA,MAED,GAAGG;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAK,EAACC,GAAA,EAAW,IAAIJ,GAAS,QAAAH,EAAA,CAAgB;AAAA,QACzC,gBAAAM,EAACE,EAAkB,qBAAlB,EACE,UAAAT,EAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ;AAEA,MAAMQ,IAAa,CAAC,EAAE,IAAAV,GAAI,QAAAG,QAAkD;AAC1E,QAAMS,IAAc,OAAO,QAAQT,CAAM,EAAE;AAAA,IACzC,CAAC,CAAA,EAAGA,CAAM,MAAMA,EAAO,SAASA,EAAO;AAAA,EAAA;AAGzC,SAAKS,EAAY,SAQf,gBAAAH,EAAC,SAAA,EACE,UAAA,OAAO,QAAQf,CAAM,EACnB;AAAA,IACC,CAAC,CAACmB,GAAOC,CAAM,MAAM;AAAA,cACjBA,CAAM,gBAAgBd,CAAE;AAAA,cACxBY,EACC,IAAI,CAAC,CAACG,GAAKC,CAAU,MAAM;;AAC1B,YAAMC,MACJC,IAAAF,EAAW,UAAX,gBAAAE,EAAmBL,OACnBG,EAAW;AACb,aAAOC,IAAQ,aAAaF,CAAG,KAAKE,CAAK,MAAM;AAAA,IACjD,CAAC,EACA,KAAK;AAAA,CAAI,CAAC;AAAA;AAAA;AAAA,EAAA,EAIhB,KAAK;AAAA,CAAI,GACd,IAxBO;AA0BX,GAEME,IAAeR,EAAkB;AAEvC,SAASS,EAAoB;AAAA,EAC3B,QAAAC;AAAA,EACA,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAtB;AAAA,EACA,WAAAuB,IAAY;AAAA,EACZ,WAAAC,IAAY;AAAA,EACZ,eAAAC,IAAgB;AAAA,EAChB,gBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,OAAAZ;AAAA,EACA,SAAAa;AAAA,EACA,UAAAC;AACF,GAA6B;AAC3B,QAAM,EAAE,QAAA5B,EAAA,IAAWN,EAAA,GAEbmC,IAAepC,EAAM,QAAQ,MAAM;AACvC,QAAI6B,KAAa,EAACH,KAAA,QAAAA,EAAS;AACzB,aAAO;AAGT,UAAM,CAACW,CAAI,IAAIX,GACTP,IAAM,GAAGgB,MAAYE,KAAA,gBAAAA,EAAM,aAAWA,KAAA,gBAAAA,EAAM,SAAQ,OAAO,IAC3DjB,IAAakB,EAA4B/B,GAAQ8B,GAAMlB,CAAG,GAC1DoB,KAAS,MAAM;;AACnB,YAAMC,IACJ,CAACL,KAAY,OAAOR,KAAU,aACzBL,IAAAf,EAAOoB,CAA4B,MAAnC,gBAAAL,EAAsC,UAASK,IAChDP,KAAA,gBAAAA,EAAY;AAElB,aAAO,OAAOoB,KAAM,YAAY,OAAOA,KAAM,WAAWA,IAAI;AAAA,IAC9D,GAAA;AAEA,WAAIT,IAEA,gBAAAlB,EAAC,OAAA,EAAI,WAAWD,EAAG,eAAeqB,CAAc,GAC7C,UAAAF,EAAeQ,GAAOb,CAAO,EAAA,CAChC,IAICa,sBAIG,OAAA,EAAI,WAAW3B,EAAG,eAAeqB,CAAc,GAAI,UAAAM,GAAM,IAHxD;AAAA,EAIX,GAAG;AAAA,IACDZ;AAAA,IACAI;AAAA,IACAL;AAAA,IACAG;AAAA,IACAI;AAAA,IACA1B;AAAA,IACA4B;AAAA,EAAA,CACD;AAED,MAAI,CAACV,KAAU,EAACC,KAAA,QAAAA,EAAS;AACvB,WAAO;AAGT,QAAMe,IAAYf,EAAQ,WAAW,KAAKE,MAAc;AAExD,SACE,gBAAAjB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC;AAAA,QACT;AAAA,QACAP;AAAA,MAAA;AAAA,MAGD,UAAA;AAAA,QAACoC,IAA2B,OAAfL;AAAA,QACd,gBAAAvB,EAAC,SAAI,WAAU,gBACZ,YAAQ,IAAI,CAACwB,GAAMK,MAAU;AAC5B,gBAAMvB,IAAM,GAAGe,KAAWG,EAAK,QAAQA,EAAK,WAAW,OAAO,IACxDjB,IAAakB,EAA4B/B,GAAQ8B,GAAMlB,CAAG,GAC1DwB,IAAiBtB,KAASgB,EAAK,QAAQ,QAAQA,EAAK;AAE1D,iBACE,gBAAAxB;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAWD;AAAA,gBACT;AAAA,gBACAgB,MAAc,SAAS;AAAA,cAAA;AAAA,cAGxB,UAAAI,MAAaK,KAAA,gBAAAA,EAAM,WAAU,UAAaA,EAAK,OAC9CL,EAAUK,EAAK,OAAOA,EAAK,MAAMA,GAAMK,GAAOhB,CAAO,IAErD,gBAAAf,EAAAiC,GAAA,EACG,UAAA;AAAA,gBAAAxB,KAAA,QAAAA,EAAY,OACX,gBAAAP,EAACO,EAAW,MAAX,EAAgB,IAEjB,CAACU,KACC,gBAAAjB;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAWD;AAAA,sBACT;AAAA,sBACA;AAAA,wBACE,eAAegB,MAAc;AAAA,wBAC7B,WAAWA,MAAc;AAAA,wBACzB,uDACEA,MAAc;AAAA,wBAChB,UAAUa,KAAab,MAAc;AAAA,sBAAA;AAAA,oBACvC;AAAA,oBAEF,OACE;AAAA,sBACE,cAAce;AAAA,sBACd,kBAAkBA;AAAA,oBAAA;AAAA,kBACpB;AAAA,gBAAA;AAAA,gBAKR,gBAAAhC;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,WAAWC;AAAA,sBACT;AAAA,sBACA6B,IAAY,cAAc;AAAA,oBAAA;AAAA,oBAG5B,UAAA;AAAA,sBAAA,gBAAA9B,EAAC,OAAA,EAAI,WAAU,gBACZ,UAAA;AAAA,wBAAA8B,IAAYL,IAAe;AAAA,0CAC3B,QAAA,EAAK,WAAU,yBACb,WAAAhB,KAAA,gBAAAA,EAAY,UAASiB,EAAK,KAAA,CAC7B;AAAA,sBAAA,GACF;AAAA,sBACCA,EAAK,SAAS,QACb,gBAAAxB,EAAC,QAAA,EAAK,WAAU,4CACb,UAAAwB,EAAK,MAAM,eAAA,EAAe,CAC7B;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAEJ,EAAA,CACF;AAAA,YAAA;AAAA,YApDGlB;AAAA,UAAA;AAAA,QAwDX,CAAC,EAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,MAAM0B,IAAc9B,EAAkB;AAEtC,SAAS+B,EAAmB;AAAA,EAC1B,WAAAzC;AAAA,EACA,UAAA0C,IAAW;AAAA,EACX,SAAArB;AAAA,EACA,eAAAsB,IAAgB;AAAA,EAChB,SAAAd;AACF,GAA4B;AAC1B,QAAM,EAAE,QAAA3B,EAAA,IAAWN,EAAA;AAEnB,SAAKyB,KAAA,QAAAA,EAAS,SAKZ,gBAAAb;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWD;AAAA,QACT;AAAA,QACAoC,MAAkB,QAAQ,SAAS;AAAA,QACnC3C;AAAA,MAAA;AAAA,MAGD,UAAAqB,EAAQ,IAAI,CAACW,MAAS;AACrB,cAAMlB,IAAM,GAAGe,KAAWG,EAAK,WAAW,OAAO,IAC3CjB,IAAakB,EAA4B/B,GAAQ8B,GAAMlB,CAAG;AAEhE,eACE,gBAAAR;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAWC;AAAA,cACT;AAAA,YAAA;AAAA,YAGD,UAAA;AAAA,cAAAQ,KAAA,QAAAA,EAAY,QAAQ,CAAC2B,sBACnB3B,EAAW,MAAX,CAAA,CAAgB,IAEjB,gBAAAP;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,iBAAiBwB,EAAK;AAAA,kBAAA;AAAA,gBACxB;AAAA,cAAA;AAAA,cAGHjB,KAAA,gBAAAA,EAAY;AAAA,YAAA;AAAA,UAAA;AAAA,UAfRiB,EAAK;AAAA,QAAA;AAAA,MAkBhB,CAAC;AAAA,IAAA;AAAA,EAAA,IAnCI;AAsCX;AAGA,SAASC,EACP/B,GACAmB,GACAP,GACA;AACA,MAAI,OAAOO,KAAY,YAAYA,MAAY;AAC7C;AAGF,QAAMuB,IACJ,aAAavB,KACb,OAAOA,EAAQ,WAAY,YAC3BA,EAAQ,YAAY,OAChBA,EAAQ,UACR;AAEN,MAAIwB,IAAyB/B;AAE7B,SACEA,KAAOO,KACP,OAAOA,EAAQP,CAA2B,KAAM,WAEhD+B,IAAiBxB,EAAQP,CAA2B,IAEpD8B,KACA9B,KAAO8B,KACP,OAAOA,EAAe9B,CAAkC,KAAM,aAE9D+B,IAAiBD,EACf9B,CACF,IAGK+B,KAAkB3C,IACrBA,EAAO2C,CAAc,IACrB3C,EAAOY,CAA0B;AACvC;"}
|
|
1
|
+
{"version":3,"file":"chart.js","sources":["../../../../src/components/ui/chart/chart.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport * as RechartsPrimitive from 'recharts';\nimport type { LegendPayload } from 'recharts/types/component/DefaultLegendContent';\nimport {\n NameType,\n Payload,\n ValueType,\n} from 'recharts/types/component/DefaultTooltipContent';\nimport type { Props as LegendProps } from 'recharts/types/component/Legend';\nimport { TooltipContentProps } from 'recharts/types/component/Tooltip';\n\nimport { cn } from '@/lib/utils';\n\n// Format: { THEME_NAME: CSS_SELECTOR }. ui-react flips light/dark via the\n// `[data-theme]` attribute (the tokens resolve `light-dark()` through\n// `color-scheme`), not the legacy `.dark` class — so per-series `theme` colors\n// scope their dark value under `[data-theme='dark']`.\nconst THEMES = { light: '', dark: \"[data-theme='dark']\" } as const;\n\nexport type ChartConfig = {\n [k in string]: {\n label?: React.ReactNode;\n icon?: React.ComponentType;\n } & (\n | { color?: string; theme?: never }\n | { color?: never; theme: Record<keyof typeof THEMES, string> }\n );\n};\n\ntype ChartContextProps = {\n config: ChartConfig;\n};\n\nexport type ChartTooltipContentProps = Partial<\n TooltipContentProps<ValueType, NameType>\n> & {\n className?: string;\n hideLabel?: boolean;\n hideIndicator?: boolean;\n indicator?: 'line' | 'dot' | 'dashed';\n nameKey?: string;\n labelKey?: string;\n labelFormatter?: (\n label: TooltipContentProps<number, string>['label'],\n payload: TooltipContentProps<number, string>['payload']\n ) => React.ReactNode;\n formatter?: (\n value: number | string,\n name: string,\n item: Payload<number | string, string>,\n index: number,\n payload: ReadonlyArray<Payload<number | string, string>>\n ) => React.ReactNode;\n labelClassName?: string;\n color?: string;\n};\n\nexport type ChartLegendContentProps = {\n className?: string;\n hideIcon?: boolean;\n verticalAlign?: LegendProps['verticalAlign'];\n payload?: LegendPayload[];\n nameKey?: string;\n};\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null);\n\nfunction useChart() {\n const context = React.useContext(ChartContext);\n\n if (!context) {\n throw new Error('useChart must be used within a <ChartContainer />');\n }\n\n return context;\n}\n\nexport interface ChartContainerProps extends React.ComponentProps<'div'> {\n config: ChartConfig;\n children: React.ComponentProps<\n typeof RechartsPrimitive.ResponsiveContainer\n >['children'];\n}\n\nfunction ChartContainer({\n id,\n className,\n children,\n config,\n ...props\n}: ChartContainerProps) {\n const uniqueId = React.useId();\n const chartId = `chart-${id || uniqueId.replace(/:/g, '')}`;\n\n return (\n <ChartContext.Provider value={{ config }}>\n <div\n id={id}\n data-slot=\"chart\"\n data-chart={chartId}\n className={cn(\n \"[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden\",\n className\n )}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <RechartsPrimitive.ResponsiveContainer>\n {children}\n </RechartsPrimitive.ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n );\n}\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(\n ([, config]) => config.theme || config.color\n );\n\n if (!colorConfig.length) {\n return null;\n }\n\n // Rendered as a text child (not dangerouslySetInnerHTML): React sets it via\n // textContent, which the browser does not HTML-parse, so a `</style>` in a\n // config color can't break out of the tag.\n return (\n <style>\n {Object.entries(THEMES)\n .map(\n ([theme, prefix]) => `\n ${prefix} [data-chart=${id}] {\n ${colorConfig\n .map(([key, itemConfig]) => {\n const color =\n itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||\n itemConfig.color;\n return color ? ` --color-${key}: ${color};` : null;\n })\n .join('\\n')}\n }\n `\n )\n .join('\\n')}\n </style>\n );\n};\n\nconst ChartTooltip = RechartsPrimitive.Tooltip;\n\n/** The `content` a caller passes to override the default tooltip (recharts' `Tooltip['content']`). */\nexport type ChartTooltipContentType = React.ComponentProps<\n typeof ChartTooltip\n>['content'];\n\nfunction ChartTooltipContent({\n active,\n payload,\n label,\n className,\n indicator = 'dot',\n hideLabel = false,\n hideIndicator = false,\n labelFormatter,\n formatter,\n labelClassName,\n color,\n nameKey,\n labelKey,\n}: ChartTooltipContentProps) {\n const { config } = useChart();\n\n const tooltipLabel = React.useMemo(() => {\n if (hideLabel || !payload?.length) {\n return null;\n }\n\n const [item] = payload;\n const key = `${labelKey || item?.dataKey || item?.name || 'value'}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const value = (() => {\n const v =\n !labelKey && typeof label === 'string'\n ? (config[label as keyof typeof config]?.label ?? label)\n : itemConfig?.label;\n\n return typeof v === 'string' || typeof v === 'number' ? v : undefined;\n })();\n\n if (labelFormatter) {\n return (\n <div className={cn('font-medium', labelClassName)}>\n {labelFormatter(value, payload)}\n </div>\n );\n }\n\n if (!value) {\n return null;\n }\n\n return <div className={cn('font-medium', labelClassName)}>{value}</div>;\n }, [\n label,\n labelFormatter,\n payload,\n hideLabel,\n labelClassName,\n config,\n labelKey,\n ]);\n\n if (!active || !payload?.length) {\n return null;\n }\n\n const nestLabel = payload.length === 1 && indicator !== 'dot';\n\n return (\n <div\n className={cn(\n 'grid min-w-[8rem] items-start gap-1.5 rounded-[var(--ui-tooltip-container-border-radius)] border border-border bg-background px-[var(--ui-tooltip-container-padding-x)] py-[var(--ui-tooltip-container-padding-y)] text-xs text-foreground shadow-md',\n className\n )}\n >\n {!nestLabel ? tooltipLabel : null}\n <div className=\"grid gap-1.5\">\n {payload.map((item, index) => {\n const key = `${nameKey || item.name || item.dataKey || 'value'}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const indicatorColor = color || item.payload.fill || item.color;\n\n return (\n <div\n key={key}\n className={cn(\n 'flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground',\n indicator === 'dot' && 'items-center'\n )}\n >\n {formatter && item?.value !== undefined && item.name ? (\n formatter(item.value, item.name, item, index, payload)\n ) : (\n <>\n {itemConfig?.icon ? (\n <itemConfig.icon />\n ) : (\n !hideIndicator && (\n <div\n className={cn(\n 'shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)',\n {\n 'h-2.5 w-2.5': indicator === 'dot',\n 'h-4 w-1': indicator === 'line',\n 'h-4 w-0 border-[1.5px] border-dashed bg-transparent':\n indicator === 'dashed',\n 'my-0.5': nestLabel && indicator === 'dashed',\n }\n )}\n style={\n {\n '--color-bg': indicatorColor,\n '--color-border': indicatorColor,\n } as React.CSSProperties\n }\n />\n )\n )}\n <div\n className={cn(\n 'flex flex-1 justify-between leading-none',\n nestLabel ? 'items-end' : 'items-center'\n )}\n >\n <div className=\"grid gap-1.5\">\n {nestLabel ? tooltipLabel : null}\n <span className=\"text-muted-foreground\">\n {itemConfig?.label || item.name}\n </span>\n </div>\n {item.value != null && (\n <span className=\"font-medium tabular-nums text-foreground\">\n {item.value.toLocaleString()}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nconst ChartLegend = RechartsPrimitive.Legend;\n\nfunction ChartLegendContent({\n className,\n hideIcon = false,\n payload,\n verticalAlign = 'bottom',\n nameKey,\n}: ChartLegendContentProps) {\n const { config } = useChart();\n\n if (!payload?.length) {\n return null;\n }\n\n return (\n <div\n className={cn(\n 'flex items-center justify-center gap-4',\n verticalAlign === 'top' ? 'pb-3' : 'pt-3',\n className\n )}\n >\n {payload.map((item) => {\n const key = `${nameKey || item.dataKey || 'value'}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n\n return (\n <div\n key={item.value}\n className={cn(\n 'flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground'\n )}\n >\n {itemConfig?.icon && !hideIcon ? (\n <itemConfig.icon />\n ) : (\n <div\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n style={{\n backgroundColor: item.color,\n }}\n />\n )}\n {itemConfig?.label}\n </div>\n );\n })}\n </div>\n );\n}\n\n// Helper to extract item config from a payload.\nfunction getPayloadConfigFromPayload(\n config: ChartConfig,\n payload: unknown,\n key: string\n) {\n if (typeof payload !== 'object' || payload === null) {\n return undefined;\n }\n\n const payloadPayload =\n 'payload' in payload &&\n typeof payload.payload === 'object' &&\n payload.payload !== null\n ? payload.payload\n : undefined;\n\n let configLabelKey: string = key;\n\n if (\n key in payload &&\n typeof payload[key as keyof typeof payload] === 'string'\n ) {\n configLabelKey = payload[key as keyof typeof payload] as string;\n } else if (\n payloadPayload &&\n key in payloadPayload &&\n typeof payloadPayload[key as keyof typeof payloadPayload] === 'string'\n ) {\n configLabelKey = payloadPayload[\n key as keyof typeof payloadPayload\n ] as string;\n }\n\n return configLabelKey in config\n ? config[configLabelKey]\n : config[key as keyof typeof config];\n}\n\nexport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n};\n"],"names":["THEMES","ChartContext","React","useChart","context","ChartContainer","id","className","children","config","props","uniqueId","chartId","jsxs","cn","jsx","ChartStyle","RechartsPrimitive","colorConfig","theme","prefix","key","itemConfig","color","_a","ChartTooltip","ChartTooltipContent","active","payload","label","indicator","hideLabel","hideIndicator","labelFormatter","formatter","labelClassName","nameKey","labelKey","tooltipLabel","item","getPayloadConfigFromPayload","value","v","nestLabel","index","indicatorColor","Fragment","ChartLegend","ChartLegendContent","hideIcon","verticalAlign","payloadPayload","configLabelKey"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsxs as l, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import * as s from "react";
|
|
3
|
+
import { InboxIcon as m, CircleWarningIcon as c } from "@acronis-platform/icons-react/stroke-mono";
|
|
4
|
+
import { cn as p } from "../../../lib/utils.js";
|
|
5
|
+
import { Spinner as d } from "../spinner/spinner.js";
|
|
6
|
+
const f = {
|
|
7
|
+
loading: "Data is loading…",
|
|
8
|
+
empty: "No data found",
|
|
9
|
+
error: "Something went wrong"
|
|
10
|
+
}, g = s.forwardRef(
|
|
11
|
+
({ className: o, state: r, message: i, action: t, ...a }, n) => /* @__PURE__ */ l(
|
|
12
|
+
"div",
|
|
13
|
+
{
|
|
14
|
+
ref: n,
|
|
15
|
+
className: p(
|
|
16
|
+
"flex size-full min-h-32 flex-col items-center justify-center gap-2 text-center text-sm leading-6 text-foreground",
|
|
17
|
+
o
|
|
18
|
+
),
|
|
19
|
+
...a,
|
|
20
|
+
role: r === "error" ? "alert" : "status",
|
|
21
|
+
"aria-live": r === "error" ? "assertive" : "polite",
|
|
22
|
+
children: [
|
|
23
|
+
r === "loading" && /* @__PURE__ */ e(d, { size: "lg", "aria-hidden": !0 }),
|
|
24
|
+
r === "empty" && /* @__PURE__ */ e(m, { size: 24, className: "text-[var(--ui-glyph-on-status-info)]" }),
|
|
25
|
+
r === "error" && /* @__PURE__ */ e(
|
|
26
|
+
c,
|
|
27
|
+
{
|
|
28
|
+
size: 24,
|
|
29
|
+
className: "text-[var(--ui-glyph-on-status-warning)]"
|
|
30
|
+
}
|
|
31
|
+
),
|
|
32
|
+
/* @__PURE__ */ e("p", { children: i ?? f[r] }),
|
|
33
|
+
r === "error" && t
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
);
|
|
38
|
+
g.displayName = "ChartState";
|
|
39
|
+
export {
|
|
40
|
+
g as ChartState
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=chart-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-state.js","sources":["../../../../src/components/ui/chart-state/chart-state.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n CircleWarningIcon,\n InboxIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\nimport { Spinner } from '../spinner';\n\n// A shared loading / empty / error placeholder for the chart types. A chart can\n// only render once recharts' `ResponsiveContainer` has data and real dimensions,\n// so every type needs the same \"there's nothing to plot yet\" surface — this is\n// that surface, dropped in place of the chart inside the same sized slot.\n//\n// Ported from the Figma InputSelect dropdown states (the reference the task\n// points at) and kept visually in step with the shipped `InputSelectStatus`\n// sibling: the empty / error states use the same 24px glyph + `text-sm` label\n// and the same `--ui-glyph-on-status-*` icon tokens. (Loading uses the shared\n// `Spinner` — brand blue, larger — not the sibling's inline gray ring.) No\n// `--ui-chart-*` tier exists yet, so it themes from existing semantic tokens\n// directly:\n// • label -> text-foreground (--ui-text-on-surface-primary)\n// • empty icon -> --ui-glyph-on-status-info\n// • error icon -> --ui-glyph-on-status-warning\n// • loading -> the shared Spinner (brand action blue)\n// The generic full-page `Empty` component is the larger, page-level sibling;\n// this one is compact and fills a chart slot.\n\nconst DEFAULT_MESSAGE: Record<ChartStateProps['state'], string> = {\n loading: 'Data is loading…',\n empty: 'No data found',\n error: 'Something went wrong',\n};\n\nexport interface ChartStateProps\n extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> {\n /** Which placeholder to show. Drives the leading glyph and default label. */\n state: 'loading' | 'empty' | 'error';\n /** Overrides the default label for the current `state`. */\n message?: string;\n /** Trailing action (e.g. a \"Try again\" button) — shown for `error` only. */\n action?: React.ReactNode;\n}\n\nconst ChartState = React.forwardRef<HTMLDivElement, ChartStateProps>(\n ({ className, state, message, action, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex size-full min-h-32 flex-col items-center justify-center gap-2 text-center text-sm leading-6 text-foreground',\n className\n )}\n {...props}\n // The status/alert live-region contract is intrinsic to the state, so it\n // wins over any consumer-passed a11y prop (spread above). No `aria-busy`\n // here: this element IS the live region, and some AT defer announcing a\n // busy region's content until busy clears — but this placeholder is\n // unmounted (swapped for the chart) rather than un-busied, so a busy flag\n // would risk swallowing the \"Data is loading…\" announcement. A consumer\n // that wants a busy signal sets `aria-busy` on the chart-slot container.\n role={state === 'error' ? 'alert' : 'status'}\n aria-live={state === 'error' ? 'assertive' : 'polite'}\n >\n {/* aria-hidden: the root is already the loading live region (+ the label),\n so the Spinner's own role=\"status\"/sr-only would double-announce. */}\n {state === 'loading' && <Spinner size=\"lg\" aria-hidden />}\n {state === 'empty' && (\n <InboxIcon size={24} className=\"text-[var(--ui-glyph-on-status-info)]\" />\n )}\n {state === 'error' && (\n <CircleWarningIcon\n size={24}\n className=\"text-[var(--ui-glyph-on-status-warning)]\"\n />\n )}\n <p>{message ?? DEFAULT_MESSAGE[state]}</p>\n {state === 'error' && action}\n </div>\n )\n);\nChartState.displayName = 'ChartState';\n\nexport { ChartState };\n"],"names":["DEFAULT_MESSAGE","ChartState","React","className","state","message","action","props","ref","jsxs","cn","jsx","Spinner","InboxIcon","CircleWarningIcon"],"mappings":";;;;;AA8BA,MAAMA,IAA4D;AAAA,EAChE,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AACT,GAYMC,IAAaC,EAAM;AAAA,EACvB,CAAC,EAAE,WAAAC,GAAW,OAAAC,GAAO,SAAAC,GAAS,QAAAC,GAAQ,GAAGC,EAAA,GAASC,MAChD,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,WAAWE;AAAA,QACT;AAAA,QACAP;AAAA,MAAA;AAAA,MAED,GAAGI;AAAA,MAQJ,MAAMH,MAAU,UAAU,UAAU;AAAA,MACpC,aAAWA,MAAU,UAAU,cAAc;AAAA,MAI5C,UAAA;AAAA,QAAAA,MAAU,aAAa,gBAAAO,EAACC,GAAA,EAAQ,MAAK,MAAK,eAAW,IAAC;AAAA,QACtDR,MAAU,WACT,gBAAAO,EAACE,KAAU,MAAM,IAAI,WAAU,yCAAwC;AAAA,QAExET,MAAU,WACT,gBAAAO;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,MAAM;AAAA,YACN,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAGd,gBAAAH,EAAC,KAAA,EAAG,UAAAN,KAAWL,EAAgBI,CAAK,GAAE;AAAA,QACrCA,MAAU,WAAWE;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG5B;AACAL,EAAW,cAAc;"}
|
|
@@ -4,12 +4,12 @@ import { TimesIcon as h } from "@acronis-platform/icons-react/stroke-mono";
|
|
|
4
4
|
import { cva as g } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
|
|
5
5
|
import { cn as m } from "../../../lib/utils.js";
|
|
6
6
|
const f = g(
|
|
7
|
-
"inline-flex h-[var(--ui-chip-global-box-height)] min-w-[var(--ui-chip-global-box-width-min)] items-center justify-center gap-[var(--ui-chip-global-box-gap)] rounded-[var(--ui-chip-global-border-radius)] border-[length:var(--ui-chip-global-border-width)] border-solid border-[var(--ui-chip-global-border-color-idle)] bg-[var(--ui-chip-global-box-color-idle)] px-[var(--ui-chip-global-box-padding-x)] text-sm leading-6 hover:border-[var(--ui-chip-global-border-color-hover)] hover:bg-[var(--ui-chip-global-box-color-hover)] [&_svg]:size-[var(--ui-chip-global-icon-size)] [&_svg]:shrink-0 [&_svg]:text-[var(--ui-chip-global-icon-color)]",
|
|
7
|
+
"inline-flex h-[var(--ui-chip-global-box-height)] min-w-[var(--ui-chip-global-box-width-min)] cursor-pointer items-center justify-center gap-[var(--ui-chip-global-box-gap)] rounded-[var(--ui-chip-global-border-radius)] border-[length:var(--ui-chip-global-border-width)] border-solid border-[var(--ui-chip-global-border-color-idle)] bg-[var(--ui-chip-global-box-color-idle)] px-[var(--ui-chip-global-box-padding-x)] text-sm leading-6 hover:border-[var(--ui-chip-global-border-color-hover)] hover:bg-[var(--ui-chip-global-box-color-hover)] [&_svg]:size-[var(--ui-chip-global-icon-size)] [&_svg]:shrink-0 [&_svg]:pointer-events-none [&_svg]:text-[var(--ui-chip-global-icon-color)]",
|
|
8
8
|
{
|
|
9
9
|
variants: {
|
|
10
10
|
variant: {
|
|
11
11
|
removable: "text-[var(--ui-chip-removable-label-color)] focus-within:outline-none focus-within:ring-[3px] focus-within:ring-[var(--ui-focus-primary)] active:border-[var(--ui-chip-global-border-color-active)] active:bg-[var(--ui-chip-global-box-color-active)]",
|
|
12
|
-
selectable: "
|
|
12
|
+
selectable: "text-[var(--ui-chip-selectable-label-color)] focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--ui-focus-primary)] data-[selected=true]:border-[var(--ui-chip-global-border-color-active)] data-[selected=true]:bg-[var(--ui-chip-global-box-color-active)]"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
defaultVariants: {
|
|
@@ -19,23 +19,23 @@ const f = g(
|
|
|
19
19
|
), x = d.forwardRef(
|
|
20
20
|
({
|
|
21
21
|
className: c,
|
|
22
|
-
variant:
|
|
22
|
+
variant: e = "removable",
|
|
23
23
|
icon: t,
|
|
24
24
|
selected: a,
|
|
25
25
|
onRemove: b,
|
|
26
26
|
removeLabel: s = "Remove",
|
|
27
|
-
children:
|
|
28
|
-
onKeyDown:
|
|
29
|
-
...
|
|
27
|
+
children: n,
|
|
28
|
+
onKeyDown: i,
|
|
29
|
+
...u
|
|
30
30
|
}, v) => {
|
|
31
|
-
const l =
|
|
31
|
+
const l = e === "selectable";
|
|
32
32
|
return /* @__PURE__ */ p(
|
|
33
33
|
"div",
|
|
34
34
|
{
|
|
35
35
|
ref: v,
|
|
36
|
-
className: m(f({ variant:
|
|
36
|
+
className: m(f({ variant: e }), c),
|
|
37
37
|
onKeyDown: (r) => {
|
|
38
|
-
l && (r.key === "Enter" || r.key === " ") && (r.preventDefault(), r.currentTarget.click()),
|
|
38
|
+
l && (r.key === "Enter" || r.key === " ") && (r.preventDefault(), r.currentTarget.click()), i == null || i(r);
|
|
39
39
|
},
|
|
40
40
|
...l ? {
|
|
41
41
|
role: "button",
|
|
@@ -43,17 +43,17 @@ const f = g(
|
|
|
43
43
|
"aria-pressed": !!a,
|
|
44
44
|
"data-selected": a ? "true" : void 0
|
|
45
45
|
} : {},
|
|
46
|
-
...
|
|
46
|
+
...u,
|
|
47
47
|
children: [
|
|
48
48
|
t,
|
|
49
|
-
/* @__PURE__ */ o("span", { className: "min-w-0 truncate", children:
|
|
50
|
-
|
|
49
|
+
/* @__PURE__ */ o("span", { className: "min-w-0 truncate", children: n }),
|
|
50
|
+
e === "removable" && /* @__PURE__ */ o(
|
|
51
51
|
"button",
|
|
52
52
|
{
|
|
53
53
|
type: "button",
|
|
54
54
|
"aria-label": s,
|
|
55
55
|
onClick: b,
|
|
56
|
-
className: "-me-1 flex shrink-0 items-center justify-center rounded-full outline-none focus-visible:outline-none",
|
|
56
|
+
className: "-me-1 flex shrink-0 cursor-pointer items-center justify-center rounded-full outline-none focus-visible:outline-none",
|
|
57
57
|
children: /* @__PURE__ */ o(h, {})
|
|
58
58
|
}
|
|
59
59
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chip.js","sources":["../../../../src/components/ui/chip/chip.tsx"],"sourcesContent":["import * as React from 'react';\nimport { TimesIcon } from '@acronis-platform/icons-react/stroke-mono';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\n// A compact, interactive label. `variant` mirrors the Figma \"Chip\" `type`:\n// `removable` carries a trailing × (remove) button; `selectable` toggles a\n// selected state. The container fill/border/label/icon all wire to the dedicated\n// `--ui-chip-*` tier from @acronis-platform/tokens-pd; geometry (height, gap,\n// padding, min-width, radius, border width, icon size) is tokenized too.\n// The Figma `state` enum (idle / hover / active / focused) maps to interaction\n// states, not props: `hover:` → the hover tokens, `:focus`/`focus-visible` → the\n// 3px `--ui-focus-primary` ring, and the `active` look is the pressed state for\n// `removable` (`active:`) and the selected state for `selectable`\n// (`data-[selected]`, driven by the `selected` prop).\nconst chipVariants = cva(\n \"inline-flex h-[var(--ui-chip-global-box-height)] min-w-[var(--ui-chip-global-box-width-min)] items-center justify-center gap-[var(--ui-chip-global-box-gap)] rounded-[var(--ui-chip-global-border-radius)] border-[length:var(--ui-chip-global-border-width)] border-solid border-[var(--ui-chip-global-border-color-idle)] bg-[var(--ui-chip-global-box-color-idle)] px-[var(--ui-chip-global-box-padding-x)] text-sm leading-6 hover:border-[var(--ui-chip-global-border-color-hover)] hover:bg-[var(--ui-chip-global-box-color-hover)] [&_svg]:size-[var(--ui-chip-global-icon-size)] [&_svg]:shrink-0 [&_svg]:text-[var(--ui-chip-global-icon-color)]\",\n {\n variants: {\n variant: {\n removable:\n 'text-[var(--ui-chip-removable-label-color)] focus-within:outline-none focus-within:ring-[3px] focus-within:ring-[var(--ui-focus-primary)] active:border-[var(--ui-chip-global-border-color-active)] active:bg-[var(--ui-chip-global-box-color-active)]',\n selectable:\n '
|
|
1
|
+
{"version":3,"file":"chip.js","sources":["../../../../src/components/ui/chip/chip.tsx"],"sourcesContent":["import * as React from 'react';\nimport { TimesIcon } from '@acronis-platform/icons-react/stroke-mono';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\n// A compact, interactive label. `variant` mirrors the Figma \"Chip\" `type`:\n// `removable` carries a trailing × (remove) button; `selectable` toggles a\n// selected state. The container fill/border/label/icon all wire to the dedicated\n// `--ui-chip-*` tier from @acronis-platform/tokens-pd; geometry (height, gap,\n// padding, min-width, radius, border width, icon size) is tokenized too.\n// The Figma `state` enum (idle / hover / active / focused) maps to interaction\n// states, not props: `hover:` → the hover tokens, `:focus`/`focus-visible` → the\n// 3px `--ui-focus-primary` ring, and the `active` look is the pressed state for\n// `removable` (`active:`) and the selected state for `selectable`\n// (`data-[selected]`, driven by the `selected` prop).\nconst chipVariants = cva(\n \"inline-flex h-[var(--ui-chip-global-box-height)] min-w-[var(--ui-chip-global-box-width-min)] cursor-pointer items-center justify-center gap-[var(--ui-chip-global-box-gap)] rounded-[var(--ui-chip-global-border-radius)] border-[length:var(--ui-chip-global-border-width)] border-solid border-[var(--ui-chip-global-border-color-idle)] bg-[var(--ui-chip-global-box-color-idle)] px-[var(--ui-chip-global-box-padding-x)] text-sm leading-6 hover:border-[var(--ui-chip-global-border-color-hover)] hover:bg-[var(--ui-chip-global-box-color-hover)] [&_svg]:size-[var(--ui-chip-global-icon-size)] [&_svg]:shrink-0 [&_svg]:pointer-events-none [&_svg]:text-[var(--ui-chip-global-icon-color)]\",\n {\n variants: {\n variant: {\n removable:\n 'text-[var(--ui-chip-removable-label-color)] focus-within:outline-none focus-within:ring-[3px] focus-within:ring-[var(--ui-focus-primary)] active:border-[var(--ui-chip-global-border-color-active)] active:bg-[var(--ui-chip-global-box-color-active)]',\n selectable:\n 'text-[var(--ui-chip-selectable-label-color)] focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--ui-focus-primary)] data-[selected=true]:border-[var(--ui-chip-global-border-color-active)] data-[selected=true]:bg-[var(--ui-chip-global-box-color-active)]',\n },\n },\n defaultVariants: {\n variant: 'removable',\n },\n }\n);\n\nexport interface ChipProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof chipVariants> {\n /** Optional leading icon, rendered at 16px before the label. */\n icon?: React.ReactNode;\n /**\n * `selectable` only — applies the selected (active) styling and exposes the\n * chip as a pressed toggle (`role=\"button\"` + `aria-pressed`).\n */\n selected?: boolean;\n /** `removable` only — called when the trailing remove (×) button is pressed. */\n onRemove?: () => void;\n /** Accessible label for the remove button (`removable`). */\n removeLabel?: string;\n}\n\nconst Chip = React.forwardRef<HTMLDivElement, ChipProps>(\n (\n {\n className,\n variant = 'removable',\n icon,\n selected,\n onRemove,\n removeLabel = 'Remove',\n children,\n onKeyDown,\n ...props\n },\n ref\n ) => {\n const selectable = variant === 'selectable';\n return (\n <div\n ref={ref}\n className={cn(chipVariants({ variant }), className)}\n onKeyDown={(event) => {\n // The selectable chip is a div with button semantics; mirror native\n // button activation so Enter/Space fire its click handler.\n if (selectable && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n event.currentTarget.click();\n }\n onKeyDown?.(event);\n }}\n {...(selectable\n ? {\n role: 'button',\n tabIndex: 0,\n 'aria-pressed': Boolean(selected),\n 'data-selected': selected ? 'true' : undefined,\n }\n : {})}\n {...props}\n >\n {icon}\n <span className=\"min-w-0 truncate\">{children}</span>\n {variant === 'removable' && (\n <button\n type=\"button\"\n aria-label={removeLabel}\n onClick={onRemove}\n className=\"-me-1 flex shrink-0 cursor-pointer items-center justify-center rounded-full outline-none focus-visible:outline-none\"\n >\n <TimesIcon />\n </button>\n )}\n </div>\n );\n }\n);\nChip.displayName = 'Chip';\n\nexport { Chip, chipVariants };\n"],"names":["chipVariants","cva","Chip","React","className","variant","icon","selected","onRemove","removeLabel","children","onKeyDown","props","ref","selectable","jsxs","cn","event","jsx","TimesIcon"],"mappings":";;;;;AAgBA,MAAMA,IAAeC;AAAA,EACnB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,WACE;AAAA,QACF,YACE;AAAA,MAAA;AAAA,IACJ;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ,GAmBMC,IAAOC,EAAM;AAAA,EACjB,CACE;AAAA,IACE,WAAAC;AAAA,IACA,SAAAC,IAAU;AAAA,IACV,MAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,aAAAC,IAAc;AAAA,IACd,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAMC,IAAaT,MAAY;AAC/B,WACE,gBAAAU;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAAF;AAAA,QACA,WAAWG,EAAGhB,EAAa,EAAE,SAAAK,EAAA,CAAS,GAAGD,CAAS;AAAA,QAClD,WAAW,CAACa,MAAU;AAGpB,UAAIH,MAAeG,EAAM,QAAQ,WAAWA,EAAM,QAAQ,SACxDA,EAAM,eAAA,GACNA,EAAM,cAAc,MAAA,IAEtBN,KAAA,QAAAA,EAAYM;AAAA,QACd;AAAA,QACC,GAAIH,IACD;AAAA,UACE,MAAM;AAAA,UACN,UAAU;AAAA,UACV,gBAAgB,EAAQP;AAAA,UACxB,iBAAiBA,IAAW,SAAS;AAAA,QAAA,IAEvC,CAAA;AAAA,QACH,GAAGK;AAAA,QAEH,UAAA;AAAA,UAAAN;AAAA,UACD,gBAAAY,EAAC,QAAA,EAAK,WAAU,oBAAoB,UAAAR,EAAA,CAAS;AAAA,UAC5CL,MAAY,eACX,gBAAAa;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAYT;AAAA,cACZ,SAASD;AAAA,cACT,WAAU;AAAA,cAEV,4BAACW,GAAA,CAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACb;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AACAjB,EAAK,cAAc;"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { jsx as t, jsxs as M } from "react/jsx-runtime";
|
|
2
|
+
import * as W from "react";
|
|
3
|
+
import { ComposedChart as X, CartesianGrid as Y, XAxis as _, YAxis as q, Bar as E, Area as I, Line as J } from "recharts";
|
|
4
|
+
import { cn as O } from "../../../lib/utils.js";
|
|
5
|
+
import { ChartContainer as P, ChartTooltip as Q, ChartTooltipContent as R, ChartLegend as S, ChartLegendContent as U } from "../chart/chart.js";
|
|
6
|
+
import { resolveAxisDomain as V } from "../chart/chart-format.js";
|
|
7
|
+
const Z = W.forwardRef(
|
|
8
|
+
({
|
|
9
|
+
className: s,
|
|
10
|
+
config: d,
|
|
11
|
+
data: m,
|
|
12
|
+
series: c,
|
|
13
|
+
xKey: f,
|
|
14
|
+
xAxisLabel: i,
|
|
15
|
+
yAxisLabel: a,
|
|
16
|
+
yUnit: h,
|
|
17
|
+
curve: l = "monotone",
|
|
18
|
+
barRadius: n = 4,
|
|
19
|
+
fillOpacity: p = 0.3,
|
|
20
|
+
showGrid: y = !0,
|
|
21
|
+
showTooltip: u = !0,
|
|
22
|
+
showLegend: C = !0,
|
|
23
|
+
showXAxis: k = !0,
|
|
24
|
+
showYAxis: v = !0,
|
|
25
|
+
xTickFormatter: g,
|
|
26
|
+
yTickFormatter: K,
|
|
27
|
+
xAxisAngle: o,
|
|
28
|
+
xAxisInterval: T,
|
|
29
|
+
yAxisTickCount: D,
|
|
30
|
+
yAxisDomain: L,
|
|
31
|
+
gridDashed: N,
|
|
32
|
+
gridHorizontal: j,
|
|
33
|
+
gridVertical: w,
|
|
34
|
+
tooltipContent: z,
|
|
35
|
+
...A
|
|
36
|
+
}, B) => {
|
|
37
|
+
const F = i ? { value: i, position: "insideBottom", offset: 0 } : void 0, $ = a ? {
|
|
38
|
+
value: a,
|
|
39
|
+
angle: -90,
|
|
40
|
+
position: "insideLeft",
|
|
41
|
+
style: { textAnchor: "middle" }
|
|
42
|
+
} : void 0, G = V(L), H = i || o != null ? 30 + (o != null ? 20 : 0) + (i ? 18 : 0) : void 0;
|
|
43
|
+
return /* @__PURE__ */ t("div", { ref: B, className: O(s), ...A, children: /* @__PURE__ */ t(
|
|
44
|
+
P,
|
|
45
|
+
{
|
|
46
|
+
config: d,
|
|
47
|
+
className: "size-full [&_.recharts-label]:fill-foreground",
|
|
48
|
+
children: /* @__PURE__ */ M(X, { data: m, children: [
|
|
49
|
+
y && /* @__PURE__ */ t(
|
|
50
|
+
Y,
|
|
51
|
+
{
|
|
52
|
+
horizontal: j ?? !0,
|
|
53
|
+
vertical: w ?? !1,
|
|
54
|
+
strokeDasharray: N ? "3 3" : void 0
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
/* @__PURE__ */ t(
|
|
58
|
+
_,
|
|
59
|
+
{
|
|
60
|
+
dataKey: f,
|
|
61
|
+
type: "category",
|
|
62
|
+
hide: !k,
|
|
63
|
+
tickLine: !1,
|
|
64
|
+
axisLine: !1,
|
|
65
|
+
tickMargin: 8,
|
|
66
|
+
tickFormatter: g,
|
|
67
|
+
angle: o,
|
|
68
|
+
interval: T,
|
|
69
|
+
textAnchor: o != null ? o < 0 ? "end" : "start" : void 0,
|
|
70
|
+
height: H,
|
|
71
|
+
label: F
|
|
72
|
+
}
|
|
73
|
+
),
|
|
74
|
+
/* @__PURE__ */ t(
|
|
75
|
+
q,
|
|
76
|
+
{
|
|
77
|
+
type: "number",
|
|
78
|
+
hide: !v,
|
|
79
|
+
tickLine: !1,
|
|
80
|
+
axisLine: !1,
|
|
81
|
+
unit: h,
|
|
82
|
+
tickFormatter: K,
|
|
83
|
+
tickCount: D,
|
|
84
|
+
domain: G,
|
|
85
|
+
width: a ? 72 : void 0,
|
|
86
|
+
label: $
|
|
87
|
+
}
|
|
88
|
+
),
|
|
89
|
+
u && /* @__PURE__ */ t(Q, { content: z ?? /* @__PURE__ */ t(R, {}) }),
|
|
90
|
+
C && /* @__PURE__ */ t(S, { content: /* @__PURE__ */ t(U, {}) }),
|
|
91
|
+
c.map((e) => {
|
|
92
|
+
const r = `var(--color-${e.key})`;
|
|
93
|
+
return e.type === "bar" ? /* @__PURE__ */ t(
|
|
94
|
+
E,
|
|
95
|
+
{
|
|
96
|
+
dataKey: e.key,
|
|
97
|
+
fill: r,
|
|
98
|
+
radius: n > 0 ? [n, n, 0, 0] : void 0,
|
|
99
|
+
isAnimationActive: !1
|
|
100
|
+
},
|
|
101
|
+
e.key
|
|
102
|
+
) : e.type === "area" ? /* @__PURE__ */ t(
|
|
103
|
+
I,
|
|
104
|
+
{
|
|
105
|
+
type: l,
|
|
106
|
+
dataKey: e.key,
|
|
107
|
+
stroke: r,
|
|
108
|
+
fill: r,
|
|
109
|
+
fillOpacity: p,
|
|
110
|
+
isAnimationActive: !1
|
|
111
|
+
},
|
|
112
|
+
e.key
|
|
113
|
+
) : /* @__PURE__ */ t(
|
|
114
|
+
J,
|
|
115
|
+
{
|
|
116
|
+
type: l,
|
|
117
|
+
dataKey: e.key,
|
|
118
|
+
stroke: r,
|
|
119
|
+
strokeWidth: 2,
|
|
120
|
+
dot: !1,
|
|
121
|
+
isAnimationActive: !1
|
|
122
|
+
},
|
|
123
|
+
e.key
|
|
124
|
+
);
|
|
125
|
+
})
|
|
126
|
+
] })
|
|
127
|
+
}
|
|
128
|
+
) });
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
Z.displayName = "ComposedChart";
|
|
132
|
+
export {
|
|
133
|
+
Z as ComposedChart
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=composed-chart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composed-chart.js","sources":["../../../../src/components/ui/composed-chart/composed-chart.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n Area,\n Bar,\n CartesianGrid,\n ComposedChart as RechartsComposedChart,\n Line,\n XAxis,\n YAxis,\n} from 'recharts';\n\nimport { cn } from '@/lib/utils';\nimport {\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n resolveAxisDomain,\n type ChartConfig,\n type CartesianChartProps,\n} from '../chart';\n\n// A typed recharts composition over the shared `Chart` primitives. A composed\n// chart's defining trait is that each series picks its own render type\n// (bar / line / area) over one shared category axis — so, like ScatterChart,\n// there's no single visual \"mode\" to model as a CVA variant (the skill's\n// \"per-series type\"). The variation lives in the `series[].type` list instead.\nexport type ComposedSeriesType = 'bar' | 'line' | 'area';\n\nexport interface ComposedSeries {\n /** Column key to plot — must match a `config` entry; drives its `--color-<key>` paint. */\n key: string;\n /** How this series renders. */\n type: ComposedSeriesType;\n}\n\nexport interface ComposedChartProps\n extends Omit<React.ComponentProps<'div'>, 'children'>,\n CartesianChartProps {\n /** Row-per-category data. Each object holds `xKey` + one numeric field per series. */\n data: ReadonlyArray<Record<string, string | number>>;\n /**\n * Per-series map of `label` / `color`, keyed by `series[].key` (imported from\n * the shared `Chart` primitives). Turned into `--color-<key>` custom\n * properties. Colors are caller-supplied — reference an existing semantic\n * `--ui-*` token; there is no chart palette tier yet.\n */\n config: ChartConfig;\n /** Series to plot, each `{ key, type }` — one bar/line/area per entry. Each key must exist in `config` and every data row. */\n series: ComposedSeries[];\n /** Category axis key (the shared dimension across rows, e.g. `\"month\"`). */\n xKey: string;\n /** Interpolation for the line and area series. */\n curve?: 'linear' | 'monotone' | 'step';\n /** Corner radius on the growing end of bar series. */\n barRadius?: number;\n /** Flat-fill opacity for area series. */\n fillOpacity?: number;\n showLegend?: boolean;\n}\n\nconst ComposedChart = React.forwardRef<HTMLDivElement, ComposedChartProps>(\n (\n {\n className,\n config,\n data,\n series,\n xKey,\n xAxisLabel,\n yAxisLabel,\n yUnit,\n curve = 'monotone',\n barRadius = 4,\n fillOpacity = 0.3,\n showGrid = true,\n showTooltip = true,\n showLegend = true,\n showXAxis = true,\n showYAxis = true,\n xTickFormatter,\n yTickFormatter,\n xAxisAngle,\n xAxisInterval,\n yAxisTickCount,\n yAxisDomain,\n gridDashed,\n gridHorizontal,\n gridVertical,\n tooltipContent,\n ...props\n },\n ref\n ) => {\n // Axis titles: the X title sits below the ticks; the Y title is rotated in\n // the left gutter. Passed to recharts' native `label` (themed via the\n // `.recharts-label` fill selector on the container).\n const xAxisTitle = xAxisLabel\n ? { value: xAxisLabel, position: 'insideBottom' as const, offset: 0 }\n : undefined;\n const yAxisTitle = yAxisLabel\n ? {\n value: yAxisLabel,\n angle: -90,\n position: 'insideLeft' as const,\n style: { textAnchor: 'middle' as const },\n }\n : undefined;\n\n const yDomain = resolveAxisDomain(yAxisDomain);\n\n // Room for the X tick row: recharts' default 30, plus a rotated tick row\n // (+20) and/or the axis title (+18). Additive — both can be present at once,\n // which the old label-or-angle ternary under-allocated.\n const xAxisHeight =\n xAxisLabel || xAxisAngle != null\n ? 30 + (xAxisAngle != null ? 20 : 0) + (xAxisLabel ? 18 : 0)\n : undefined;\n\n return (\n <div ref={ref} className={cn(className)} {...props}>\n <ChartContainer\n config={config}\n className=\"size-full [&_.recharts-label]:fill-foreground\"\n >\n <RechartsComposedChart data={data as readonly unknown[]}>\n {showGrid && (\n <CartesianGrid\n horizontal={gridHorizontal ?? true}\n vertical={gridVertical ?? false}\n strokeDasharray={gridDashed ? '3 3' : undefined}\n />\n )}\n <XAxis\n dataKey={xKey}\n type=\"category\"\n hide={!showXAxis}\n tickLine={false}\n axisLine={false}\n tickMargin={8}\n tickFormatter={xTickFormatter}\n angle={xAxisAngle}\n interval={xAxisInterval}\n textAnchor={\n xAxisAngle != null ? (xAxisAngle < 0 ? 'end' : 'start') : undefined\n }\n height={xAxisHeight}\n label={xAxisTitle}\n />\n <YAxis\n type=\"number\"\n hide={!showYAxis}\n tickLine={false}\n axisLine={false}\n unit={yUnit}\n tickFormatter={yTickFormatter}\n tickCount={yAxisTickCount}\n domain={yDomain}\n width={yAxisLabel ? 72 : undefined}\n label={yAxisTitle}\n />\n {showTooltip && (\n <ChartTooltip content={tooltipContent ?? <ChartTooltipContent />} />\n )}\n {showLegend && <ChartLegend content={<ChartLegendContent />} />}\n {/* Rendered in the caller's `series` order — recharts paints children\n back-to-front, so later entries sit on top. Order them so thin\n marks (a line) come after the areas/bars they should overlay. */}\n {series.map((s) => {\n const color = `var(--color-${s.key})`;\n if (s.type === 'bar') {\n return (\n <Bar\n key={s.key}\n dataKey={s.key}\n fill={color}\n radius={\n barRadius > 0\n ? [barRadius, barRadius, 0, 0]\n : undefined\n }\n isAnimationActive={false}\n />\n );\n }\n if (s.type === 'area') {\n return (\n <Area\n key={s.key}\n type={curve}\n dataKey={s.key}\n stroke={color}\n fill={color}\n fillOpacity={fillOpacity}\n isAnimationActive={false}\n />\n );\n }\n return (\n <Line\n key={s.key}\n type={curve}\n dataKey={s.key}\n stroke={color}\n strokeWidth={2}\n dot={false}\n isAnimationActive={false}\n />\n );\n })}\n </RechartsComposedChart>\n </ChartContainer>\n </div>\n );\n }\n);\nComposedChart.displayName = 'ComposedChart';\n\nexport { ComposedChart };\n"],"names":["ComposedChart","React","className","config","data","series","xKey","xAxisLabel","yAxisLabel","yUnit","curve","barRadius","fillOpacity","showGrid","showTooltip","showLegend","showXAxis","showYAxis","xTickFormatter","yTickFormatter","xAxisAngle","xAxisInterval","yAxisTickCount","yAxisDomain","gridDashed","gridHorizontal","gridVertical","tooltipContent","props","ref","xAxisTitle","yAxisTitle","yDomain","resolveAxisDomain","xAxisHeight","jsx","cn","ChartContainer","jsxs","RechartsComposedChart","CartesianGrid","XAxis","YAxis","ChartTooltip","ChartTooltipContent","ChartLegend","ChartLegendContent","s","color","Bar","Area","Line"],"mappings":"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"}
|