@mantine/charts 9.6.1 → 9.6.2

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.
@@ -118,21 +118,33 @@ const GaugeChart = (0, _mantine_core.factory)((_props) => {
118
118
  const sortedSections = [...sections].sort((a, b) => a.value - b.value);
119
119
  const direction = resolvedEndAngle >= startAngle ? 1 : -1;
120
120
  let prevAngle = startAngle;
121
- return sortedSections.map((section, index) => {
121
+ const resolvedSections = sortedSections.map((section) => {
122
122
  const sectionEndAngle = valueToAngle(section.value, min, max, startAngle, resolvedEndAngle);
123
123
  if ((sectionEndAngle - prevAngle) * direction <= 0) return null;
124
124
  const path = describeArc(cx, cy, r, prevAngle, sectionEndAngle);
125
- const resolvedColor = (0, _mantine_core.getThemeColor)(section.color, theme);
126
125
  prevAngle = sectionEndAngle;
127
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
128
- ...getStyles("section"),
129
- d: path,
130
- fill: "none",
131
- stroke: resolvedColor,
132
- strokeWidth: thickness,
133
- strokeLinecap: "butt"
134
- }, index);
126
+ return {
127
+ path,
128
+ color: (0, _mantine_core.getThemeColor)(section.color, theme)
129
+ };
135
130
  });
131
+ const visibleSections = resolvedSections.filter((section) => section !== null);
132
+ const capSections = roundCaps && visibleSections.length > 0 ? visibleSections.length === 1 ? [visibleSections[0]] : [visibleSections[0], visibleSections[visibleSections.length - 1]] : [];
133
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [capSections.map((section, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
134
+ ...getStyles("sectionCap"),
135
+ d: section.path,
136
+ fill: "none",
137
+ stroke: section.color,
138
+ strokeWidth: thickness,
139
+ strokeLinecap: "round"
140
+ }, index)), resolvedSections.map((section, index) => section ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
141
+ ...getStyles("section"),
142
+ d: section.path,
143
+ fill: "none",
144
+ stroke: section.color,
145
+ strokeWidth: thickness,
146
+ strokeLinecap: "butt"
147
+ }, index) : null)] });
136
148
  })() : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
137
149
  ...getStyles("section"),
138
150
  d: describeArc(cx, cy, r, startAngle, valueToAngle(value, min, max, startAngle, resolvedEndAngle)),
