diff --git a/.changeset/sixty-parrots-tan.md b/.changeset/sixty-parrots-tan.md new file mode 100644 index 0000000000..88436391eb --- /dev/null +++ b/.changeset/sixty-parrots-tan.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Make number of decimal digits in Gauge configurable via the `decimalDigits` property diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index 0f71bcb004..597b1a9abf 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -450,6 +450,8 @@ export type GaugeProps = { size?: 'normal' | 'small'; description?: ReactNode; getColor?: GaugePropsGetColor; + relativeToMax?: boolean; + decimalDigits?: number; }; // @public (undocumented) diff --git a/packages/core-components/src/components/ProgressBars/Gauge.test.tsx b/packages/core-components/src/components/ProgressBars/Gauge.test.tsx index 2d9e852e6c..2d92391a30 100644 --- a/packages/core-components/src/components/ProgressBars/Gauge.test.tsx +++ b/packages/core-components/src/components/ProgressBars/Gauge.test.tsx @@ -47,6 +47,27 @@ describe('', () => { getByText('10m'); }); + it('handle relativeToMax prop', async () => { + const { getByText } = await renderInTestApp( + , + ); + getByText('7 pts'); + }); + + it('handle decimalDigits prop', async () => { + const { getByText } = await renderInTestApp( + , + ); + getByText('5.50/10'); + }); + const ok = '#111'; const warning = '#222'; const error = '#333'; diff --git a/packages/core-components/src/components/ProgressBars/Gauge.tsx b/packages/core-components/src/components/ProgressBars/Gauge.tsx index e72172fd59..a1ddbff4ea 100644 --- a/packages/core-components/src/components/ProgressBars/Gauge.tsx +++ b/packages/core-components/src/components/ProgressBars/Gauge.tsx @@ -75,6 +75,8 @@ export type GaugeProps = { size?: 'normal' | 'small'; description?: ReactNode; getColor?: GaugePropsGetColor; + relativeToMax?: boolean; + decimalDigits?: number; }; /** @public */ @@ -93,6 +95,7 @@ const defaultGaugeProps = { inverse: false, unit: '%', max: 100, + relativeToMax: false, }; export const getProgressColor: GaugePropsGetColor = ({ @@ -129,13 +132,36 @@ export function Gauge(props: GaugeProps) { const { getColor = getProgressColor, size = 'normal' } = props; const classes = useStyles(props); const { palette } = useTheme(); - const { value, fractional, inverse, unit, max, description } = { + const { + value, + fractional, + inverse, + unit, + max, + description, + relativeToMax, + decimalDigits, + } = { ...defaultGaugeProps, ...props, }; - const asPercentage = fractional ? Math.round(value * max) : value; - const asActual = max !== 100 ? Math.round(value) : asPercentage; + let asPercentage: number; + if (relativeToMax) { + asPercentage = (value / max) * 100; + } else { + asPercentage = fractional ? Math.round(value * max) : value; + } + let asActual: number; + if (relativeToMax) { + asActual = value; + } else { + asActual = max !== 100 ? Math.round(value) : asPercentage; + } + const asDisplay = + decimalDigits === undefined + ? asActual.toString() + : asActual.toFixed(decimalDigits); const [isHovering, setIsHovering] = useState(false); @@ -164,7 +190,12 @@ export function Gauge(props: GaugeProps) { percent={asPercentage} strokeWidth={12} trailWidth={12} - strokeColor={getColor({ palette, value: asActual, inverse, max })} + strokeColor={getColor({ + palette, + value: asPercentage, + inverse, + max: relativeToMax ? 100 : max, + })} className={classes.circle} /> {description && isHovering ? ( @@ -175,7 +206,7 @@ export function Gauge(props: GaugeProps) { [classes.overlaySmall]: size === 'small', })} > - {isNaN(value) ? 'N/A' : `${asActual}${unit}`} + {isNaN(value) ? 'N/A' : `${asDisplay}${unit}`} )}