@@ -1 +1 @@
1
- {"version":3,"file":"GaugeChart.cjs","names":["createVarsResolver","rem","factory","useProps","useMantineTheme","useStyles","getThemeColor","Box","classes"],"sources":["../../src/GaugeChart/GaugeChart.tsx"],"sourcesContent":["import {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getThemeColor,\n MantineColor,\n rem,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport classes from './GaugeChart.module.css';\n\nexport interface GaugeChartSection {\n /** Upper bound value for this section */\n value: number;\n\n /** Color of the section */\n color: MantineColor;\n}\n\nexport type GaugeChartStylesNames = 'root' | 'track' | 'section' | 'needle' | 'label';\n\nexport type GaugeChartCssVariables = {\n root: '--gauge-size';\n};\n\nexport interface GaugeChartProps\n extends\n BoxProps,\n StylesApiProps<GaugeChartFactory>,\n ElementProps<'svg', 'display' | 'opacity' | 'viewBox' | 'width' | 'height' | 'target'> {\n /** Current value to display. Fills the arc from `min` up to `value`, unless `sections` is set – then the arc is colored by thresholds and the value is displayed only in the center label. */\n value: number;\n\n /** Minimum value of the gauge, @default 0 */\n min?: number;\n\n /** Maximum value of the gauge, @default 100 */\n max?: number;\n\n /** Value marked on the arc with a line marker, use to display a goal or the current value of a gauge with `sections` */\n target?: number;\n\n /** Threshold sections of the gauge arc, each section is filled from the previous section upper bound to its own `value`. If set, the arc is not filled based on `value`. */\n sections?: GaugeChartSection[];\n\n /** Arc thickness in px, @default 12 */\n thickness?: number;\n\n /** Chart size (width and height), @default 200 */\n size?: number;\n\n /** Start angle in degrees, @default -120 */\n startAngle?: number;\n\n /** End angle in degrees, @default 120 */\n endAngle?: number;\n\n /** Label displayed in the center of the gauge */\n label?: React.ReactNode;\n\n /** Value formatter for default label, @default (v) => String(v) */\n valueFormatter?: (value: number) => string;\n\n /** Color of the gauge track (unfilled portion) */\n trackColor?: MantineColor;\n\n /** Color of the filled arc when sections are not provided */\n filledColor?: MantineColor;\n\n /** Color of the target marker */\n targetColor?: MantineColor;\n\n /** Thickness of the target marker, @default 2 */\n targetSize?: number;\n\n /** Whether to round arc endpoints. Not applied to `sections` – rounded caps of adjacent sections would overlap each other. @default false */\n roundCaps?: boolean;\n}\n\nexport type GaugeChartFactory = Factory<{\n props: GaugeChartProps;\n ref: SVGSVGElement;\n stylesNames: GaugeChartStylesNames;\n vars: GaugeChartCssVariables;\n}>;\n\nconst defaultProps = {\n min: 0,\n max: 100,\n thickness: 12,\n size: 200,\n startAngle: -120,\n endAngle: 120,\n roundCaps: false,\n targetSize: 2,\n} satisfies Partial<GaugeChartProps>;\n\nconst varsResolver = createVarsResolver<GaugeChartFactory>((_theme, { size }) => ({\n root: {\n '--gauge-size': rem(size),\n },\n}));\n\nfunction polarToCartesian(cx: number, cy: number, r: number, angleDeg: number) {\n const rad = ((angleDeg - 90) * Math.PI) / 180;\n return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) };\n}\n\nfunction describeArc(cx: number, cy: number, r: number, startAngle: number, endAngle: number) {\n const delta = endAngle - startAngle;\n const sweep = delta >= 0 ? 1 : 0;\n const start = polarToCartesian(cx, cy, r, startAngle);\n\n // A single arc command cannot express a full circle – its endpoints would be identical\n // and nothing would be rendered, so it is split into two half-circle arcs.\n if (Math.abs(delta) >= 360) {\n const mid = polarToCartesian(cx, cy, r, startAngle + (delta >= 0 ? 180 : -180));\n return `M ${start.x} ${start.y} A ${r} ${r} 0 0 ${sweep} ${mid.x} ${mid.y} A ${r} ${r} 0 0 ${sweep} ${start.x} ${start.y}`;\n }\n\n const end = polarToCartesian(cx, cy, r, endAngle);\n const largeArc = Math.abs(delta) > 180 ? 1 : 0;\n return `M ${start.x} ${start.y} A ${r} ${r} 0 ${largeArc} ${sweep} ${end.x} ${end.y}`;\n}\n\nfunction valueToAngle(\n value: number,\n min: number,\n max: number,\n startAngle: number,\n endAngle: number\n) {\n if (max === min) {\n return startAngle;\n }\n const clamped = Math.max(min, Math.min(max, value));\n return startAngle + ((clamped - min) / (max - min)) * (endAngle - startAngle);\n}\n\nfunction isAngleInArc(angle: number, start: number, end: number) {\n const delta = end - start;\n\n if (Math.abs(delta) >= 360) {\n return true;\n }\n\n // Distance from the start angle measured along the direction the arc sweeps,\n // so that descending ranges (endAngle < startAngle) are handled the same way.\n const distance = delta >= 0 ? angle - start : start - angle;\n return ((distance % 360) + 360) % 360 <= Math.abs(delta);\n}\n\nfunction getArcBoundingBox(\n cx: number,\n cy: number,\n r: number,\n startAngle: number,\n endAngle: number,\n padding: number,\n labelReserve: number\n) {\n const startPt = polarToCartesian(cx, cy, r, startAngle);\n const endPt = polarToCartesian(cx, cy, r, endAngle);\n\n let minX = Math.min(startPt.x, endPt.x, cx - labelReserve);\n let maxX = Math.max(startPt.x, endPt.x, cx + labelReserve);\n let minY = Math.min(startPt.y, endPt.y, cy - labelReserve);\n let maxY = Math.max(startPt.y, endPt.y, cy + labelReserve);\n\n const cardinals = [\n { angle: 0, x: cx, y: cy - r },\n { angle: 90, x: cx + r, y: cy },\n { angle: 180, x: cx, y: cy + r },\n { angle: 270, x: cx - r, y: cy },\n ];\n\n for (const cardinal of cardinals) {\n if (isAngleInArc(cardinal.angle, startAngle, endAngle)) {\n minX = Math.min(minX, cardinal.x);\n maxX = Math.max(maxX, cardinal.x);\n minY = Math.min(minY, cardinal.y);\n maxY = Math.max(maxY, cardinal.y);\n }\n }\n\n return {\n x: minX - padding,\n y: minY - padding,\n width: maxX - minX + padding * 2,\n height: maxY - minY + padding * 2,\n };\n}\n\nexport const GaugeChart = factory<GaugeChartFactory>((_props) => {\n const props = useProps('GaugeChart', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n attributes,\n value,\n min,\n max,\n target,\n sections,\n thickness,\n size,\n startAngle,\n endAngle,\n label,\n valueFormatter,\n trackColor,\n filledColor,\n targetColor,\n targetSize,\n roundCaps,\n variant,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n\n const getStyles = useStyles<GaugeChartFactory>({\n name: 'GaugeChart',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const svgSize = size!;\n const cx = svgSize / 2;\n const cy = svgSize / 2;\n const r = (svgSize - thickness!) / 2;\n const strokeLinecap = roundCaps ? 'round' : 'butt';\n const needleLength = thickness! * 1.5;\n\n // The needle sticks out past the arc radius, and a round cap adds half of its own\n // width on top of that – both contribute at the same time. Only reserved when there is a\n // target to draw, otherwise every gauge without one would get an oversized viewBox and\n // render its arc smaller than the requested `size`.\n const needleExtent = needleLength / 2 + (roundCaps ? targetSize! / 2 : 0);\n const strokePadding = target != null ? Math.max(thickness! / 2, needleExtent) : thickness! / 2;\n\n // A gauge cannot span more than a full turn – a larger range would wrap the arc onto\n // itself and make later sections overwrite earlier ones.\n const span = endAngle! - startAngle!;\n const resolvedEndAngle = startAngle! + Math.max(-360, Math.min(360, span));\n\n const labelReserve = Math.max(thickness!, svgSize * 0.11);\n const bbox = getArcBoundingBox(\n cx,\n cy,\n r,\n startAngle!,\n resolvedEndAngle,\n strokePadding,\n labelReserve\n );\n\n const resolvedTrackColor = trackColor\n ? getThemeColor(trackColor, theme)\n : 'var(--mantine-color-default-border)';\n\n const trackPath = describeArc(cx, cy, r, startAngle!, resolvedEndAngle);\n\n const sectionElements =\n sections && sections.length > 0 ? (\n (() => {\n const sortedSections = [...sections].sort((a, b) => a.value - b.value);\n const direction = resolvedEndAngle >= startAngle! ? 1 : -1;\n let prevAngle = startAngle!;\n\n return sortedSections.map((section, index) => {\n const sectionEndAngle = valueToAngle(\n section.value,\n min!,\n max!,\n startAngle!,\n resolvedEndAngle\n );\n if ((sectionEndAngle - prevAngle) * direction <= 0) {\n return null;\n }\n const path = describeArc(cx, cy, r, prevAngle, sectionEndAngle);\n const resolvedColor = getThemeColor(section.color, theme);\n prevAngle = sectionEndAngle;\n\n return (\n <path\n key={index}\n {...getStyles('section')}\n d={path}\n fill=\"none\"\n stroke={resolvedColor}\n strokeWidth={thickness}\n strokeLinecap=\"butt\"\n />\n );\n });\n })()\n ) : (\n <path\n {...getStyles('section')}\n d={describeArc(\n cx,\n cy,\n r,\n startAngle!,\n valueToAngle(value, min!, max!, startAngle!, resolvedEndAngle)\n )}\n fill=\"none\"\n stroke={\n filledColor ? getThemeColor(filledColor, theme) : 'var(--mantine-primary-color-filled)'\n }\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n );\n\n const needleElement =\n target != null\n ? (() => {\n const targetAngle = valueToAngle(target, min!, max!, startAngle!, resolvedEndAngle);\n const inner = polarToCartesian(cx, cy, r - needleLength / 2, targetAngle);\n const outer = polarToCartesian(cx, cy, r + needleLength / 2, targetAngle);\n const resolvedTargetColor = targetColor\n ? getThemeColor(targetColor, theme)\n : 'var(--mantine-color-bright)';\n\n return (\n <line\n {...getStyles('needle')}\n x1={inner.x}\n y1={inner.y}\n x2={outer.x}\n y2={outer.y}\n stroke={resolvedTargetColor}\n strokeWidth={targetSize}\n strokeLinecap={strokeLinecap}\n />\n );\n })()\n : null;\n\n const formatValue = valueFormatter || ((v: number) => String(v));\n\n // The arc is drawn from the clamped value, and `aria-valuetext` is defined as the\n // human-readable equivalent of `aria-valuenow` – reporting the raw value in either the\n // default label or `aria-valuetext` would contradict both the arc and `aria-valuenow`.\n const clampedValue = Math.max(min!, Math.min(max!, value));\n const formattedValue = formatValue(clampedValue);\n const labelContent = label !== undefined ? label : formattedValue;\n\n // A meter with no accessible name is announced as \"meter\" and nothing else, so there is\n // always a name. A string `label` names the metric (\"CPU usage\") and is used unless an\n // explicit `aria-label` is given; the generic fallback covers the rest. The default label\n // is the formatted value, which would only repeat `aria-valuetext`.\n const ariaLabel =\n others['aria-labelledby'] !== undefined\n ? undefined\n : (others['aria-label'] ?? (typeof label === 'string' ? label : undefined) ?? 'Gauge');\n\n return (\n <Box\n component=\"svg\"\n viewBox={`${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`}\n __vars={{ '--gauge-aspect-ratio': `${bbox.width} / ${bbox.height}` }}\n {...getStyles('root')}\n variant={variant}\n role=\"meter\"\n aria-label={ariaLabel}\n aria-valuenow={clampedValue}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuetext={formattedValue}\n {...others}\n >\n <path\n {...getStyles('track')}\n d={trackPath}\n fill=\"none\"\n stroke={resolvedTrackColor}\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n\n {sectionElements}\n {needleElement}\n\n <foreignObject x={bbox.x} y={bbox.y} width={bbox.width} height={bbox.height}>\n <div\n {...getStyles('label', {\n style: {\n transform: `translate(${cx - bbox.x - bbox.width / 2}px, ${cy - bbox.y - bbox.height / 2}px)`,\n },\n })}\n >\n {labelContent}\n </div>\n </foreignObject>\n </Box>\n );\n});\n\nGaugeChart.displayName = '@mantine/charts/GaugeChart';\nGaugeChart.classes = classes;\nGaugeChart.varsResolver = varsResolver;\n"],"mappings":"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"}
1
+ {"version":3,"file":"GaugeChart.cjs","names":["createVarsResolver","rem","factory","useProps","useMantineTheme","useStyles","getThemeColor","Box","classes"],"sources":["../../src/GaugeChart/GaugeChart.tsx"],"sourcesContent":["import {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getThemeColor,\n MantineColor,\n rem,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport classes from './GaugeChart.module.css';\n\nexport interface GaugeChartSection {\n /** Upper bound value for this section */\n value: number;\n\n /** Color of the section */\n color: MantineColor;\n}\n\nexport type GaugeChartStylesNames =\n | 'root'\n | 'track'\n | 'section'\n | 'sectionCap'\n | 'needle'\n | 'label';\n\nexport type GaugeChartCssVariables = {\n root: '--gauge-size';\n};\n\nexport interface GaugeChartProps\n extends\n BoxProps,\n StylesApiProps<GaugeChartFactory>,\n ElementProps<'svg', 'display' | 'opacity' | 'viewBox' | 'width' | 'height' | 'target'> {\n /** Current value to display. Fills the arc from `min` up to `value`, unless `sections` is set – then the arc is colored by thresholds and the value is displayed only in the center label. */\n value: number;\n\n /** Minimum value of the gauge, @default 0 */\n min?: number;\n\n /** Maximum value of the gauge, @default 100 */\n max?: number;\n\n /** Value marked on the arc with a line marker, use to display a goal or the current value of a gauge with `sections` */\n target?: number;\n\n /** Threshold sections of the gauge arc, each section is filled from the previous section upper bound to its own `value`. If set, the arc is not filled based on `value`. */\n sections?: GaugeChartSection[];\n\n /** Arc thickness in px, @default 12 */\n thickness?: number;\n\n /** Chart size (width and height), @default 200 */\n size?: number;\n\n /** Start angle in degrees, @default -120 */\n startAngle?: number;\n\n /** End angle in degrees, @default 120 */\n endAngle?: number;\n\n /** Label displayed in the center of the gauge */\n label?: React.ReactNode;\n\n /** Value formatter for default label, @default (v) => String(v) */\n valueFormatter?: (value: number) => string;\n\n /** Color of the gauge track (unfilled portion) */\n trackColor?: MantineColor;\n\n /** Color of the filled arc when sections are not provided */\n filledColor?: MantineColor;\n\n /** Color of the target marker */\n targetColor?: MantineColor;\n\n /** Thickness of the target marker, @default 2 */\n targetSize?: number;\n\n /** Whether to round arc endpoints. With `sections`, only the outer ends of the first and last sections are rounded. @default false */\n roundCaps?: boolean;\n}\n\nexport type GaugeChartFactory = Factory<{\n props: GaugeChartProps;\n ref: SVGSVGElement;\n stylesNames: GaugeChartStylesNames;\n vars: GaugeChartCssVariables;\n}>;\n\nconst defaultProps = {\n min: 0,\n max: 100,\n thickness: 12,\n size: 200,\n startAngle: -120,\n endAngle: 120,\n roundCaps: false,\n targetSize: 2,\n} satisfies Partial<GaugeChartProps>;\n\nconst varsResolver = createVarsResolver<GaugeChartFactory>((_theme, { size }) => ({\n root: {\n '--gauge-size': rem(size),\n },\n}));\n\nfunction polarToCartesian(cx: number, cy: number, r: number, angleDeg: number) {\n const rad = ((angleDeg - 90) * Math.PI) / 180;\n return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) };\n}\n\nfunction describeArc(cx: number, cy: number, r: number, startAngle: number, endAngle: number) {\n const delta = endAngle - startAngle;\n const sweep = delta >= 0 ? 1 : 0;\n const start = polarToCartesian(cx, cy, r, startAngle);\n\n // A single arc command cannot express a full circle – its endpoints would be identical\n // and nothing would be rendered, so it is split into two half-circle arcs.\n if (Math.abs(delta) >= 360) {\n const mid = polarToCartesian(cx, cy, r, startAngle + (delta >= 0 ? 180 : -180));\n return `M ${start.x} ${start.y} A ${r} ${r} 0 0 ${sweep} ${mid.x} ${mid.y} A ${r} ${r} 0 0 ${sweep} ${start.x} ${start.y}`;\n }\n\n const end = polarToCartesian(cx, cy, r, endAngle);\n const largeArc = Math.abs(delta) > 180 ? 1 : 0;\n return `M ${start.x} ${start.y} A ${r} ${r} 0 ${largeArc} ${sweep} ${end.x} ${end.y}`;\n}\n\nfunction valueToAngle(\n value: number,\n min: number,\n max: number,\n startAngle: number,\n endAngle: number\n) {\n if (max === min) {\n return startAngle;\n }\n const clamped = Math.max(min, Math.min(max, value));\n return startAngle + ((clamped - min) / (max - min)) * (endAngle - startAngle);\n}\n\nfunction isAngleInArc(angle: number, start: number, end: number) {\n const delta = end - start;\n\n if (Math.abs(delta) >= 360) {\n return true;\n }\n\n // Distance from the start angle measured along the direction the arc sweeps,\n // so that descending ranges (endAngle < startAngle) are handled the same way.\n const distance = delta >= 0 ? angle - start : start - angle;\n return ((distance % 360) + 360) % 360 <= Math.abs(delta);\n}\n\nfunction getArcBoundingBox(\n cx: number,\n cy: number,\n r: number,\n startAngle: number,\n endAngle: number,\n padding: number,\n labelReserve: number\n) {\n const startPt = polarToCartesian(cx, cy, r, startAngle);\n const endPt = polarToCartesian(cx, cy, r, endAngle);\n\n let minX = Math.min(startPt.x, endPt.x, cx - labelReserve);\n let maxX = Math.max(startPt.x, endPt.x, cx + labelReserve);\n let minY = Math.min(startPt.y, endPt.y, cy - labelReserve);\n let maxY = Math.max(startPt.y, endPt.y, cy + labelReserve);\n\n const cardinals = [\n { angle: 0, x: cx, y: cy - r },\n { angle: 90, x: cx + r, y: cy },\n { angle: 180, x: cx, y: cy + r },\n { angle: 270, x: cx - r, y: cy },\n ];\n\n for (const cardinal of cardinals) {\n if (isAngleInArc(cardinal.angle, startAngle, endAngle)) {\n minX = Math.min(minX, cardinal.x);\n maxX = Math.max(maxX, cardinal.x);\n minY = Math.min(minY, cardinal.y);\n maxY = Math.max(maxY, cardinal.y);\n }\n }\n\n return {\n x: minX - padding,\n y: minY - padding,\n width: maxX - minX + padding * 2,\n height: maxY - minY + padding * 2,\n };\n}\n\nexport const GaugeChart = factory<GaugeChartFactory>((_props) => {\n const props = useProps('GaugeChart', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n attributes,\n value,\n min,\n max,\n target,\n sections,\n thickness,\n size,\n startAngle,\n endAngle,\n label,\n valueFormatter,\n trackColor,\n filledColor,\n targetColor,\n targetSize,\n roundCaps,\n variant,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n\n const getStyles = useStyles<GaugeChartFactory>({\n name: 'GaugeChart',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const svgSize = size!;\n const cx = svgSize / 2;\n const cy = svgSize / 2;\n const r = (svgSize - thickness!) / 2;\n const strokeLinecap = roundCaps ? 'round' : 'butt';\n const needleLength = thickness! * 1.5;\n\n // The needle sticks out past the arc radius, and a round cap adds half of its own\n // width on top of that – both contribute at the same time. Only reserved when there is a\n // target to draw, otherwise every gauge without one would get an oversized viewBox and\n // render its arc smaller than the requested `size`.\n const needleExtent = needleLength / 2 + (roundCaps ? targetSize! / 2 : 0);\n const strokePadding = target != null ? Math.max(thickness! / 2, needleExtent) : thickness! / 2;\n\n // A gauge cannot span more than a full turn – a larger range would wrap the arc onto\n // itself and make later sections overwrite earlier ones.\n const span = endAngle! - startAngle!;\n const resolvedEndAngle = startAngle! + Math.max(-360, Math.min(360, span));\n\n const labelReserve = Math.max(thickness!, svgSize * 0.11);\n const bbox = getArcBoundingBox(\n cx,\n cy,\n r,\n startAngle!,\n resolvedEndAngle,\n strokePadding,\n labelReserve\n );\n\n const resolvedTrackColor = trackColor\n ? getThemeColor(trackColor, theme)\n : 'var(--mantine-color-default-border)';\n\n const trackPath = describeArc(cx, cy, r, startAngle!, resolvedEndAngle);\n\n const sectionElements =\n sections && sections.length > 0 ? (\n (() => {\n const sortedSections = [...sections].sort((a, b) => a.value - b.value);\n const direction = resolvedEndAngle >= startAngle! ? 1 : -1;\n let prevAngle = startAngle!;\n\n const resolvedSections = sortedSections.map((section) => {\n const sectionEndAngle = valueToAngle(\n section.value,\n min!,\n max!,\n startAngle!,\n resolvedEndAngle\n );\n if ((sectionEndAngle - prevAngle) * direction <= 0) {\n return null;\n }\n const path = describeArc(cx, cy, r, prevAngle, sectionEndAngle);\n prevAngle = sectionEndAngle;\n return { path, color: getThemeColor(section.color, theme) };\n });\n\n const visibleSections = resolvedSections.filter((section) => section !== null);\n\n const capSections =\n roundCaps && visibleSections.length > 0\n ? visibleSections.length === 1\n ? [visibleSections[0]]\n : [visibleSections[0], visibleSections[visibleSections.length - 1]]\n : [];\n\n return (\n <>\n {capSections.map((section, index) => (\n <path\n key={index}\n {...getStyles('sectionCap')}\n d={section.path}\n fill=\"none\"\n stroke={section.color}\n strokeWidth={thickness}\n strokeLinecap=\"round\"\n />\n ))}\n {resolvedSections.map((section, index) =>\n section ? (\n <path\n key={index}\n {...getStyles('section')}\n d={section.path}\n fill=\"none\"\n stroke={section.color}\n strokeWidth={thickness}\n strokeLinecap=\"butt\"\n />\n ) : null\n )}\n </>\n );\n })()\n ) : (\n <path\n {...getStyles('section')}\n d={describeArc(\n cx,\n cy,\n r,\n startAngle!,\n valueToAngle(value, min!, max!, startAngle!, resolvedEndAngle)\n )}\n fill=\"none\"\n stroke={\n filledColor ? getThemeColor(filledColor, theme) : 'var(--mantine-primary-color-filled)'\n }\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n );\n\n const needleElement =\n target != null\n ? (() => {\n const targetAngle = valueToAngle(target, min!, max!, startAngle!, resolvedEndAngle);\n const inner = polarToCartesian(cx, cy, r - needleLength / 2, targetAngle);\n const outer = polarToCartesian(cx, cy, r + needleLength / 2, targetAngle);\n const resolvedTargetColor = targetColor\n ? getThemeColor(targetColor, theme)\n : 'var(--mantine-color-bright)';\n\n return (\n <line\n {...getStyles('needle')}\n x1={inner.x}\n y1={inner.y}\n x2={outer.x}\n y2={outer.y}\n stroke={resolvedTargetColor}\n strokeWidth={targetSize}\n strokeLinecap={strokeLinecap}\n />\n );\n })()\n : null;\n\n const formatValue = valueFormatter || ((v: number) => String(v));\n\n // The arc is drawn from the clamped value, and `aria-valuetext` is defined as the\n // human-readable equivalent of `aria-valuenow` – reporting the raw value in either the\n // default label or `aria-valuetext` would contradict both the arc and `aria-valuenow`.\n const clampedValue = Math.max(min!, Math.min(max!, value));\n const formattedValue = formatValue(clampedValue);\n const labelContent = label !== undefined ? label : formattedValue;\n\n // A meter with no accessible name is announced as \"meter\" and nothing else, so there is\n // always a name. A string `label` names the metric (\"CPU usage\") and is used unless an\n // explicit `aria-label` is given; the generic fallback covers the rest. The default label\n // is the formatted value, which would only repeat `aria-valuetext`.\n const ariaLabel =\n others['aria-labelledby'] !== undefined\n ? undefined\n : (others['aria-label'] ?? (typeof label === 'string' ? label : undefined) ?? 'Gauge');\n\n return (\n <Box\n component=\"svg\"\n viewBox={`${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`}\n __vars={{ '--gauge-aspect-ratio': `${bbox.width} / ${bbox.height}` }}\n {...getStyles('root')}\n variant={variant}\n role=\"meter\"\n aria-label={ariaLabel}\n aria-valuenow={clampedValue}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuetext={formattedValue}\n {...others}\n >\n <path\n {...getStyles('track')}\n d={trackPath}\n fill=\"none\"\n stroke={resolvedTrackColor}\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n\n {sectionElements}\n {needleElement}\n\n <foreignObject x={bbox.x} y={bbox.y} width={bbox.width} height={bbox.height}>\n <div\n {...getStyles('label', {\n style: {\n transform: `translate(${cx - bbox.x - bbox.width / 2}px, ${cy - bbox.y - bbox.height / 2}px)`,\n },\n })}\n >\n {labelContent}\n </div>\n </foreignObject>\n </Box>\n );\n});\n\nGaugeChart.displayName = '@mantine/charts/GaugeChart';\nGaugeChart.classes = classes;\nGaugeChart.varsResolver = varsResolver;\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import GaugeChart_module_default from "./GaugeChart.module.mjs";
3
3
  import { Box, createVarsResolver, factory, getThemeColor, rem, useMantineTheme, useProps, useStyles } from "@mantine/core";
4
- import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region packages/@mantine/charts/src/GaugeChart/GaugeChart.tsx
6
6
  const defaultProps = {
7
7
  min: 0,
@@ -118,21 +118,33 @@ const GaugeChart = factory((_props) => {
118
118
  const sortedSections = [...sections].sort((a, b) => a.value - b.value);
119
119
  const direction = resolvedEndAngle >= startAngle ? 1 : -1;
120
120
  let prevAngle = startAngle;
121
- return sortedSections.map((section, index) => {
121
+ const resolvedSections = sortedSections.map((section) => {
122
122
  const sectionEndAngle = valueToAngle(section.value, min, max, startAngle, resolvedEndAngle);
123
123
  if ((sectionEndAngle - prevAngle) * direction <= 0) return null;
124
124
  const path = describeArc(cx, cy, r, prevAngle, sectionEndAngle);
125
- const resolvedColor = getThemeColor(section.color, theme);
126
125
  prevAngle = sectionEndAngle;
127
- return /* @__PURE__ */ jsx("path", {
128
- ...getStyles("section"),
129
- d: path,
130
- fill: "none",
131
- stroke: resolvedColor,
132
- strokeWidth: thickness,
133
- strokeLinecap: "butt"
134
- }, index);
126
+ return {
127
+ path,
128
+ color: getThemeColor(section.color, theme)
129
+ };
135
130
  });
131
+ const visibleSections = resolvedSections.filter((section) => section !== null);
132
+ const capSections = roundCaps && visibleSections.length > 0 ? visibleSections.length === 1 ? [visibleSections[0]] : [visibleSections[0], visibleSections[visibleSections.length - 1]] : [];
133
+ return /* @__PURE__ */ jsxs(Fragment, { children: [capSections.map((section, index) => /* @__PURE__ */ jsx("path", {
134
+ ...getStyles("sectionCap"),
135
+ d: section.path,
136
+ fill: "none",
137
+ stroke: section.color,
138
+ strokeWidth: thickness,
139
+ strokeLinecap: "round"
140
+ }, index)), resolvedSections.map((section, index) => section ? /* @__PURE__ */ jsx("path", {
141
+ ...getStyles("section"),
142
+ d: section.path,
143
+ fill: "none",
144
+ stroke: section.color,
145
+ strokeWidth: thickness,
146
+ strokeLinecap: "butt"
147
+ }, index) : null)] });
136
148
  })() : /* @__PURE__ */ jsx("path", {
137
149
  ...getStyles("section"),
138
150
  d: describeArc(cx, cy, r, startAngle, valueToAngle(value, min, max, startAngle, resolvedEndAngle)),
@@ -1 +1 @@
1
- {"version":3,"file":"GaugeChart.mjs","names":["classes"],"sources":["../../src/GaugeChart/GaugeChart.tsx"],"sourcesContent":["import {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getThemeColor,\n MantineColor,\n rem,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport classes from './GaugeChart.module.css';\n\nexport interface GaugeChartSection {\n /** Upper bound value for this section */\n value: number;\n\n /** Color of the section */\n color: MantineColor;\n}\n\nexport type GaugeChartStylesNames = 'root' | 'track' | 'section' | 'needle' | 'label';\n\nexport type GaugeChartCssVariables = {\n root: '--gauge-size';\n};\n\nexport interface GaugeChartProps\n extends\n BoxProps,\n StylesApiProps<GaugeChartFactory>,\n ElementProps<'svg', 'display' | 'opacity' | 'viewBox' | 'width' | 'height' | 'target'> {\n /** Current value to display. Fills the arc from `min` up to `value`, unless `sections` is set – then the arc is colored by thresholds and the value is displayed only in the center label. */\n value: number;\n\n /** Minimum value of the gauge, @default 0 */\n min?: number;\n\n /** Maximum value of the gauge, @default 100 */\n max?: number;\n\n /** Value marked on the arc with a line marker, use to display a goal or the current value of a gauge with `sections` */\n target?: number;\n\n /** Threshold sections of the gauge arc, each section is filled from the previous section upper bound to its own `value`. If set, the arc is not filled based on `value`. */\n sections?: GaugeChartSection[];\n\n /** Arc thickness in px, @default 12 */\n thickness?: number;\n\n /** Chart size (width and height), @default 200 */\n size?: number;\n\n /** Start angle in degrees, @default -120 */\n startAngle?: number;\n\n /** End angle in degrees, @default 120 */\n endAngle?: number;\n\n /** Label displayed in the center of the gauge */\n label?: React.ReactNode;\n\n /** Value formatter for default label, @default (v) => String(v) */\n valueFormatter?: (value: number) => string;\n\n /** Color of the gauge track (unfilled portion) */\n trackColor?: MantineColor;\n\n /** Color of the filled arc when sections are not provided */\n filledColor?: MantineColor;\n\n /** Color of the target marker */\n targetColor?: MantineColor;\n\n /** Thickness of the target marker, @default 2 */\n targetSize?: number;\n\n /** Whether to round arc endpoints. Not applied to `sections` – rounded caps of adjacent sections would overlap each other. @default false */\n roundCaps?: boolean;\n}\n\nexport type GaugeChartFactory = Factory<{\n props: GaugeChartProps;\n ref: SVGSVGElement;\n stylesNames: GaugeChartStylesNames;\n vars: GaugeChartCssVariables;\n}>;\n\nconst defaultProps = {\n min: 0,\n max: 100,\n thickness: 12,\n size: 200,\n startAngle: -120,\n endAngle: 120,\n roundCaps: false,\n targetSize: 2,\n} satisfies Partial<GaugeChartProps>;\n\nconst varsResolver = createVarsResolver<GaugeChartFactory>((_theme, { size }) => ({\n root: {\n '--gauge-size': rem(size),\n },\n}));\n\nfunction polarToCartesian(cx: number, cy: number, r: number, angleDeg: number) {\n const rad = ((angleDeg - 90) * Math.PI) / 180;\n return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) };\n}\n\nfunction describeArc(cx: number, cy: number, r: number, startAngle: number, endAngle: number) {\n const delta = endAngle - startAngle;\n const sweep = delta >= 0 ? 1 : 0;\n const start = polarToCartesian(cx, cy, r, startAngle);\n\n // A single arc command cannot express a full circle – its endpoints would be identical\n // and nothing would be rendered, so it is split into two half-circle arcs.\n if (Math.abs(delta) >= 360) {\n const mid = polarToCartesian(cx, cy, r, startAngle + (delta >= 0 ? 180 : -180));\n return `M ${start.x} ${start.y} A ${r} ${r} 0 0 ${sweep} ${mid.x} ${mid.y} A ${r} ${r} 0 0 ${sweep} ${start.x} ${start.y}`;\n }\n\n const end = polarToCartesian(cx, cy, r, endAngle);\n const largeArc = Math.abs(delta) > 180 ? 1 : 0;\n return `M ${start.x} ${start.y} A ${r} ${r} 0 ${largeArc} ${sweep} ${end.x} ${end.y}`;\n}\n\nfunction valueToAngle(\n value: number,\n min: number,\n max: number,\n startAngle: number,\n endAngle: number\n) {\n if (max === min) {\n return startAngle;\n }\n const clamped = Math.max(min, Math.min(max, value));\n return startAngle + ((clamped - min) / (max - min)) * (endAngle - startAngle);\n}\n\nfunction isAngleInArc(angle: number, start: number, end: number) {\n const delta = end - start;\n\n if (Math.abs(delta) >= 360) {\n return true;\n }\n\n // Distance from the start angle measured along the direction the arc sweeps,\n // so that descending ranges (endAngle < startAngle) are handled the same way.\n const distance = delta >= 0 ? angle - start : start - angle;\n return ((distance % 360) + 360) % 360 <= Math.abs(delta);\n}\n\nfunction getArcBoundingBox(\n cx: number,\n cy: number,\n r: number,\n startAngle: number,\n endAngle: number,\n padding: number,\n labelReserve: number\n) {\n const startPt = polarToCartesian(cx, cy, r, startAngle);\n const endPt = polarToCartesian(cx, cy, r, endAngle);\n\n let minX = Math.min(startPt.x, endPt.x, cx - labelReserve);\n let maxX = Math.max(startPt.x, endPt.x, cx + labelReserve);\n let minY = Math.min(startPt.y, endPt.y, cy - labelReserve);\n let maxY = Math.max(startPt.y, endPt.y, cy + labelReserve);\n\n const cardinals = [\n { angle: 0, x: cx, y: cy - r },\n { angle: 90, x: cx + r, y: cy },\n { angle: 180, x: cx, y: cy + r },\n { angle: 270, x: cx - r, y: cy },\n ];\n\n for (const cardinal of cardinals) {\n if (isAngleInArc(cardinal.angle, startAngle, endAngle)) {\n minX = Math.min(minX, cardinal.x);\n maxX = Math.max(maxX, cardinal.x);\n minY = Math.min(minY, cardinal.y);\n maxY = Math.max(maxY, cardinal.y);\n }\n }\n\n return {\n x: minX - padding,\n y: minY - padding,\n width: maxX - minX + padding * 2,\n height: maxY - minY + padding * 2,\n };\n}\n\nexport const GaugeChart = factory<GaugeChartFactory>((_props) => {\n const props = useProps('GaugeChart', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n attributes,\n value,\n min,\n max,\n target,\n sections,\n thickness,\n size,\n startAngle,\n endAngle,\n label,\n valueFormatter,\n trackColor,\n filledColor,\n targetColor,\n targetSize,\n roundCaps,\n variant,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n\n const getStyles = useStyles<GaugeChartFactory>({\n name: 'GaugeChart',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const svgSize = size!;\n const cx = svgSize / 2;\n const cy = svgSize / 2;\n const r = (svgSize - thickness!) / 2;\n const strokeLinecap = roundCaps ? 'round' : 'butt';\n const needleLength = thickness! * 1.5;\n\n // The needle sticks out past the arc radius, and a round cap adds half of its own\n // width on top of that – both contribute at the same time. Only reserved when there is a\n // target to draw, otherwise every gauge without one would get an oversized viewBox and\n // render its arc smaller than the requested `size`.\n const needleExtent = needleLength / 2 + (roundCaps ? targetSize! / 2 : 0);\n const strokePadding = target != null ? Math.max(thickness! / 2, needleExtent) : thickness! / 2;\n\n // A gauge cannot span more than a full turn – a larger range would wrap the arc onto\n // itself and make later sections overwrite earlier ones.\n const span = endAngle! - startAngle!;\n const resolvedEndAngle = startAngle! + Math.max(-360, Math.min(360, span));\n\n const labelReserve = Math.max(thickness!, svgSize * 0.11);\n const bbox = getArcBoundingBox(\n cx,\n cy,\n r,\n startAngle!,\n resolvedEndAngle,\n strokePadding,\n labelReserve\n );\n\n const resolvedTrackColor = trackColor\n ? getThemeColor(trackColor, theme)\n : 'var(--mantine-color-default-border)';\n\n const trackPath = describeArc(cx, cy, r, startAngle!, resolvedEndAngle);\n\n const sectionElements =\n sections && sections.length > 0 ? (\n (() => {\n const sortedSections = [...sections].sort((a, b) => a.value - b.value);\n const direction = resolvedEndAngle >= startAngle! ? 1 : -1;\n let prevAngle = startAngle!;\n\n return sortedSections.map((section, index) => {\n const sectionEndAngle = valueToAngle(\n section.value,\n min!,\n max!,\n startAngle!,\n resolvedEndAngle\n );\n if ((sectionEndAngle - prevAngle) * direction <= 0) {\n return null;\n }\n const path = describeArc(cx, cy, r, prevAngle, sectionEndAngle);\n const resolvedColor = getThemeColor(section.color, theme);\n prevAngle = sectionEndAngle;\n\n return (\n <path\n key={index}\n {...getStyles('section')}\n d={path}\n fill=\"none\"\n stroke={resolvedColor}\n strokeWidth={thickness}\n strokeLinecap=\"butt\"\n />\n );\n });\n })()\n ) : (\n <path\n {...getStyles('section')}\n d={describeArc(\n cx,\n cy,\n r,\n startAngle!,\n valueToAngle(value, min!, max!, startAngle!, resolvedEndAngle)\n )}\n fill=\"none\"\n stroke={\n filledColor ? getThemeColor(filledColor, theme) : 'var(--mantine-primary-color-filled)'\n }\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n );\n\n const needleElement =\n target != null\n ? (() => {\n const targetAngle = valueToAngle(target, min!, max!, startAngle!, resolvedEndAngle);\n const inner = polarToCartesian(cx, cy, r - needleLength / 2, targetAngle);\n const outer = polarToCartesian(cx, cy, r + needleLength / 2, targetAngle);\n const resolvedTargetColor = targetColor\n ? getThemeColor(targetColor, theme)\n : 'var(--mantine-color-bright)';\n\n return (\n <line\n {...getStyles('needle')}\n x1={inner.x}\n y1={inner.y}\n x2={outer.x}\n y2={outer.y}\n stroke={resolvedTargetColor}\n strokeWidth={targetSize}\n strokeLinecap={strokeLinecap}\n />\n );\n })()\n : null;\n\n const formatValue = valueFormatter || ((v: number) => String(v));\n\n // The arc is drawn from the clamped value, and `aria-valuetext` is defined as the\n // human-readable equivalent of `aria-valuenow` – reporting the raw value in either the\n // default label or `aria-valuetext` would contradict both the arc and `aria-valuenow`.\n const clampedValue = Math.max(min!, Math.min(max!, value));\n const formattedValue = formatValue(clampedValue);\n const labelContent = label !== undefined ? label : formattedValue;\n\n // A meter with no accessible name is announced as \"meter\" and nothing else, so there is\n // always a name. A string `label` names the metric (\"CPU usage\") and is used unless an\n // explicit `aria-label` is given; the generic fallback covers the rest. The default label\n // is the formatted value, which would only repeat `aria-valuetext`.\n const ariaLabel =\n others['aria-labelledby'] !== undefined\n ? undefined\n : (others['aria-label'] ?? (typeof label === 'string' ? label : undefined) ?? 'Gauge');\n\n return (\n <Box\n component=\"svg\"\n viewBox={`${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`}\n __vars={{ '--gauge-aspect-ratio': `${bbox.width} / ${bbox.height}` }}\n {...getStyles('root')}\n variant={variant}\n role=\"meter\"\n aria-label={ariaLabel}\n aria-valuenow={clampedValue}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuetext={formattedValue}\n {...others}\n >\n <path\n {...getStyles('track')}\n d={trackPath}\n fill=\"none\"\n stroke={resolvedTrackColor}\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n\n {sectionElements}\n {needleElement}\n\n <foreignObject x={bbox.x} y={bbox.y} width={bbox.width} height={bbox.height}>\n <div\n {...getStyles('label', {\n style: {\n transform: `translate(${cx - bbox.x - bbox.width / 2}px, ${cy - bbox.y - bbox.height / 2}px)`,\n },\n })}\n >\n {labelContent}\n </div>\n </foreignObject>\n </Box>\n );\n});\n\nGaugeChart.displayName = '@mantine/charts/GaugeChart';\nGaugeChart.classes = classes;\nGaugeChart.varsResolver = varsResolver;\n"],"mappings":";;;;;AA4FA,MAAM,eAAe;CACnB,KAAK;CACL,KAAK;CACL,WAAW;CACX,MAAM;CACN,YAAY;CACZ,UAAU;CACV,WAAW;CACX,YAAY;AACd;AAEA,MAAM,eAAe,oBAAuC,QAAQ,EAAE,YAAY,EAChF,MAAM,EACJ,gBAAgB,IAAI,IAAI,EAC1B,EACF,EAAE;AAEF,SAAS,iBAAiB,IAAY,IAAY,GAAW,UAAkB;CAC7E,MAAM,OAAQ,WAAW,MAAM,KAAK,KAAM;CAC1C,OAAO;EAAE,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG;EAAG,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG;CAAE;AAChE;AAEA,SAAS,YAAY,IAAY,IAAY,GAAW,YAAoB,UAAkB;CAC5F,MAAM,QAAQ,WAAW;CACzB,MAAM,QAAQ,SAAS,IAAI,IAAI;CAC/B,MAAM,QAAQ,iBAAiB,IAAI,IAAI,GAAG,UAAU;CAIpD,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK;EAC1B,MAAM,MAAM,iBAAiB,IAAI,IAAI,GAAG,cAAc,SAAS,IAAI,MAAM,KAAK;EAC9E,OAAO,KAAK,MAAM,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,MAAM,GAAG,IAAI,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM;CACzH;CAEA,MAAM,MAAM,iBAAiB,IAAI,IAAI,GAAG,QAAQ;CAChD,MAAM,WAAW,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI;CAC7C,OAAO,KAAK,MAAM,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,SAAS,GAAG,MAAM,GAAG,IAAI,EAAE,GAAG,IAAI;AACpF;AAEA,SAAS,aACP,OACA,KACA,KACA,YACA,UACA;CACA,IAAI,QAAQ,KACV,OAAO;CAGT,OAAO,cADS,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,CACrB,IAAI,QAAQ,MAAM,QAAS,WAAW;AACpE;AAEA,SAAS,aAAa,OAAe,OAAe,KAAa;CAC/D,MAAM,QAAQ,MAAM;CAEpB,IAAI,KAAK,IAAI,KAAK,KAAK,KACrB,OAAO;CAMT,SADiB,SAAS,IAAI,QAAQ,QAAQ,QAAQ,SAClC,MAAO,OAAO,OAAO,KAAK,IAAI,KAAK;AACzD;AAEA,SAAS,kBACP,IACA,IACA,GACA,YACA,UACA,SACA,cACA;CACA,MAAM,UAAU,iBAAiB,IAAI,IAAI,GAAG,UAAU;CACtD,MAAM,QAAQ,iBAAiB,IAAI,IAAI,GAAG,QAAQ;CAElD,IAAI,OAAO,KAAK,IAAI,QAAQ,GAAG,MAAM,GAAG,KAAK,YAAY;CACzD,IAAI,OAAO,KAAK,IAAI,QAAQ,GAAG,MAAM,GAAG,KAAK,YAAY;CACzD,IAAI,OAAO,KAAK,IAAI,QAAQ,GAAG,MAAM,GAAG,KAAK,YAAY;CACzD,IAAI,OAAO,KAAK,IAAI,QAAQ,GAAG,MAAM,GAAG,KAAK,YAAY;CAEzD,MAAM,YAAY;EAChB;GAAE,OAAO;GAAG,GAAG;GAAI,GAAG,KAAK;EAAE;EAC7B;GAAE,OAAO;GAAI,GAAG,KAAK;GAAG,GAAG;EAAG;EAC9B;GAAE,OAAO;GAAK,GAAG;GAAI,GAAG,KAAK;EAAE;EAC/B;GAAE,OAAO;GAAK,GAAG,KAAK;GAAG,GAAG;EAAG;CACjC;CAEA,KAAK,MAAM,YAAY,WACrB,IAAI,aAAa,SAAS,OAAO,YAAY,QAAQ,GAAG;EACtD,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;EAChC,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;EAChC,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;EAChC,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;CAClC;CAGF,OAAO;EACL,GAAG,OAAO;EACV,GAAG,OAAO;EACV,OAAO,OAAO,OAAO,UAAU;EAC/B,QAAQ,OAAO,OAAO,UAAU;CAClC;AACF;AAEA,MAAa,aAAa,SAA4B,WAAW;CAC/D,MAAM,QAAQ,SAAS,cAAc,cAAc,MAAM;CACzD,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,YACA,OACA,KACA,KACA,QACA,UACA,WACA,MACA,YACA,UACA,OACA,gBACA,YACA,aACA,aACA,YACA,WACA,SACA,GAAG,WACD;CAEJ,MAAM,QAAQ,gBAAgB;CAE9B,MAAM,YAAY,UAA6B;EAC7C,MAAM;EACN,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,UAAU;CAChB,MAAM,KAAK,UAAU;CACrB,MAAM,KAAK,UAAU;CACrB,MAAM,KAAK,UAAU,aAAc;CACnC,MAAM,gBAAgB,YAAY,UAAU;CAC5C,MAAM,eAAe,YAAa;CAMlC,MAAM,eAAe,eAAe,KAAK,YAAY,aAAc,IAAI;CACvE,MAAM,gBAAgB,UAAU,OAAO,KAAK,IAAI,YAAa,GAAG,YAAY,IAAI,YAAa;CAI7F,MAAM,OAAO,WAAY;CACzB,MAAM,mBAAmB,aAAc,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;CAGzE,MAAM,OAAO,kBACX,IACA,IACA,GACA,YACA,kBACA,eAPmB,KAAK,IAAI,WAAY,UAAU,GAQvC,CACb;CAEA,MAAM,qBAAqB,aACvB,cAAc,YAAY,KAAK,IAC/B;CAEJ,MAAM,YAAY,YAAY,IAAI,IAAI,GAAG,YAAa,gBAAgB;CAEtE,MAAM,kBACJ,YAAY,SAAS,SAAS,WACrB;EACL,MAAM,iBAAiB,CAAC,GAAG,QAAQ,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;EACrE,MAAM,YAAY,oBAAoB,aAAc,IAAI;EACxD,IAAI,YAAY;EAEhB,OAAO,eAAe,KAAK,SAAS,UAAU;GAC5C,MAAM,kBAAkB,aACtB,QAAQ,OACR,KACA,KACA,YACA,gBACF;GACA,KAAK,kBAAkB,aAAa,aAAa,GAC/C,OAAO;GAET,MAAM,OAAO,YAAY,IAAI,IAAI,GAAG,WAAW,eAAe;GAC9D,MAAM,gBAAgB,cAAc,QAAQ,OAAO,KAAK;GACxD,YAAY;GAEZ,OACE,oBAAC,QAAD;IAEE,GAAI,UAAU,SAAS;IACvB,GAAG;IACH,MAAK;IACL,QAAQ;IACR,aAAa;IACb,eAAc;GACf,GAPM,KAON;EAEL,CAAC;CACH,EAAA,CAAG,IAEH,oBAAC,QAAD;EACE,GAAI,UAAU,SAAS;EACvB,GAAG,YACD,IACA,IACA,GACA,YACA,aAAa,OAAO,KAAM,KAAM,YAAa,gBAAgB,CAC/D;EACA,MAAK;EACL,QACE,cAAc,cAAc,aAAa,KAAK,IAAI;EAEpD,aAAa;EACE;CAChB,CAAA;CAGL,MAAM,gBACJ,UAAU,cACC;EACL,MAAM,cAAc,aAAa,QAAQ,KAAM,KAAM,YAAa,gBAAgB;EAClF,MAAM,QAAQ,iBAAiB,IAAI,IAAI,IAAI,eAAe,GAAG,WAAW;EACxE,MAAM,QAAQ,iBAAiB,IAAI,IAAI,IAAI,eAAe,GAAG,WAAW;EACxE,MAAM,sBAAsB,cACxB,cAAc,aAAa,KAAK,IAChC;EAEJ,OACE,oBAAC,QAAD;GACE,GAAI,UAAU,QAAQ;GACtB,IAAI,MAAM;GACV,IAAI,MAAM;GACV,IAAI,MAAM;GACV,IAAI,MAAM;GACV,QAAQ;GACR,aAAa;GACE;EAChB,CAAA;CAEL,EAAA,CAAG,IACH;CAEN,MAAM,cAAc,oBAAoB,MAAc,OAAO,CAAC;CAK9D,MAAM,eAAe,KAAK,IAAI,KAAM,KAAK,IAAI,KAAM,KAAK,CAAC;CACzD,MAAM,iBAAiB,YAAY,YAAY;CAC/C,MAAM,eAAe,UAAU,KAAA,IAAY,QAAQ;CAMnD,MAAM,YACJ,OAAO,uBAAuB,KAAA,IAC1B,KAAA,IACC,OAAO,kBAAkB,OAAO,UAAU,WAAW,QAAQ,KAAA,MAAc;CAElF,OACE,qBAAC,KAAD;EACE,WAAU;EACV,SAAS,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,MAAM,GAAG,KAAK;EACnD,QAAQ,EAAE,wBAAwB,GAAG,KAAK,MAAM,KAAK,KAAK,SAAS;EACnE,GAAI,UAAU,MAAM;EACX;EACT,MAAK;EACL,cAAY;EACZ,iBAAe;EACf,iBAAe;EACf,iBAAe;EACf,kBAAgB;EAChB,GAAI;EAZN,UAAA;GAcE,oBAAC,QAAD;IACE,GAAI,UAAU,OAAO;IACrB,GAAG;IACH,MAAK;IACL,QAAQ;IACR,aAAa;IACE;GAChB,CAAA;GAEA;GACA;GAED,oBAAC,iBAAD;IAAe,GAAG,KAAK;IAAG,GAAG,KAAK;IAAG,OAAO,KAAK;IAAO,QAAQ,KAAK;IACnE,UAAA,oBAAC,OAAD;KACE,GAAI,UAAU,SAAS,EACrB,OAAO,EACL,WAAW,aAAa,KAAK,KAAK,IAAI,KAAK,QAAQ,EAAE,MAAM,KAAK,KAAK,IAAI,KAAK,SAAS,EAAE,KAC3F,EACF,CAAC;KAEA,UAAA;IACE,CAAA;GACQ,CAAA;EACZ;;AAET,CAAC;AAED,WAAW,cAAc;AACzB,WAAW,UAAUA;AACrB,WAAW,eAAe"}
1
+ {"version":3,"file":"GaugeChart.mjs","names":["classes"],"sources":["../../src/GaugeChart/GaugeChart.tsx"],"sourcesContent":["import {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getThemeColor,\n MantineColor,\n rem,\n StylesApiProps,\n useMantineTheme,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport classes from './GaugeChart.module.css';\n\nexport interface GaugeChartSection {\n /** Upper bound value for this section */\n value: number;\n\n /** Color of the section */\n color: MantineColor;\n}\n\nexport type GaugeChartStylesNames =\n | 'root'\n | 'track'\n | 'section'\n | 'sectionCap'\n | 'needle'\n | 'label';\n\nexport type GaugeChartCssVariables = {\n root: '--gauge-size';\n};\n\nexport interface GaugeChartProps\n extends\n BoxProps,\n StylesApiProps<GaugeChartFactory>,\n ElementProps<'svg', 'display' | 'opacity' | 'viewBox' | 'width' | 'height' | 'target'> {\n /** Current value to display. Fills the arc from `min` up to `value`, unless `sections` is set – then the arc is colored by thresholds and the value is displayed only in the center label. */\n value: number;\n\n /** Minimum value of the gauge, @default 0 */\n min?: number;\n\n /** Maximum value of the gauge, @default 100 */\n max?: number;\n\n /** Value marked on the arc with a line marker, use to display a goal or the current value of a gauge with `sections` */\n target?: number;\n\n /** Threshold sections of the gauge arc, each section is filled from the previous section upper bound to its own `value`. If set, the arc is not filled based on `value`. */\n sections?: GaugeChartSection[];\n\n /** Arc thickness in px, @default 12 */\n thickness?: number;\n\n /** Chart size (width and height), @default 200 */\n size?: number;\n\n /** Start angle in degrees, @default -120 */\n startAngle?: number;\n\n /** End angle in degrees, @default 120 */\n endAngle?: number;\n\n /** Label displayed in the center of the gauge */\n label?: React.ReactNode;\n\n /** Value formatter for default label, @default (v) => String(v) */\n valueFormatter?: (value: number) => string;\n\n /** Color of the gauge track (unfilled portion) */\n trackColor?: MantineColor;\n\n /** Color of the filled arc when sections are not provided */\n filledColor?: MantineColor;\n\n /** Color of the target marker */\n targetColor?: MantineColor;\n\n /** Thickness of the target marker, @default 2 */\n targetSize?: number;\n\n /** Whether to round arc endpoints. With `sections`, only the outer ends of the first and last sections are rounded. @default false */\n roundCaps?: boolean;\n}\n\nexport type GaugeChartFactory = Factory<{\n props: GaugeChartProps;\n ref: SVGSVGElement;\n stylesNames: GaugeChartStylesNames;\n vars: GaugeChartCssVariables;\n}>;\n\nconst defaultProps = {\n min: 0,\n max: 100,\n thickness: 12,\n size: 200,\n startAngle: -120,\n endAngle: 120,\n roundCaps: false,\n targetSize: 2,\n} satisfies Partial<GaugeChartProps>;\n\nconst varsResolver = createVarsResolver<GaugeChartFactory>((_theme, { size }) => ({\n root: {\n '--gauge-size': rem(size),\n },\n}));\n\nfunction polarToCartesian(cx: number, cy: number, r: number, angleDeg: number) {\n const rad = ((angleDeg - 90) * Math.PI) / 180;\n return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) };\n}\n\nfunction describeArc(cx: number, cy: number, r: number, startAngle: number, endAngle: number) {\n const delta = endAngle - startAngle;\n const sweep = delta >= 0 ? 1 : 0;\n const start = polarToCartesian(cx, cy, r, startAngle);\n\n // A single arc command cannot express a full circle – its endpoints would be identical\n // and nothing would be rendered, so it is split into two half-circle arcs.\n if (Math.abs(delta) >= 360) {\n const mid = polarToCartesian(cx, cy, r, startAngle + (delta >= 0 ? 180 : -180));\n return `M ${start.x} ${start.y} A ${r} ${r} 0 0 ${sweep} ${mid.x} ${mid.y} A ${r} ${r} 0 0 ${sweep} ${start.x} ${start.y}`;\n }\n\n const end = polarToCartesian(cx, cy, r, endAngle);\n const largeArc = Math.abs(delta) > 180 ? 1 : 0;\n return `M ${start.x} ${start.y} A ${r} ${r} 0 ${largeArc} ${sweep} ${end.x} ${end.y}`;\n}\n\nfunction valueToAngle(\n value: number,\n min: number,\n max: number,\n startAngle: number,\n endAngle: number\n) {\n if (max === min) {\n return startAngle;\n }\n const clamped = Math.max(min, Math.min(max, value));\n return startAngle + ((clamped - min) / (max - min)) * (endAngle - startAngle);\n}\n\nfunction isAngleInArc(angle: number, start: number, end: number) {\n const delta = end - start;\n\n if (Math.abs(delta) >= 360) {\n return true;\n }\n\n // Distance from the start angle measured along the direction the arc sweeps,\n // so that descending ranges (endAngle < startAngle) are handled the same way.\n const distance = delta >= 0 ? angle - start : start - angle;\n return ((distance % 360) + 360) % 360 <= Math.abs(delta);\n}\n\nfunction getArcBoundingBox(\n cx: number,\n cy: number,\n r: number,\n startAngle: number,\n endAngle: number,\n padding: number,\n labelReserve: number\n) {\n const startPt = polarToCartesian(cx, cy, r, startAngle);\n const endPt = polarToCartesian(cx, cy, r, endAngle);\n\n let minX = Math.min(startPt.x, endPt.x, cx - labelReserve);\n let maxX = Math.max(startPt.x, endPt.x, cx + labelReserve);\n let minY = Math.min(startPt.y, endPt.y, cy - labelReserve);\n let maxY = Math.max(startPt.y, endPt.y, cy + labelReserve);\n\n const cardinals = [\n { angle: 0, x: cx, y: cy - r },\n { angle: 90, x: cx + r, y: cy },\n { angle: 180, x: cx, y: cy + r },\n { angle: 270, x: cx - r, y: cy },\n ];\n\n for (const cardinal of cardinals) {\n if (isAngleInArc(cardinal.angle, startAngle, endAngle)) {\n minX = Math.min(minX, cardinal.x);\n maxX = Math.max(maxX, cardinal.x);\n minY = Math.min(minY, cardinal.y);\n maxY = Math.max(maxY, cardinal.y);\n }\n }\n\n return {\n x: minX - padding,\n y: minY - padding,\n width: maxX - minX + padding * 2,\n height: maxY - minY + padding * 2,\n };\n}\n\nexport const GaugeChart = factory<GaugeChartFactory>((_props) => {\n const props = useProps('GaugeChart', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n attributes,\n value,\n min,\n max,\n target,\n sections,\n thickness,\n size,\n startAngle,\n endAngle,\n label,\n valueFormatter,\n trackColor,\n filledColor,\n targetColor,\n targetSize,\n roundCaps,\n variant,\n ...others\n } = props;\n\n const theme = useMantineTheme();\n\n const getStyles = useStyles<GaugeChartFactory>({\n name: 'GaugeChart',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const svgSize = size!;\n const cx = svgSize / 2;\n const cy = svgSize / 2;\n const r = (svgSize - thickness!) / 2;\n const strokeLinecap = roundCaps ? 'round' : 'butt';\n const needleLength = thickness! * 1.5;\n\n // The needle sticks out past the arc radius, and a round cap adds half of its own\n // width on top of that – both contribute at the same time. Only reserved when there is a\n // target to draw, otherwise every gauge without one would get an oversized viewBox and\n // render its arc smaller than the requested `size`.\n const needleExtent = needleLength / 2 + (roundCaps ? targetSize! / 2 : 0);\n const strokePadding = target != null ? Math.max(thickness! / 2, needleExtent) : thickness! / 2;\n\n // A gauge cannot span more than a full turn – a larger range would wrap the arc onto\n // itself and make later sections overwrite earlier ones.\n const span = endAngle! - startAngle!;\n const resolvedEndAngle = startAngle! + Math.max(-360, Math.min(360, span));\n\n const labelReserve = Math.max(thickness!, svgSize * 0.11);\n const bbox = getArcBoundingBox(\n cx,\n cy,\n r,\n startAngle!,\n resolvedEndAngle,\n strokePadding,\n labelReserve\n );\n\n const resolvedTrackColor = trackColor\n ? getThemeColor(trackColor, theme)\n : 'var(--mantine-color-default-border)';\n\n const trackPath = describeArc(cx, cy, r, startAngle!, resolvedEndAngle);\n\n const sectionElements =\n sections && sections.length > 0 ? (\n (() => {\n const sortedSections = [...sections].sort((a, b) => a.value - b.value);\n const direction = resolvedEndAngle >= startAngle! ? 1 : -1;\n let prevAngle = startAngle!;\n\n const resolvedSections = sortedSections.map((section) => {\n const sectionEndAngle = valueToAngle(\n section.value,\n min!,\n max!,\n startAngle!,\n resolvedEndAngle\n );\n if ((sectionEndAngle - prevAngle) * direction <= 0) {\n return null;\n }\n const path = describeArc(cx, cy, r, prevAngle, sectionEndAngle);\n prevAngle = sectionEndAngle;\n return { path, color: getThemeColor(section.color, theme) };\n });\n\n const visibleSections = resolvedSections.filter((section) => section !== null);\n\n const capSections =\n roundCaps && visibleSections.length > 0\n ? visibleSections.length === 1\n ? [visibleSections[0]]\n : [visibleSections[0], visibleSections[visibleSections.length - 1]]\n : [];\n\n return (\n <>\n {capSections.map((section, index) => (\n <path\n key={index}\n {...getStyles('sectionCap')}\n d={section.path}\n fill=\"none\"\n stroke={section.color}\n strokeWidth={thickness}\n strokeLinecap=\"round\"\n />\n ))}\n {resolvedSections.map((section, index) =>\n section ? (\n <path\n key={index}\n {...getStyles('section')}\n d={section.path}\n fill=\"none\"\n stroke={section.color}\n strokeWidth={thickness}\n strokeLinecap=\"butt\"\n />\n ) : null\n )}\n </>\n );\n })()\n ) : (\n <path\n {...getStyles('section')}\n d={describeArc(\n cx,\n cy,\n r,\n startAngle!,\n valueToAngle(value, min!, max!, startAngle!, resolvedEndAngle)\n )}\n fill=\"none\"\n stroke={\n filledColor ? getThemeColor(filledColor, theme) : 'var(--mantine-primary-color-filled)'\n }\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n );\n\n const needleElement =\n target != null\n ? (() => {\n const targetAngle = valueToAngle(target, min!, max!, startAngle!, resolvedEndAngle);\n const inner = polarToCartesian(cx, cy, r - needleLength / 2, targetAngle);\n const outer = polarToCartesian(cx, cy, r + needleLength / 2, targetAngle);\n const resolvedTargetColor = targetColor\n ? getThemeColor(targetColor, theme)\n : 'var(--mantine-color-bright)';\n\n return (\n <line\n {...getStyles('needle')}\n x1={inner.x}\n y1={inner.y}\n x2={outer.x}\n y2={outer.y}\n stroke={resolvedTargetColor}\n strokeWidth={targetSize}\n strokeLinecap={strokeLinecap}\n />\n );\n })()\n : null;\n\n const formatValue = valueFormatter || ((v: number) => String(v));\n\n // The arc is drawn from the clamped value, and `aria-valuetext` is defined as the\n // human-readable equivalent of `aria-valuenow` – reporting the raw value in either the\n // default label or `aria-valuetext` would contradict both the arc and `aria-valuenow`.\n const clampedValue = Math.max(min!, Math.min(max!, value));\n const formattedValue = formatValue(clampedValue);\n const labelContent = label !== undefined ? label : formattedValue;\n\n // A meter with no accessible name is announced as \"meter\" and nothing else, so there is\n // always a name. A string `label` names the metric (\"CPU usage\") and is used unless an\n // explicit `aria-label` is given; the generic fallback covers the rest. The default label\n // is the formatted value, which would only repeat `aria-valuetext`.\n const ariaLabel =\n others['aria-labelledby'] !== undefined\n ? undefined\n : (others['aria-label'] ?? (typeof label === 'string' ? label : undefined) ?? 'Gauge');\n\n return (\n <Box\n component=\"svg\"\n viewBox={`${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`}\n __vars={{ '--gauge-aspect-ratio': `${bbox.width} / ${bbox.height}` }}\n {...getStyles('root')}\n variant={variant}\n role=\"meter\"\n aria-label={ariaLabel}\n aria-valuenow={clampedValue}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuetext={formattedValue}\n {...others}\n >\n <path\n {...getStyles('track')}\n d={trackPath}\n fill=\"none\"\n stroke={resolvedTrackColor}\n strokeWidth={thickness}\n strokeLinecap={strokeLinecap}\n />\n\n {sectionElements}\n {needleElement}\n\n <foreignObject x={bbox.x} y={bbox.y} width={bbox.width} height={bbox.height}>\n <div\n {...getStyles('label', {\n style: {\n transform: `translate(${cx - bbox.x - bbox.width / 2}px, ${cy - bbox.y - bbox.height / 2}px)`,\n },\n })}\n >\n {labelContent}\n </div>\n </foreignObject>\n </Box>\n );\n});\n\nGaugeChart.displayName = '@mantine/charts/GaugeChart';\nGaugeChart.classes = classes;\nGaugeChart.varsResolver = varsResolver;\n"],"mappings":"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"}
@@ -5,7 +5,7 @@ export interface GaugeChartSection {
5
5
  /** Color of the section */
6
6
  color: MantineColor;
7
7
  }
8
- export type GaugeChartStylesNames = 'root' | 'track' | 'section' | 'needle' | 'label';
8
+ export type GaugeChartStylesNames = 'root' | 'track' | 'section' | 'sectionCap' | 'needle' | 'label';
9
9
  export type GaugeChartCssVariables = {
10
10
  root: '--gauge-size';
11
11
  };
@@ -40,7 +40,7 @@ export interface GaugeChartProps extends BoxProps, StylesApiProps<GaugeChartFact
40
40
  targetColor?: MantineColor;
41
41
  /** Thickness of the target marker, @default 2 */
42
42
  targetSize?: number;
43
- /** Whether to round arc endpoints. Not applied to `sections` – rounded caps of adjacent sections would overlap each other. @default false */
43
+ /** Whether to round arc endpoints. With `sections`, only the outer ends of the first and last sections are rounded. @default false */
44
44
  roundCaps?: boolean;
45
45
  }
46
46
  export type GaugeChartFactory = Factory<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mantine/charts",
3
- "version": "9.6.1",
3
+ "version": "9.6.2",
4
4
  "description": "Charts components built with recharts and Mantine",
5
5
  "homepage": "https://mantine.dev/",
6
6
  "license": "MIT",
@@ -35,8 +35,8 @@
35
35
  "directory": "packages/@mantine/charts"
36
36
  },
37
37
  "peerDependencies": {
38
- "@mantine/core": "9.6.1",
39
- "@mantine/hooks": "9.6.1",
38
+ "@mantine/core": "9.6.2",
39
+ "@mantine/hooks": "9.6.2",
40
40
  "react": "^19.2.0",
41
41
  "react-dom": "^19.2.0",
42
42
  "recharts": ">=3.2.1"