From aeca3d7115a803f61716d046a71d92bcc6a5e2ea Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 1 Apr 2026 18:02:42 +0300 Subject: [PATCH 01/46] [circularprogress][linearprogress] Improve accessibility --- .../material-ui/api/linear-progress.json | 2 + .../linear-progress/linear-progress.json | 12 ++- .../src/LinearProgress/LinearProgress.d.ts | 10 ++ .../src/LinearProgress/LinearProgress.js | 39 +++++-- .../src/LinearProgress/LinearProgress.test.js | 100 ++++++++++++++++++ 5 files changed, 154 insertions(+), 9 deletions(-) diff --git a/docs/pages/material-ui/api/linear-progress.json b/docs/pages/material-ui/api/linear-progress.json index 24bad2d39cb85c..d6204754fbbb94 100644 --- a/docs/pages/material-ui/api/linear-progress.json +++ b/docs/pages/material-ui/api/linear-progress.json @@ -8,6 +8,8 @@ }, "default": "'primary'" }, + "maxValue": { "type": { "name": "number" }, "default": "100" }, + "minValue": { "type": { "name": "number" }, "default": "0" }, "sx": { "type": { "name": "union", diff --git a/docs/translations/api-docs/linear-progress/linear-progress.json b/docs/translations/api-docs/linear-progress/linear-progress.json index 58187bd226c6a9..e7894768ed859c 100644 --- a/docs/translations/api-docs/linear-progress/linear-progress.json +++ b/docs/translations/api-docs/linear-progress/linear-progress.json @@ -5,13 +5,21 @@ "color": { "description": "The color of the component. It supports both default and custom theme colors, which can be added as shown in the palette customization guide." }, + "maxValue": { + "description": "The maximum value of progress in determinate and buffer variants." + }, + "minValue": { + "description": "The minimum value of progress in determinate and buffer variants." + }, "sx": { "description": "The system prop that allows defining system overrides as well as additional CSS styles." }, "value": { - "description": "The value of the progress indicator for the determinate and buffer variants. Value between 0 and 100." + "description": "The value of the progress indicator for the determinate and buffer variants. Value between minValue and maxValue." + }, + "valueBuffer": { + "description": "The value for the buffer variant. Value between minValue and maxValue." }, - "valueBuffer": { "description": "The value for the buffer variant. Value between 0 and 100." }, "variant": { "description": "The variant to use. Use indeterminate or query when there is no progress value." } diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.d.ts b/packages/mui-material/src/LinearProgress/LinearProgress.d.ts index b6f062fd51d47b..ef6656399afa5f 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.d.ts +++ b/packages/mui-material/src/LinearProgress/LinearProgress.d.ts @@ -28,6 +28,16 @@ export interface LinearProgressProps extends StandardProps< LinearProgressPropsColorOverrides > | undefined; + /** + * The value of the progress indicator for the determinate and buffer variants. + * @default 100 + */ + maxValue?: number | undefined; + /** + * The minimum value of progress in determinate and buffer variants. + * @default 0 + */ + minValue?: number | undefined; /** * The system prop that allows defining system overrides as well as additional CSS styles. */ diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.js b/packages/mui-material/src/LinearProgress/LinearProgress.js index 620156e49a4e62..a75256c07737c5 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.js @@ -357,6 +357,8 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { const { className, color = 'primary', + maxValue = 100, + minValue = 0, value, valueBuffer, variant = 'indeterminate', @@ -377,27 +379,40 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { if (variant === 'determinate' || variant === 'buffer') { if (value !== undefined) { rootProps['aria-valuenow'] = Math.round(value); - rootProps['aria-valuemin'] = 0; - rootProps['aria-valuemax'] = 100; - let transform = value - 100; + rootProps['aria-valuemin'] = minValue; + rootProps['aria-valuemax'] = maxValue; + let transform = ((value - minValue) / (maxValue - minValue)) * 100 - 100; if (isRtl) { transform = -transform; } inlineStyles.bar1.transform = `translateX(${transform}%)`; + if ((value < minValue || value > maxValue) && process.env.NODE_ENV !== 'production') { + console.error( + `MUI: The value provided to the LinearProgress component is out of range (value: ${value}, min: ${minValue}, max: ${maxValue}).`, + ); + } } else if (process.env.NODE_ENV !== 'production') { console.error( 'MUI: You need to provide a value prop ' + - 'when using the determinate or buffer variant of LinearProgress .', + 'when using the determinate or buffer variant of LinearProgress.', ); } } if (variant === 'buffer') { if (valueBuffer !== undefined) { - let transform = (valueBuffer || 0) - 100; + let transform = ((valueBuffer - minValue) / (maxValue - minValue)) * 100 - 100; if (isRtl) { transform = -transform; } inlineStyles.bar2.transform = `translateX(${transform}%)`; + if ( + (valueBuffer < minValue || valueBuffer > maxValue || valueBuffer < value) && + process.env.NODE_ENV !== 'production' + ) { + console.error( + `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: ${valueBuffer}, value: ${value}, min: ${minValue}, max: ${maxValue}).`, + ); + } } else if (process.env.NODE_ENV !== 'production') { console.error( 'MUI: You need to provide a valueBuffer prop ' + @@ -457,6 +472,16 @@ LinearProgress.propTypes /* remove-proptypes */ = { PropTypes.oneOf(['inherit', 'primary', 'secondary']), PropTypes.string, ]), + /** + * The maximum value of progress in determinate and buffer variants. + * @default 100 + */ + maxValue: PropTypes.number, + /** + * The minimum value of progress in determinate and buffer variants. + * @default 0 + */ + minValue: PropTypes.number, /** * The system prop that allows defining system overrides as well as additional CSS styles. */ @@ -467,12 +492,12 @@ LinearProgress.propTypes /* remove-proptypes */ = { ]), /** * The value of the progress indicator for the determinate and buffer variants. - * Value between 0 and 100. + * Value between minValue and maxValue. */ value: PropTypes.number, /** * The value for the buffer variant. - * Value between 0 and 100. + * Value between minValue and maxValue. */ valueBuffer: PropTypes.number, /** diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.test.js b/packages/mui-material/src/LinearProgress/LinearProgress.test.js index aebcd614c9f69c..2d29192bcbe047 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.test.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.test.js @@ -4,6 +4,7 @@ import { screen, strictModeDoubleLoggingSuppressed, } from '@mui/internal-test-utils'; +import RtlProvider from '@mui/system/RtlProvider'; import LinearProgress, { linearProgressClasses as classes } from '@mui/material/LinearProgress'; import describeConformance from '../../test/describeConformance'; @@ -83,6 +84,17 @@ describe('', () => { expect(progressbar.children[0]).to.have.nested.property('style.transform', 'translateX(-23%)'); }); + it('should set opposite width of bar1 on determinate variant in RTL', () => { + render( + + , + , + ); + const progressbar = screen.getByRole('progressbar'); + + expect(progressbar.children[0]).to.have.nested.property('style.transform', 'translateX(23%)'); + }); + it('should render with buffer classes for the primary color by default', () => { render(); const progressbar = screen.getByRole('progressbar'); @@ -132,6 +144,7 @@ describe('', () => { it('should render with query classes', () => { render(); + const progressbar = screen.getByRole('progressbar'); expect(progressbar).to.have.class(classes.query); @@ -169,4 +182,91 @@ describe('', () => { ]); }); }); + + describe('prop: minValue & maxValue', () => { + it('should be able to use custom min and max values', () => { + render(); + const progressbar = screen.getByRole('progressbar'); + + expect(progressbar).to.have.attribute('aria-valuenow', '5'); + expect(progressbar).to.have.attribute('aria-valuemin', '0'); + expect(progressbar).to.have.attribute('aria-valuemax', '10'); + }); + + it('min and max values should be used to calculate the width of the bar', () => { + render(); + const progressbar = screen.getByRole('progressbar'); + + expect(progressbar.children[0]).to.have.nested.property( + 'style.transform', + 'translateX(-75%)', + ); + }); + + it('min and max values should be used to calculate the width of the buffer bar', () => { + render( + , + ); + const progressbar = screen.getByRole('progressbar'); + + expect(progressbar.querySelector(`.${classes.bar1}`)).to.have.nested.property( + 'style.transform', + 'translateX(-75%)', + ); + expect(progressbar.querySelector(`.${classes.bar2}`)).to.have.nested.property( + 'style.transform', + 'translateX(-25%)', + ); + }); + + it('should warn if the value is out of range', () => { + expect(() => { + render(); + }).toErrorDev([ + `MUI: The value provided to the LinearProgress component is out of range (value: -1, min: 0, max: 10).`, + !strictModeDoubleLoggingSuppressed && + `MUI: The value provided to the LinearProgress component is out of range (value: -1, min: 0, max: 10).`, + ]); + + expect(() => { + render(); + }).toErrorDev([ + `MUI: The value provided to the LinearProgress component is out of range (value: 11, min: 0, max: 10).`, + !strictModeDoubleLoggingSuppressed && + `MUI: The value provided to the LinearProgress component is out of range (value: 11, min: 0, max: 10).`, + ]); + }); + + it('should warn if the valueBuffer is out of range or less than the value prop', () => { + expect(() => { + render( + , + ); + }).toErrorDev([ + `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: 4, value: 5, min: 0, max: 10).`, + !strictModeDoubleLoggingSuppressed && + `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: 4, value: 5, min: 0, max: 10).`, + ]); + + expect(() => { + render( + , + ); + }).toErrorDev([ + `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: 11, value: 5, min: 0, max: 10).`, + !strictModeDoubleLoggingSuppressed && + `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: 11, value: 5, min: 0, max: 10).`, + ]); + + expect(() => { + render( + , + ); + }).toErrorDev([ + `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: -1, value: 5, min: 0, max: 10).`, + !strictModeDoubleLoggingSuppressed && + `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: -1, value: 5, min: 0, max: 10).`, + ]); + }); + }); }); From c1b867ad6f8c7e9803197494b3087cb6ec099a9a Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 1 Apr 2026 18:06:13 +0300 Subject: [PATCH 02/46] add linear query --- docs/data/material/components/progress/LinearQuery.js | 10 ++++++++++ docs/data/material/components/progress/LinearQuery.tsx | 10 ++++++++++ docs/data/material/components/progress/progress.md | 4 ++++ 3 files changed, 24 insertions(+) create mode 100644 docs/data/material/components/progress/LinearQuery.js create mode 100644 docs/data/material/components/progress/LinearQuery.tsx diff --git a/docs/data/material/components/progress/LinearQuery.js b/docs/data/material/components/progress/LinearQuery.js new file mode 100644 index 00000000000000..4785ca8d14b3cd --- /dev/null +++ b/docs/data/material/components/progress/LinearQuery.js @@ -0,0 +1,10 @@ +import Box from '@mui/material/Box'; +import LinearProgress from '@mui/material/LinearProgress'; + +export default function LinearQuery() { + return ( + + + + ); +} diff --git a/docs/data/material/components/progress/LinearQuery.tsx b/docs/data/material/components/progress/LinearQuery.tsx new file mode 100644 index 00000000000000..4785ca8d14b3cd --- /dev/null +++ b/docs/data/material/components/progress/LinearQuery.tsx @@ -0,0 +1,10 @@ +import Box from '@mui/material/Box'; +import LinearProgress from '@mui/material/LinearProgress'; + +export default function LinearQuery() { + return ( + + + + ); +} diff --git a/docs/data/material/components/progress/progress.md b/docs/data/material/components/progress/progress.md index b60007b63f5fa1..c017d3bef79c1e 100644 --- a/docs/data/material/components/progress/progress.md +++ b/docs/data/material/components/progress/progress.md @@ -56,6 +56,10 @@ The animations of the components rely on CSS as much as possible to work even be {{"demo": "LinearIndeterminate.js"}} +### Linear query + +{{"demo": "LinearQuery.js"}} + ### Linear color {{"demo": "LinearColor.js"}} From b18110c59efb16fbbf549b9ed97395430e9eb897 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 10:06:42 +0300 Subject: [PATCH 03/46] also add visible label to linear --- .../progress/LinearWithValueLabel.js | 37 +++++++++-------- .../progress/LinearWithValueLabel.tsx | 41 +++++++++++-------- .../material/components/progress/progress.md | 2 +- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/docs/data/material/components/progress/LinearWithValueLabel.js b/docs/data/material/components/progress/LinearWithValueLabel.js index 85251478f227df..ba9282b42f5545 100644 --- a/docs/data/material/components/progress/LinearWithValueLabel.js +++ b/docs/data/material/components/progress/LinearWithValueLabel.js @@ -4,26 +4,31 @@ import LinearProgress from '@mui/material/LinearProgress'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; -function LinearProgressWithLabel(props) { +function LinearProgressWithLabelAndValue(props) { return ( - - - +
+ + Uploading photos… + + + + + + + + {`${Math.round(props.value)}%`} + + - - - {`${Math.round(props.value)}%`} - - - +
); } -LinearProgressWithLabel.propTypes = { +LinearProgressWithLabelAndValue.propTypes = { /** * The value of the progress indicator for the determinate and buffer variants. * Value between 0 and 100. @@ -45,7 +50,7 @@ export default function LinearWithValueLabel() { return ( - + ); } diff --git a/docs/data/material/components/progress/LinearWithValueLabel.tsx b/docs/data/material/components/progress/LinearWithValueLabel.tsx index 49d05a435fdf26..27cf48ec9aa0e3 100644 --- a/docs/data/material/components/progress/LinearWithValueLabel.tsx +++ b/docs/data/material/components/progress/LinearWithValueLabel.tsx @@ -3,23 +3,32 @@ import LinearProgress, { LinearProgressProps } from '@mui/material/LinearProgres import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; -function LinearProgressWithLabel(props: LinearProgressProps & { value: number }) { +function LinearProgressWithLabelAndValue(props: LinearProgressProps & { value: number }) { return ( - - - +
+ + Uploading photos… + + + + + + + + {`${Math.round(props.value)}%`} + + - - {`${Math.round(props.value)}%`} - - +
); } @@ -37,7 +46,7 @@ export default function LinearWithValueLabel() { return ( - + ); } diff --git a/docs/data/material/components/progress/progress.md b/docs/data/material/components/progress/progress.md index c017d3bef79c1e..c5fd1eb6a4b4f7 100644 --- a/docs/data/material/components/progress/progress.md +++ b/docs/data/material/components/progress/progress.md @@ -72,7 +72,7 @@ The animations of the components rely on CSS as much as possible to work even be {{"demo": "LinearBuffer.js"}} -### Linear with label +### Linear with label and value label {{"demo": "LinearWithValueLabel.js"}} From 0dafb88d67d80c3a9a01cd6fc43ea825c2643c79 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 10:07:28 +0300 Subject: [PATCH 04/46] update proptypes --- packages/mui-material/src/LinearProgress/LinearProgress.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.js b/packages/mui-material/src/LinearProgress/LinearProgress.js index a75256c07737c5..36b533f15e06b8 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.js @@ -473,7 +473,7 @@ LinearProgress.propTypes /* remove-proptypes */ = { PropTypes.string, ]), /** - * The maximum value of progress in determinate and buffer variants. + * The value of the progress indicator for the determinate and buffer variants. * @default 100 */ maxValue: PropTypes.number, @@ -492,12 +492,12 @@ LinearProgress.propTypes /* remove-proptypes */ = { ]), /** * The value of the progress indicator for the determinate and buffer variants. - * Value between minValue and maxValue. + * Value between 0 and 100. */ value: PropTypes.number, /** * The value for the buffer variant. - * Value between minValue and maxValue. + * Value between 0 and 100. */ valueBuffer: PropTypes.number, /** From c37598195baac7a9d0f558c19bcd422fa83e5048 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 10:36:43 +0300 Subject: [PATCH 05/46] linear with aria-valuetext --- .../progress/LinearWithAriaValueText.js | 73 ++++++++++++++++ .../progress/LinearWithAriaValueText.tsx | 85 +++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 docs/data/material/components/progress/LinearWithAriaValueText.js create mode 100644 docs/data/material/components/progress/LinearWithAriaValueText.tsx diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.js b/docs/data/material/components/progress/LinearWithAriaValueText.js new file mode 100644 index 00000000000000..925263a6cdc044 --- /dev/null +++ b/docs/data/material/components/progress/LinearWithAriaValueText.js @@ -0,0 +1,73 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import LinearProgress from '@mui/material/LinearProgress'; +import Typography from '@mui/material/Typography'; +import Box from '@mui/material/Box'; + +function LinearProgressWithLabelAndValue({ maxValue, minValue, value }) { + const progressText = `${value} out of ${maxValue} files`; + return ( +
+ + Uploading photos… + + + + + + + + {progressText} + + + +
+ ); +} + +LinearProgressWithLabelAndValue.propTypes = { + /** + * The value of the progress indicator for the determinate and buffer variants. + * Value between 0 and 100. + */ + value: PropTypes.number.isRequired, + /** + * The minimum value of the progress indicator. + */ + minValue: PropTypes.number.isRequired, + /** + * The maximum value of the progress indicator. + */ + maxValue: PropTypes.number.isRequired, +}; + +export default function LinearWithAriaValueText() { + const [progress, setProgress] = React.useState(0); + + React.useEffect(() => { + const timer = setInterval(() => { + setProgress((prevProgress) => (prevProgress >= 10 ? 0 : prevProgress + 1)); + }, 800); + return () => { + clearInterval(timer); + }; + }, []); + + return ( + + + + ); +} diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.tsx b/docs/data/material/components/progress/LinearWithAriaValueText.tsx new file mode 100644 index 00000000000000..c21bfe5cb979bb --- /dev/null +++ b/docs/data/material/components/progress/LinearWithAriaValueText.tsx @@ -0,0 +1,85 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import LinearProgress, { LinearProgressProps } from '@mui/material/LinearProgress'; +import Typography from '@mui/material/Typography'; +import Box from '@mui/material/Box'; + +type LinearProgressWithLabelAndValueProps = LinearProgressProps & { + minValue: number; + maxValue: number; + value: number; +}; + +function LinearProgressWithLabelAndValue({ + maxValue, + minValue, + value, + ...rest +}: LinearProgressWithLabelAndValueProps) { + const progressText = `${value} out of ${maxValue} files`; + return ( +
+ + Uploading photos… + + + + + + + + {progressText} + + + +
+ ); +} + +LinearProgressWithLabelAndValue.propTypes = { + /** + * The value of the progress indicator for the determinate and buffer variants. + * Value between 0 and 100. + */ + value: PropTypes.number.isRequired, + /** + * The minimum value of the progress indicator. + */ + minValue: PropTypes.number.isRequired, + /** + * The maximum value of the progress indicator. + */ + maxValue: PropTypes.number.isRequired, +}; + +export default function LinearWithAriaValueText() { + const [progress, setProgress] = React.useState(0); + + React.useEffect(() => { + const timer = setInterval(() => { + setProgress((prevProgress) => (prevProgress >= 10 ? 0 : prevProgress + 1)); + }, 800); + return () => { + clearInterval(timer); + }; + }, []); + + return ( + + + + ); +} From ad8c0f5859e6507ff78e8e6e5783de258b1741c5 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 10:36:53 +0300 Subject: [PATCH 06/46] docs add example --- docs/data/material/components/progress/progress.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/data/material/components/progress/progress.md b/docs/data/material/components/progress/progress.md index c5fd1eb6a4b4f7..591c81f76192d8 100644 --- a/docs/data/material/components/progress/progress.md +++ b/docs/data/material/components/progress/progress.md @@ -76,6 +76,12 @@ The animations of the components rely on CSS as much as possible to work even be {{"demo": "LinearWithValueLabel.js"}} +### Linear with custom value text + +By default, the progress value is read by assistive technology as percentages. Use `aria-valuetext` when you the progress value does not involve percentages. + +{{"demo": "LinearWithAriaValueText.js"}} + ## Non-standard ranges The progress components accept a value in the range 0 - 100. This simplifies things for screen-reader users, where these are the default min / max values. Sometimes, however, you might be working with a data source where the values fall outside this range. Here's how you can easily transform a value in any range to a scale of 0 - 100: From c961d520428e1b5b3531c811f8e6a3b779f1f751 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 10:37:24 +0300 Subject: [PATCH 07/46] prettier --- .../material/components/progress/LinearWithValueLabel.js | 7 ++++++- .../material/components/progress/LinearWithValueLabel.tsx | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/data/material/components/progress/LinearWithValueLabel.js b/docs/data/material/components/progress/LinearWithValueLabel.js index ba9282b42f5545..e0f276bba2baa2 100644 --- a/docs/data/material/components/progress/LinearWithValueLabel.js +++ b/docs/data/material/components/progress/LinearWithValueLabel.js @@ -7,7 +7,12 @@ import Box from '@mui/material/Box'; function LinearProgressWithLabelAndValue(props) { return (
- + Uploading photos… diff --git a/docs/data/material/components/progress/LinearWithValueLabel.tsx b/docs/data/material/components/progress/LinearWithValueLabel.tsx index 27cf48ec9aa0e3..a884d0316caa64 100644 --- a/docs/data/material/components/progress/LinearWithValueLabel.tsx +++ b/docs/data/material/components/progress/LinearWithValueLabel.tsx @@ -3,7 +3,9 @@ import LinearProgress, { LinearProgressProps } from '@mui/material/LinearProgres import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; -function LinearProgressWithLabelAndValue(props: LinearProgressProps & { value: number }) { +function LinearProgressWithLabelAndValue( + props: LinearProgressProps & { value: number }, +) { return (
Date: Thu, 2 Apr 2026 10:37:42 +0300 Subject: [PATCH 08/46] circular progress add props --- .../material-ui/api/circular-progress.json | 2 + .../circular-progress/circular-progress.json | 8 +++- .../linear-progress/linear-progress.json | 8 ++-- .../CircularProgress/CircularProgress.d.ts | 12 +++++- .../src/CircularProgress/CircularProgress.js | 43 ++++++++++++++++--- .../CircularProgress/CircularProgress.test.js | 42 +++++++++++++++++- 6 files changed, 100 insertions(+), 15 deletions(-) diff --git a/docs/pages/material-ui/api/circular-progress.json b/docs/pages/material-ui/api/circular-progress.json index f63f73040a471b..822147e5397177 100644 --- a/docs/pages/material-ui/api/circular-progress.json +++ b/docs/pages/material-ui/api/circular-progress.json @@ -10,6 +10,8 @@ }, "disableShrink": { "type": { "name": "custom", "description": "bool" }, "default": "false" }, "enableTrackSlot": { "type": { "name": "bool" }, "default": "false" }, + "maxValue": { "type": { "name": "number" }, "default": "100" }, + "minValue": { "type": { "name": "number" }, "default": "0" }, "size": { "type": { "name": "union", "description": "number
| string" }, "default": "40" diff --git a/docs/translations/api-docs/circular-progress/circular-progress.json b/docs/translations/api-docs/circular-progress/circular-progress.json index d8c41375452659..71cc43c08f53d7 100644 --- a/docs/translations/api-docs/circular-progress/circular-progress.json +++ b/docs/translations/api-docs/circular-progress/circular-progress.json @@ -11,6 +11,12 @@ "enableTrackSlot": { "description": "If true, a track circle slot is mounted to show a subtle background for the progress. The size and thickness apply to the track slot to be consistent with the progress circle." }, + "maxValue": { + "description": "The value of the progress indicator for the determinate and buffer variants." + }, + "minValue": { + "description": "The minimum value of progress in determinate and buffer variants." + }, "size": { "description": "The size of the component. If using a number, the pixel unit is assumed. If using a string, you need to provide the CSS unit, for example '3rem'." }, @@ -19,7 +25,7 @@ }, "thickness": { "description": "The thickness of the circle." }, "value": { - "description": "The value of the progress indicator for the determinate variant. Value between 0 and 100." + "description": "The value of the progress indicator for the determinate variant. Value between minValue and maxValue." }, "variant": { "description": "The variant to use. Use indeterminate when there is no progress value." diff --git a/docs/translations/api-docs/linear-progress/linear-progress.json b/docs/translations/api-docs/linear-progress/linear-progress.json index e7894768ed859c..0d42cc6fb834db 100644 --- a/docs/translations/api-docs/linear-progress/linear-progress.json +++ b/docs/translations/api-docs/linear-progress/linear-progress.json @@ -6,7 +6,7 @@ "description": "The color of the component. It supports both default and custom theme colors, which can be added as shown in the palette customization guide." }, "maxValue": { - "description": "The maximum value of progress in determinate and buffer variants." + "description": "The value of the progress indicator for the determinate and buffer variants." }, "minValue": { "description": "The minimum value of progress in determinate and buffer variants." @@ -15,11 +15,9 @@ "description": "The system prop that allows defining system overrides as well as additional CSS styles." }, "value": { - "description": "The value of the progress indicator for the determinate and buffer variants. Value between minValue and maxValue." - }, - "valueBuffer": { - "description": "The value for the buffer variant. Value between minValue and maxValue." + "description": "The value of the progress indicator for the determinate and buffer variants. Value between 0 and 100." }, + "valueBuffer": { "description": "The value for the buffer variant. Value between 0 and 100." }, "variant": { "description": "The variant to use. Use indeterminate or query when there is no progress value." } diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts index ccfaacc659102b..ed7593da4c9810 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts +++ b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts @@ -40,6 +40,16 @@ export interface CircularProgressProps extends StandardProps< * @default false */ enableTrackSlot?: boolean | undefined; + /** + * The value of the progress indicator for the determinate and buffer variants. + * @default 100 + */ + maxValue?: number | undefined; + /** + * The minimum value of progress in determinate and buffer variants. + * @default 0 + */ + minValue?: number | undefined; /** * The size of the component. * If using a number, the pixel unit is assumed. @@ -58,7 +68,7 @@ export interface CircularProgressProps extends StandardProps< thickness?: number | undefined; /** * The value of the progress indicator for the determinate variant. - * Value between 0 and 100. + * Value between `minValue` and `maxValue`. * @default 0 */ value?: number | undefined; diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index 0686fade4245c8..ffec8e8de4ead7 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -155,7 +155,7 @@ const CircularProgressCircle = styled('circle', { props: ({ ownerState }) => ownerState.variant === 'indeterminate' && !ownerState.disableShrink, style: dashAnimation || { - // At runtime for Pigment CSS, `bufferAnimation` will be null and the generated keyframe will be used. + // At runtime for Pigment CSS, `dashAnimation` will be null and the generated keyframe will be used. animation: `${circularDashKeyframe} 1.4s ease-in-out infinite`, }, }, @@ -187,6 +187,8 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref color = 'primary', disableShrink = false, enableTrackSlot = false, + minValue = 0, + maxValue = 100, size = 40, style, thickness = 3.6, @@ -213,11 +215,28 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref const rootProps = {}; if (variant === 'determinate') { - const circumference = 2 * Math.PI * ((SIZE - thickness) / 2); - circleStyle.strokeDasharray = circumference.toFixed(3); - rootProps['aria-valuenow'] = Math.round(value); - circleStyle.strokeDashoffset = `${(((100 - value) / 100) * circumference).toFixed(3)}px`; - rootStyle.transform = 'rotate(-90deg)'; + if (value !== undefined) { + const circumference = 2 * Math.PI * ((SIZE - thickness) / 2); + + circleStyle.strokeDasharray = circumference.toFixed(3); + circleStyle.strokeDashoffset = `${(((maxValue - value) / (maxValue - minValue)) * circumference).toFixed(3)}px`; + rootStyle.transform = 'rotate(-90deg)'; + + rootProps['aria-valuenow'] = Math.round(value); + rootProps['aria-valuemin'] = minValue; + rootProps['aria-valuemax'] = maxValue; + + if (value < minValue || value > maxValue) { + console.error( + `MUI: The value provided to the CircularProgress component is out of range (value: ${value}, min: ${minValue}, max: ${maxValue}).`, + ); + } + } else if (process.env.NODE_ENV !== 'production') { + console.error( + 'MUI: You need to provide a value prop ' + + 'when using the determinate variant of CircularProgress.', + ); + } } return ( @@ -306,6 +325,16 @@ CircularProgress.propTypes /* remove-proptypes */ = { * @default false */ enableTrackSlot: PropTypes.bool, + /** + * The value of the progress indicator for the determinate and buffer variants. + * @default 100 + */ + maxValue: PropTypes.number, + /** + * The minimum value of progress in determinate and buffer variants. + * @default 0 + */ + minValue: PropTypes.number, /** * The size of the component. * If using a number, the pixel unit is assumed. @@ -332,7 +361,7 @@ CircularProgress.propTypes /* remove-proptypes */ = { thickness: PropTypes.number, /** * The value of the progress indicator for the determinate variant. - * Value between 0 and 100. + * Value between `minValue` and `maxValue`. * @default 0 */ value: PropTypes.number, diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index 706d5e2d104202..9c46278afe8b19 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -1,5 +1,9 @@ import { expect } from 'chai'; -import { createRenderer } from '@mui/internal-test-utils'; +import { + createRenderer, + strictModeDoubleLoggingSuppressed, + screen, +} from '@mui/internal-test-utils'; import CircularProgress, { circularProgressClasses as classes, } from '@mui/material/CircularProgress'; @@ -170,4 +174,40 @@ describe('', () => { expect(trackEl.style.strokeDashoffset).to.equal(''); }); }); + + describe('prop: minValue & maxValue', () => { + it('should be able to use custom min and max values', () => { + render(); + const progressbar = screen.getByRole('progressbar'); + + expect(progressbar).to.have.attribute('aria-valuenow', '5'); + expect(progressbar).to.have.attribute('aria-valuemin', '0'); + expect(progressbar).to.have.attribute('aria-valuemax', '10'); + }); + + it('min and max values should be used to calculate the circumference of the circle', () => { + render(); + const progressbar = screen.getByRole('progressbar'); + + expect(progressbar).to.have.nested.property('style.transform', 'rotate(-90deg)'); + }); + + it('should warn if the value is out of range', () => { + expect(() => { + render(); + }).toErrorDev([ + `MUI: The value provided to the CircularProgress component is out of range (value: -1, min: 0, max: 10).`, + !strictModeDoubleLoggingSuppressed && + `MUI: The value provided to the CircularProgress component is out of range (value: -1, min: 0, max: 10).`, + ]); + + expect(() => { + render(); + }).toErrorDev([ + `MUI: The value provided to the CircularProgress component is out of range (value: 11, min: 0, max: 10).`, + !strictModeDoubleLoggingSuppressed && + `MUI: The value provided to the CircularProgress component is out of range (value: 11, min: 0, max: 10).`, + ]); + }); + }); }); From bed4f272baccd21a2fde7162f5821cbf3ab88dea Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 10:51:07 +0300 Subject: [PATCH 09/46] add circular with different scale --- .../progress/CircularCustomScale.js | 26 +++++++++++++++++++ .../progress/CircularCustomScale.tsx | 26 +++++++++++++++++++ .../progress/CircularCustomScale.tsx.preview | 7 +++++ .../material/components/progress/progress.md | 6 +++++ 4 files changed, 65 insertions(+) create mode 100644 docs/data/material/components/progress/CircularCustomScale.js create mode 100644 docs/data/material/components/progress/CircularCustomScale.tsx create mode 100644 docs/data/material/components/progress/CircularCustomScale.tsx.preview diff --git a/docs/data/material/components/progress/CircularCustomScale.js b/docs/data/material/components/progress/CircularCustomScale.js new file mode 100644 index 00000000000000..53acf5b1a2ebfa --- /dev/null +++ b/docs/data/material/components/progress/CircularCustomScale.js @@ -0,0 +1,26 @@ +import * as React from 'react'; +import CircularProgress from '@mui/material/CircularProgress'; + +export default function CircularCustomScale() { + const [progress, setProgress] = React.useState(0); + + React.useEffect(() => { + const timer = setInterval(() => { + setProgress((prevProgress) => (prevProgress >= 20 ? 0 : prevProgress + 2)); + }, 800); + + return () => { + clearInterval(timer); + }; + }, []); + + return ( + + ); +} diff --git a/docs/data/material/components/progress/CircularCustomScale.tsx b/docs/data/material/components/progress/CircularCustomScale.tsx new file mode 100644 index 00000000000000..53acf5b1a2ebfa --- /dev/null +++ b/docs/data/material/components/progress/CircularCustomScale.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import CircularProgress from '@mui/material/CircularProgress'; + +export default function CircularCustomScale() { + const [progress, setProgress] = React.useState(0); + + React.useEffect(() => { + const timer = setInterval(() => { + setProgress((prevProgress) => (prevProgress >= 20 ? 0 : prevProgress + 2)); + }, 800); + + return () => { + clearInterval(timer); + }; + }, []); + + return ( + + ); +} diff --git a/docs/data/material/components/progress/CircularCustomScale.tsx.preview b/docs/data/material/components/progress/CircularCustomScale.tsx.preview new file mode 100644 index 00000000000000..14ff546f541ac9 --- /dev/null +++ b/docs/data/material/components/progress/CircularCustomScale.tsx.preview @@ -0,0 +1,7 @@ + diff --git a/docs/data/material/components/progress/progress.md b/docs/data/material/components/progress/progress.md index 591c81f76192d8..82cc874c938b6a 100644 --- a/docs/data/material/components/progress/progress.md +++ b/docs/data/material/components/progress/progress.md @@ -38,6 +38,12 @@ The animations of the components rely on CSS as much as possible to work even be {{"demo": "CircularDeterminate.js"}} +### Circular custom scale + +You can change the default 0 -> 100 scale by using the `minValue` and `maxValue` props. + +{{"demo": "CircularCustomScale.js"}} + ### Circular track {{"demo": "CircularEnableTrack.js"}} From dfa71f5b2aaba8a67978ecbc385f4f821fca69d4 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 10:59:00 +0300 Subject: [PATCH 10/46] pnpm docs:typescript:formatted --- .../components/progress/CircularCustomScale.tsx.preview | 2 +- .../data/material/components/progress/CircularWithValueLabel.js | 2 +- docs/data/material/components/progress/LinearQuery.tsx.preview | 1 + .../components/progress/LinearWithAriaValueText.tsx.preview | 1 + .../components/progress/LinearWithValueLabel.tsx.preview | 2 +- 5 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 docs/data/material/components/progress/LinearQuery.tsx.preview create mode 100644 docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview diff --git a/docs/data/material/components/progress/CircularCustomScale.tsx.preview b/docs/data/material/components/progress/CircularCustomScale.tsx.preview index 14ff546f541ac9..6ef492eb865db5 100644 --- a/docs/data/material/components/progress/CircularCustomScale.tsx.preview +++ b/docs/data/material/components/progress/CircularCustomScale.tsx.preview @@ -4,4 +4,4 @@ maxValue={20} value={progress} aria-label="Loading" -/> +/> \ No newline at end of file diff --git a/docs/data/material/components/progress/CircularWithValueLabel.js b/docs/data/material/components/progress/CircularWithValueLabel.js index a5e42a9386ede1..bbd7e6783918e6 100644 --- a/docs/data/material/components/progress/CircularWithValueLabel.js +++ b/docs/data/material/components/progress/CircularWithValueLabel.js @@ -39,7 +39,7 @@ function CircularProgressWithLabel(props) { CircularProgressWithLabel.propTypes = { /** * The value of the progress indicator for the determinate variant. - * Value between 0 and 100. + * Value between `minValue` and `maxValue`. * @default 0 */ value: PropTypes.number.isRequired, diff --git a/docs/data/material/components/progress/LinearQuery.tsx.preview b/docs/data/material/components/progress/LinearQuery.tsx.preview new file mode 100644 index 00000000000000..b14a4d9082d17d --- /dev/null +++ b/docs/data/material/components/progress/LinearQuery.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview b/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview new file mode 100644 index 00000000000000..32be86105f538e --- /dev/null +++ b/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/material/components/progress/LinearWithValueLabel.tsx.preview b/docs/data/material/components/progress/LinearWithValueLabel.tsx.preview index 106f18a93820c2..62528e5a310292 100644 --- a/docs/data/material/components/progress/LinearWithValueLabel.tsx.preview +++ b/docs/data/material/components/progress/LinearWithValueLabel.tsx.preview @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 3bcc3ee1388500bef4b2d4cc594c2bc4fd175a8e Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 11:05:53 +0300 Subject: [PATCH 11/46] no need for proptypes in ts demo --- .../progress/LinearWithAriaValueText.tsx | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.tsx b/docs/data/material/components/progress/LinearWithAriaValueText.tsx index c21bfe5cb979bb..7af0ecdd66f161 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.tsx +++ b/docs/data/material/components/progress/LinearWithAriaValueText.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import PropTypes from 'prop-types'; import LinearProgress, { LinearProgressProps } from '@mui/material/LinearProgress'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; @@ -49,22 +48,6 @@ function LinearProgressWithLabelAndValue({ ); } -LinearProgressWithLabelAndValue.propTypes = { - /** - * The value of the progress indicator for the determinate and buffer variants. - * Value between 0 and 100. - */ - value: PropTypes.number.isRequired, - /** - * The minimum value of the progress indicator. - */ - minValue: PropTypes.number.isRequired, - /** - * The maximum value of the progress indicator. - */ - maxValue: PropTypes.number.isRequired, -}; - export default function LinearWithAriaValueText() { const [progress, setProgress] = React.useState(0); From 45067ede7800e2679f4679d2ea011f0af62c409d Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 12:15:10 +0300 Subject: [PATCH 12/46] align examples --- .../progress/LinearWithAriaValueText.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.js b/docs/data/material/components/progress/LinearWithAriaValueText.js index 925263a6cdc044..298caabe7fee08 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.js +++ b/docs/data/material/components/progress/LinearWithAriaValueText.js @@ -4,7 +4,7 @@ import LinearProgress from '@mui/material/LinearProgress'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; -function LinearProgressWithLabelAndValue({ maxValue, minValue, value }) { +function LinearProgressWithLabelAndValue({ maxValue, minValue, value, ...rest }) { const progressText = `${value} out of ${maxValue} files`; return (
@@ -25,6 +25,7 @@ function LinearProgressWithLabelAndValue({ maxValue, minValue, value }) { minValue={minValue} maxValue={maxValue} value={value} + {...rest} /> @@ -40,17 +41,19 @@ function LinearProgressWithLabelAndValue({ maxValue, minValue, value }) { LinearProgressWithLabelAndValue.propTypes = { /** * The value of the progress indicator for the determinate and buffer variants. - * Value between 0 and 100. + * @default 100 */ - value: PropTypes.number.isRequired, + maxValue: PropTypes.number.isRequired, /** - * The minimum value of the progress indicator. + * The minimum value of progress in determinate and buffer variants. + * @default 0 */ minValue: PropTypes.number.isRequired, /** - * The maximum value of the progress indicator. + * The value of the progress indicator for the determinate and buffer variants. + * Value between 0 and 100. */ - maxValue: PropTypes.number.isRequired, + value: PropTypes.number.isRequired, }; export default function LinearWithAriaValueText() { From 02a318a1bb2f01f0eec986bf37ab2589d45f1722 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 12:31:45 +0300 Subject: [PATCH 13/46] update docs --- .../material-ui/api/linear-progress.json | 2 +- .../circular-progress/circular-progress.json | 4 +-- .../linear-progress/linear-progress.json | 10 ++++--- .../CircularProgress/CircularProgress.d.ts | 4 +-- .../src/CircularProgress/CircularProgress.js | 29 +++++++------------ .../src/LinearProgress/LinearProgress.d.ts | 9 +++--- .../src/LinearProgress/LinearProgress.js | 9 +++--- 7 files changed, 32 insertions(+), 35 deletions(-) diff --git a/docs/pages/material-ui/api/linear-progress.json b/docs/pages/material-ui/api/linear-progress.json index d6204754fbbb94..68c8b1f8c40485 100644 --- a/docs/pages/material-ui/api/linear-progress.json +++ b/docs/pages/material-ui/api/linear-progress.json @@ -17,7 +17,7 @@ }, "additionalInfo": { "sx": true } }, - "value": { "type": { "name": "number" } }, + "value": { "type": { "name": "number" }, "default": "0" }, "valueBuffer": { "type": { "name": "number" } }, "variant": { "type": { diff --git a/docs/translations/api-docs/circular-progress/circular-progress.json b/docs/translations/api-docs/circular-progress/circular-progress.json index 71cc43c08f53d7..ef81b96c5f1421 100644 --- a/docs/translations/api-docs/circular-progress/circular-progress.json +++ b/docs/translations/api-docs/circular-progress/circular-progress.json @@ -12,10 +12,10 @@ "description": "If true, a track circle slot is mounted to show a subtle background for the progress. The size and thickness apply to the track slot to be consistent with the progress circle." }, "maxValue": { - "description": "The value of the progress indicator for the determinate and buffer variants." + "description": "The maximum value for the progress indicator for the determinate variant." }, "minValue": { - "description": "The minimum value of progress in determinate and buffer variants." + "description": "The minimum value for the progress indicator for the determinate variant." }, "size": { "description": "The size of the component. If using a number, the pixel unit is assumed. If using a string, you need to provide the CSS unit, for example '3rem'." diff --git a/docs/translations/api-docs/linear-progress/linear-progress.json b/docs/translations/api-docs/linear-progress/linear-progress.json index 0d42cc6fb834db..8224518281c7a3 100644 --- a/docs/translations/api-docs/linear-progress/linear-progress.json +++ b/docs/translations/api-docs/linear-progress/linear-progress.json @@ -6,18 +6,20 @@ "description": "The color of the component. It supports both default and custom theme colors, which can be added as shown in the palette customization guide." }, "maxValue": { - "description": "The value of the progress indicator for the determinate and buffer variants." + "description": "The maximum value for the progress indicator for the determinate and buffer variants." }, "minValue": { - "description": "The minimum value of progress in determinate and buffer variants." + "description": "The minimum value for the progress indicator for the determinate and buffer variants." }, "sx": { "description": "The system prop that allows defining system overrides as well as additional CSS styles." }, "value": { - "description": "The value of the progress indicator for the determinate and buffer variants. Value between 0 and 100." + "description": "The value of the progress indicator for the determinate and buffer variants. Value between minValue and maxValue." + }, + "valueBuffer": { + "description": "The value for the buffer variant. Value between minValue and maxValue." }, - "valueBuffer": { "description": "The value for the buffer variant. Value between 0 and 100." }, "variant": { "description": "The variant to use. Use indeterminate or query when there is no progress value." } diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts index ed7593da4c9810..d839f82d44e570 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts +++ b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts @@ -41,12 +41,12 @@ export interface CircularProgressProps extends StandardProps< */ enableTrackSlot?: boolean | undefined; /** - * The value of the progress indicator for the determinate and buffer variants. + * The maximum value for the progress indicator for the determinate variant. * @default 100 */ maxValue?: number | undefined; /** - * The minimum value of progress in determinate and buffer variants. + * The minimum value for the progress indicator for the determinate variant. * @default 0 */ minValue?: number | undefined; diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index ffec8e8de4ead7..11c0ad2e93599b 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -215,26 +215,19 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref const rootProps = {}; if (variant === 'determinate') { - if (value !== undefined) { - const circumference = 2 * Math.PI * ((SIZE - thickness) / 2); + const circumference = 2 * Math.PI * ((SIZE - thickness) / 2); - circleStyle.strokeDasharray = circumference.toFixed(3); - circleStyle.strokeDashoffset = `${(((maxValue - value) / (maxValue - minValue)) * circumference).toFixed(3)}px`; - rootStyle.transform = 'rotate(-90deg)'; + circleStyle.strokeDasharray = circumference.toFixed(3); + circleStyle.strokeDashoffset = `${(((maxValue - value) / (maxValue - minValue)) * circumference).toFixed(3)}px`; + rootStyle.transform = 'rotate(-90deg)'; - rootProps['aria-valuenow'] = Math.round(value); - rootProps['aria-valuemin'] = minValue; - rootProps['aria-valuemax'] = maxValue; + rootProps['aria-valuenow'] = Math.round(value); + rootProps['aria-valuemin'] = minValue; + rootProps['aria-valuemax'] = maxValue; - if (value < minValue || value > maxValue) { - console.error( - `MUI: The value provided to the CircularProgress component is out of range (value: ${value}, min: ${minValue}, max: ${maxValue}).`, - ); - } - } else if (process.env.NODE_ENV !== 'production') { + if ((value < minValue || value > maxValue) && process.env.NODE_ENV !== 'production') { console.error( - 'MUI: You need to provide a value prop ' + - 'when using the determinate variant of CircularProgress.', + `MUI: The value provided to the CircularProgress component is out of range (value: ${value}, min: ${minValue}, max: ${maxValue}).`, ); } } @@ -326,12 +319,12 @@ CircularProgress.propTypes /* remove-proptypes */ = { */ enableTrackSlot: PropTypes.bool, /** - * The value of the progress indicator for the determinate and buffer variants. + * The maximum value for the progress indicator for the determinate variant. * @default 100 */ maxValue: PropTypes.number, /** - * The minimum value of progress in determinate and buffer variants. + * The minimum value for the progress indicator for the determinate variant. * @default 0 */ minValue: PropTypes.number, diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.d.ts b/packages/mui-material/src/LinearProgress/LinearProgress.d.ts index ef6656399afa5f..20c2618b925a0b 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.d.ts +++ b/packages/mui-material/src/LinearProgress/LinearProgress.d.ts @@ -29,12 +29,12 @@ export interface LinearProgressProps extends StandardProps< > | undefined; /** - * The value of the progress indicator for the determinate and buffer variants. + * The maximum value for the progress indicator for the determinate and buffer variants. * @default 100 */ maxValue?: number | undefined; /** - * The minimum value of progress in determinate and buffer variants. + * The minimum value for the progress indicator for the determinate and buffer variants. * @default 0 */ minValue?: number | undefined; @@ -44,12 +44,13 @@ export interface LinearProgressProps extends StandardProps< sx?: SxProps | undefined; /** * The value of the progress indicator for the determinate and buffer variants. - * Value between 0 and 100. + * Value between `minValue` and `maxValue`. + * @default 0 */ value?: number | undefined; /** * The value for the buffer variant. - * Value between 0 and 100. + * Value between `minValue` and `maxValue`. */ valueBuffer?: number | undefined; /** diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.js b/packages/mui-material/src/LinearProgress/LinearProgress.js index 36b533f15e06b8..87b1f8fec0506f 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.js @@ -473,12 +473,12 @@ LinearProgress.propTypes /* remove-proptypes */ = { PropTypes.string, ]), /** - * The value of the progress indicator for the determinate and buffer variants. + * The maximum value for the progress indicator for the determinate and buffer variants. * @default 100 */ maxValue: PropTypes.number, /** - * The minimum value of progress in determinate and buffer variants. + * The minimum value for the progress indicator for the determinate and buffer variants. * @default 0 */ minValue: PropTypes.number, @@ -492,12 +492,13 @@ LinearProgress.propTypes /* remove-proptypes */ = { ]), /** * The value of the progress indicator for the determinate and buffer variants. - * Value between 0 and 100. + * Value between `minValue` and `maxValue`. + * @default 0 */ value: PropTypes.number, /** * The value for the buffer variant. - * Value between 0 and 100. + * Value between `minValue` and `maxValue`. */ valueBuffer: PropTypes.number, /** From 19d21ff564812b35b74ea4b0389395bbe6ac55ef Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 12:49:34 +0300 Subject: [PATCH 14/46] improve description --- docs/data/material/components/progress/progress.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/material/components/progress/progress.md b/docs/data/material/components/progress/progress.md index 82cc874c938b6a..8813641bf2d076 100644 --- a/docs/data/material/components/progress/progress.md +++ b/docs/data/material/components/progress/progress.md @@ -40,7 +40,7 @@ The animations of the components rely on CSS as much as possible to work even be ### Circular custom scale -You can change the default 0 -> 100 scale by using the `minValue` and `maxValue` props. +By default, progress values are expected in the 0–100 range. You can customize this range by using the `minValue` and `maxValue` props. {{"demo": "CircularCustomScale.js"}} From 935f82749bdb206d8171ab39a38e257130c783b5 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 12:50:10 +0300 Subject: [PATCH 15/46] correct grammar --- docs/data/material/components/progress/progress.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/material/components/progress/progress.md b/docs/data/material/components/progress/progress.md index 8813641bf2d076..6c399867cbefac 100644 --- a/docs/data/material/components/progress/progress.md +++ b/docs/data/material/components/progress/progress.md @@ -84,7 +84,7 @@ By default, progress values are expected in the 0–100 range. You can customize ### Linear with custom value text -By default, the progress value is read by assistive technology as percentages. Use `aria-valuetext` when you the progress value does not involve percentages. +By default, the progress value is read by assistive technology as percentages. Use `aria-valuetext` when the progress value does not involve percentages. {{"demo": "LinearWithAriaValueText.js"}} From 3fb4f2fe895df5b7dfd3d52047013a635696a4a7 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Thu, 2 Apr 2026 13:55:19 +0300 Subject: [PATCH 16/46] docs typecript formatted --- .../components/progress/LinearWithAriaValueText.js | 7 ++++--- .../material/components/progress/LinearWithValueLabel.js | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.js b/docs/data/material/components/progress/LinearWithAriaValueText.js index 298caabe7fee08..573e9684d5f127 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.js +++ b/docs/data/material/components/progress/LinearWithAriaValueText.js @@ -40,18 +40,19 @@ function LinearProgressWithLabelAndValue({ maxValue, minValue, value, ...rest }) LinearProgressWithLabelAndValue.propTypes = { /** - * The value of the progress indicator for the determinate and buffer variants. + * The maximum value for the progress indicator for the determinate and buffer variants. * @default 100 */ maxValue: PropTypes.number.isRequired, /** - * The minimum value of progress in determinate and buffer variants. + * The minimum value for the progress indicator for the determinate and buffer variants. * @default 0 */ minValue: PropTypes.number.isRequired, /** * The value of the progress indicator for the determinate and buffer variants. - * Value between 0 and 100. + * Value between `minValue` and `maxValue`. + * @default 0 */ value: PropTypes.number.isRequired, }; diff --git a/docs/data/material/components/progress/LinearWithValueLabel.js b/docs/data/material/components/progress/LinearWithValueLabel.js index e0f276bba2baa2..ce63b778d2a409 100644 --- a/docs/data/material/components/progress/LinearWithValueLabel.js +++ b/docs/data/material/components/progress/LinearWithValueLabel.js @@ -36,7 +36,8 @@ function LinearProgressWithLabelAndValue(props) { LinearProgressWithLabelAndValue.propTypes = { /** * The value of the progress indicator for the determinate and buffer variants. - * Value between 0 and 100. + * Value between `minValue` and `maxValue`. + * @default 0 */ value: PropTypes.number.isRequired, }; From 2aef00882e00d72046ac63454ebabcec43d9b5fa Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Mon, 6 Apr 2026 10:48:25 +0300 Subject: [PATCH 17/46] code review integration --- .../material/components/progress/progress.md | 29 --------- .../material-ui/api/circular-progress.json | 4 +- .../material-ui/api/linear-progress.json | 4 +- .../circular-progress/circular-progress.json | 6 +- .../linear-progress/linear-progress.json | 8 +-- .../CircularProgress/CircularProgress.d.ts | 6 +- .../src/CircularProgress/CircularProgress.js | 26 ++++---- .../CircularProgress/CircularProgress.test.js | 35 +++++++---- .../src/LinearProgress/LinearProgress.d.ts | 9 ++- .../src/LinearProgress/LinearProgress.js | 49 ++++++++------- .../src/LinearProgress/LinearProgress.test.js | 63 +++++++++++-------- 11 files changed, 117 insertions(+), 122 deletions(-) diff --git a/docs/data/material/components/progress/progress.md b/docs/data/material/components/progress/progress.md index 6c399867cbefac..3a10cb0c2fd045 100644 --- a/docs/data/material/components/progress/progress.md +++ b/docs/data/material/components/progress/progress.md @@ -88,35 +88,6 @@ By default, the progress value is read by assistive technology as percentages. U {{"demo": "LinearWithAriaValueText.js"}} -## Non-standard ranges - -The progress components accept a value in the range 0 - 100. This simplifies things for screen-reader users, where these are the default min / max values. Sometimes, however, you might be working with a data source where the values fall outside this range. Here's how you can easily transform a value in any range to a scale of 0 - 100: - -```jsx -// MIN = Minimum expected value -// MAX = Maximum expected value -// Function to normalise the values (MIN / MAX could be integrated) -const normalise = (value) => ((value - MIN) * 100) / (MAX - MIN); - -// Example component that utilizes the `normalise` function at the point of render. -function Progress(props) { - return ( - - - - - ); -} -``` - ## Customization Here are some examples of customizing the component. diff --git a/docs/pages/material-ui/api/circular-progress.json b/docs/pages/material-ui/api/circular-progress.json index 822147e5397177..fc7517c646aa5e 100644 --- a/docs/pages/material-ui/api/circular-progress.json +++ b/docs/pages/material-ui/api/circular-progress.json @@ -10,8 +10,8 @@ }, "disableShrink": { "type": { "name": "custom", "description": "bool" }, "default": "false" }, "enableTrackSlot": { "type": { "name": "bool" }, "default": "false" }, - "maxValue": { "type": { "name": "number" }, "default": "100" }, - "minValue": { "type": { "name": "number" }, "default": "0" }, + "max": { "type": { "name": "number" }, "default": "100" }, + "min": { "type": { "name": "number" }, "default": "0" }, "size": { "type": { "name": "union", "description": "number
| string" }, "default": "40" diff --git a/docs/pages/material-ui/api/linear-progress.json b/docs/pages/material-ui/api/linear-progress.json index 68c8b1f8c40485..c3b7b9e35b6659 100644 --- a/docs/pages/material-ui/api/linear-progress.json +++ b/docs/pages/material-ui/api/linear-progress.json @@ -8,8 +8,8 @@ }, "default": "'primary'" }, - "maxValue": { "type": { "name": "number" }, "default": "100" }, - "minValue": { "type": { "name": "number" }, "default": "0" }, + "max": { "type": { "name": "number" }, "default": "100" }, + "min": { "type": { "name": "number" }, "default": "0" }, "sx": { "type": { "name": "union", diff --git a/docs/translations/api-docs/circular-progress/circular-progress.json b/docs/translations/api-docs/circular-progress/circular-progress.json index ef81b96c5f1421..57dbd12f9bc486 100644 --- a/docs/translations/api-docs/circular-progress/circular-progress.json +++ b/docs/translations/api-docs/circular-progress/circular-progress.json @@ -11,10 +11,10 @@ "enableTrackSlot": { "description": "If true, a track circle slot is mounted to show a subtle background for the progress. The size and thickness apply to the track slot to be consistent with the progress circle." }, - "maxValue": { + "max": { "description": "The maximum value for the progress indicator for the determinate variant." }, - "minValue": { + "min": { "description": "The minimum value for the progress indicator for the determinate variant." }, "size": { @@ -25,7 +25,7 @@ }, "thickness": { "description": "The thickness of the circle." }, "value": { - "description": "The value of the progress indicator for the determinate variant. Value between minValue and maxValue." + "description": "The value of the progress indicator for the determinate variant. Value between min and max." }, "variant": { "description": "The variant to use. Use indeterminate when there is no progress value." diff --git a/docs/translations/api-docs/linear-progress/linear-progress.json b/docs/translations/api-docs/linear-progress/linear-progress.json index 8224518281c7a3..2e778c18335e1d 100644 --- a/docs/translations/api-docs/linear-progress/linear-progress.json +++ b/docs/translations/api-docs/linear-progress/linear-progress.json @@ -5,20 +5,20 @@ "color": { "description": "The color of the component. It supports both default and custom theme colors, which can be added as shown in the palette customization guide." }, - "maxValue": { + "max": { "description": "The maximum value for the progress indicator for the determinate and buffer variants." }, - "minValue": { + "min": { "description": "The minimum value for the progress indicator for the determinate and buffer variants." }, "sx": { "description": "The system prop that allows defining system overrides as well as additional CSS styles." }, "value": { - "description": "The value of the progress indicator for the determinate and buffer variants. Value between minValue and maxValue." + "description": "The value of the progress indicator for the determinate and buffer variants. Value between min and max." }, "valueBuffer": { - "description": "The value for the buffer variant. Value between minValue and maxValue." + "description": "The value for the buffer variant. Value between min and max." }, "variant": { "description": "The variant to use. Use indeterminate or query when there is no progress value." diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts index d839f82d44e570..5b0bd16bb2f0db 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts +++ b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts @@ -44,12 +44,12 @@ export interface CircularProgressProps extends StandardProps< * The maximum value for the progress indicator for the determinate variant. * @default 100 */ - maxValue?: number | undefined; + max?: number | undefined; /** * The minimum value for the progress indicator for the determinate variant. * @default 0 */ - minValue?: number | undefined; + min?: number | undefined; /** * The size of the component. * If using a number, the pixel unit is assumed. @@ -68,7 +68,7 @@ export interface CircularProgressProps extends StandardProps< thickness?: number | undefined; /** * The value of the progress indicator for the determinate variant. - * Value between `minValue` and `maxValue`. + * Value between `min` and `max`. * @default 0 */ value?: number | undefined; diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index 11c0ad2e93599b..c90e8235de84a3 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -187,8 +187,8 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref color = 'primary', disableShrink = false, enableTrackSlot = false, - minValue = 0, - maxValue = 100, + min = 0, + max = 100, size = 40, style, thickness = 3.6, @@ -218,17 +218,19 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref const circumference = 2 * Math.PI * ((SIZE - thickness) / 2); circleStyle.strokeDasharray = circumference.toFixed(3); - circleStyle.strokeDashoffset = `${(((maxValue - value) / (maxValue - minValue)) * circumference).toFixed(3)}px`; + circleStyle.strokeDashoffset = `${(((max - value) / (max - min)) * circumference).toFixed(3)}px`; rootStyle.transform = 'rotate(-90deg)'; rootProps['aria-valuenow'] = Math.round(value); - rootProps['aria-valuemin'] = minValue; - rootProps['aria-valuemax'] = maxValue; + rootProps['aria-valuemin'] = min; + rootProps['aria-valuemax'] = max; - if ((value < minValue || value > maxValue) && process.env.NODE_ENV !== 'production') { - console.error( - `MUI: The value provided to the CircularProgress component is out of range (value: ${value}, min: ${minValue}, max: ${maxValue}).`, - ); + if (process.env.NODE_ENV !== 'production') { + if (value < min || value > max || min >= max) { + console.error( + `MUI: The min, max, and value props in CircularProgress should be numbers where min < max and min <= value <= max. Received min=${min}, max=${max}, value=${value}.`, + ); + } } } @@ -322,12 +324,12 @@ CircularProgress.propTypes /* remove-proptypes */ = { * The maximum value for the progress indicator for the determinate variant. * @default 100 */ - maxValue: PropTypes.number, + max: PropTypes.number, /** * The minimum value for the progress indicator for the determinate variant. * @default 0 */ - minValue: PropTypes.number, + min: PropTypes.number, /** * The size of the component. * If using a number, the pixel unit is assumed. @@ -354,7 +356,7 @@ CircularProgress.propTypes /* remove-proptypes */ = { thickness: PropTypes.number, /** * The value of the progress indicator for the determinate variant. - * Value between `minValue` and `maxValue`. + * Value between `min` and `max`. * @default 0 */ value: PropTypes.number, diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index 9c46278afe8b19..e8c825cea2dfec 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -175,9 +175,9 @@ describe('', () => { }); }); - describe('prop: minValue & maxValue', () => { + describe('prop: min & max', () => { it('should be able to use custom min and max values', () => { - render(); + render(); const progressbar = screen.getByRole('progressbar'); expect(progressbar).to.have.attribute('aria-valuenow', '5'); @@ -186,27 +186,40 @@ describe('', () => { }); it('min and max values should be used to calculate the circumference of the circle', () => { - render(); + render(); const progressbar = screen.getByRole('progressbar'); expect(progressbar).to.have.nested.property('style.transform', 'rotate(-90deg)'); }); - it('should warn if the value is out of range', () => { + it('should error if min, max, and value props are invalid', () => { expect(() => { - render(); + render(); }).toErrorDev([ - `MUI: The value provided to the CircularProgress component is out of range (value: -1, min: 0, max: 10).`, + 'MUI: The min, max, and value props in CircularProgress should be numbers where min < max and min <= value <= max. Received min=10, max=0, value=5.', !strictModeDoubleLoggingSuppressed && - `MUI: The value provided to the CircularProgress component is out of range (value: -1, min: 0, max: 10).`, + 'MUI: The min, max, and value props in CircularProgress should be numbers where min < max and min <= value <= max. Received min=10, max=0, value=5.', + ]); + expect(() => { + render(); + }).toErrorDev([ + 'MUI: The min, max, and value props in CircularProgress should be numbers where min < max and min <= value <= max. Received min=10, max=10, value=15.', + !strictModeDoubleLoggingSuppressed && + 'MUI: The min, max, and value props in CircularProgress should be numbers where min < max and min <= value <= max. Received min=10, max=10, value=15.', + ]); + expect(() => { + render(); + }).toErrorDev([ + 'MUI: The min, max, and value props in CircularProgress should be numbers where min < max and min <= value <= max. Received min=10, max=20, value=5.', + !strictModeDoubleLoggingSuppressed && + 'MUI: The min, max, and value props in CircularProgress should be numbers where min < max and min <= value <= max. Received min=10, max=20, value=5.', ]); - expect(() => { - render(); + render(); }).toErrorDev([ - `MUI: The value provided to the CircularProgress component is out of range (value: 11, min: 0, max: 10).`, + 'MUI: The min, max, and value props in CircularProgress should be numbers where min < max and min <= value <= max. Received min=10, max=20, value=25.', !strictModeDoubleLoggingSuppressed && - `MUI: The value provided to the CircularProgress component is out of range (value: 11, min: 0, max: 10).`, + 'MUI: The min, max, and value props in CircularProgress should be numbers where min < max and min <= value <= max. Received min=10, max=20, value=25.', ]); }); }); diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.d.ts b/packages/mui-material/src/LinearProgress/LinearProgress.d.ts index 20c2618b925a0b..8592d522225b98 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.d.ts +++ b/packages/mui-material/src/LinearProgress/LinearProgress.d.ts @@ -32,25 +32,24 @@ export interface LinearProgressProps extends StandardProps< * The maximum value for the progress indicator for the determinate and buffer variants. * @default 100 */ - maxValue?: number | undefined; + max?: number | undefined; /** * The minimum value for the progress indicator for the determinate and buffer variants. * @default 0 */ - minValue?: number | undefined; + min?: number | undefined; /** * The system prop that allows defining system overrides as well as additional CSS styles. */ sx?: SxProps | undefined; /** * The value of the progress indicator for the determinate and buffer variants. - * Value between `minValue` and `maxValue`. - * @default 0 + * Value between `min` and `max`. */ value?: number | undefined; /** * The value for the buffer variant. - * Value between `minValue` and `maxValue`. + * Value between `min` and `max`. */ valueBuffer?: number | undefined; /** diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.js b/packages/mui-material/src/LinearProgress/LinearProgress.js index 87b1f8fec0506f..e8f1c998297203 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.js @@ -357,8 +357,8 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { const { className, color = 'primary', - maxValue = 100, - minValue = 0, + max = 100, + min = 0, value, valueBuffer, variant = 'indeterminate', @@ -378,19 +378,21 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { if (variant === 'determinate' || variant === 'buffer') { if (value !== undefined) { + if (process.env.NODE_ENV !== 'production') { + if (value < min || value > max || min >= max) { + console.error( + `MUI: The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=${min}, max=${max}, value=${value}.`, + ); + } + } rootProps['aria-valuenow'] = Math.round(value); - rootProps['aria-valuemin'] = minValue; - rootProps['aria-valuemax'] = maxValue; - let transform = ((value - minValue) / (maxValue - minValue)) * 100 - 100; + rootProps['aria-valuemin'] = min; + rootProps['aria-valuemax'] = max; + let transform = ((value - min) / (max - min)) * 100 - 100; if (isRtl) { transform = -transform; } inlineStyles.bar1.transform = `translateX(${transform}%)`; - if ((value < minValue || value > maxValue) && process.env.NODE_ENV !== 'production') { - console.error( - `MUI: The value provided to the LinearProgress component is out of range (value: ${value}, min: ${minValue}, max: ${maxValue}).`, - ); - } } else if (process.env.NODE_ENV !== 'production') { console.error( 'MUI: You need to provide a value prop ' + @@ -400,19 +402,19 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { } if (variant === 'buffer') { if (valueBuffer !== undefined) { - let transform = ((valueBuffer - minValue) / (maxValue - minValue)) * 100 - 100; + if (process.env.NODE_ENV !== 'production') { + if (valueBuffer < min || valueBuffer > max || valueBuffer < value || min >= max) { + console.error( + `MUI: The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=${min}, max=${max}, value=${value}, valueBuffer=${valueBuffer}.`, + ); + } + } + + let transform = ((valueBuffer - min) / (max - min)) * 100 - 100; if (isRtl) { transform = -transform; } inlineStyles.bar2.transform = `translateX(${transform}%)`; - if ( - (valueBuffer < minValue || valueBuffer > maxValue || valueBuffer < value) && - process.env.NODE_ENV !== 'production' - ) { - console.error( - `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: ${valueBuffer}, value: ${value}, min: ${minValue}, max: ${maxValue}).`, - ); - } } else if (process.env.NODE_ENV !== 'production') { console.error( 'MUI: You need to provide a valueBuffer prop ' + @@ -476,12 +478,12 @@ LinearProgress.propTypes /* remove-proptypes */ = { * The maximum value for the progress indicator for the determinate and buffer variants. * @default 100 */ - maxValue: PropTypes.number, + max: PropTypes.number, /** * The minimum value for the progress indicator for the determinate and buffer variants. * @default 0 */ - minValue: PropTypes.number, + min: PropTypes.number, /** * The system prop that allows defining system overrides as well as additional CSS styles. */ @@ -492,13 +494,12 @@ LinearProgress.propTypes /* remove-proptypes */ = { ]), /** * The value of the progress indicator for the determinate and buffer variants. - * Value between `minValue` and `maxValue`. - * @default 0 + * Value between `min` and `max`. */ value: PropTypes.number, /** * The value for the buffer variant. - * Value between `minValue` and `maxValue`. + * Value between `min` and `max`. */ valueBuffer: PropTypes.number, /** diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.test.js b/packages/mui-material/src/LinearProgress/LinearProgress.test.js index 2d29192bcbe047..b102fcbb40b711 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.test.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.test.js @@ -183,9 +183,9 @@ describe('', () => { }); }); - describe('prop: minValue & maxValue', () => { + describe('prop: min & max', () => { it('should be able to use custom min and max values', () => { - render(); + render(); const progressbar = screen.getByRole('progressbar'); expect(progressbar).to.have.attribute('aria-valuenow', '5'); @@ -194,7 +194,7 @@ describe('', () => { }); it('min and max values should be used to calculate the width of the bar', () => { - render(); + render(); const progressbar = screen.getByRole('progressbar'); expect(progressbar.children[0]).to.have.nested.property( @@ -204,9 +204,7 @@ describe('', () => { }); it('min and max values should be used to calculate the width of the buffer bar', () => { - render( - , - ); + render(); const progressbar = screen.getByRole('progressbar'); expect(progressbar.querySelector(`.${classes.bar1}`)).to.have.nested.property( @@ -221,51 +219,62 @@ describe('', () => { it('should warn if the value is out of range', () => { expect(() => { - render(); + render(); }).toErrorDev([ - `MUI: The value provided to the LinearProgress component is out of range (value: -1, min: 0, max: 10).`, + 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=-1.', !strictModeDoubleLoggingSuppressed && - `MUI: The value provided to the LinearProgress component is out of range (value: -1, min: 0, max: 10).`, + 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=-1.', ]); expect(() => { - render(); + render(); }).toErrorDev([ - `MUI: The value provided to the LinearProgress component is out of range (value: 11, min: 0, max: 10).`, + 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=11.', !strictModeDoubleLoggingSuppressed && - `MUI: The value provided to the LinearProgress component is out of range (value: 11, min: 0, max: 10).`, + 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=11.', ]); }); it('should warn if the valueBuffer is out of range or less than the value prop', () => { expect(() => { - render( - , - ); + render(); }).toErrorDev([ - `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: 4, value: 5, min: 0, max: 10).`, + 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=4.', !strictModeDoubleLoggingSuppressed && - `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: 4, value: 5, min: 0, max: 10).`, + 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=4.', ]); expect(() => { - render( - , - ); + render(); }).toErrorDev([ - `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: 11, value: 5, min: 0, max: 10).`, + 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=11.', !strictModeDoubleLoggingSuppressed && - `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: 11, value: 5, min: 0, max: 10).`, + 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=11.', ]); expect(() => { - render( - , - ); + render(); + }).toErrorDev([ + 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=-1.', + !strictModeDoubleLoggingSuppressed && + 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=-1.', + ]); + }); + + it('should warn if min is equal or greater than max', () => { + expect(() => { + render(); + }).toErrorDev([ + 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=0, value=5.', + !strictModeDoubleLoggingSuppressed && + 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=0, value=5.', + ]); + expect(() => { + render(); }).toErrorDev([ - `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: -1, value: 5, min: 0, max: 10).`, + 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=10, value=5.', !strictModeDoubleLoggingSuppressed && - `MUI: The valueBuffer provided to the LinearProgress component is out of range or less than the value prop (valueBuffer: -1, value: 5, min: 0, max: 10).`, + 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=10, value=5.', ]); }); }); From c3f70d2a16c0037ad13fa83b6c20750303828be9 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Mon, 6 Apr 2026 10:54:48 +0300 Subject: [PATCH 18/46] docs changes --- .../progress/CircularCustomScale.js | 4 ++-- .../progress/CircularCustomScale.tsx | 4 ++-- .../progress/CircularCustomScale.tsx.preview | 4 ++-- .../progress/CircularWithValueLabel.js | 2 +- .../progress/LinearWithAriaValueText.js | 22 +++++++++---------- .../progress/LinearWithAriaValueText.tsx | 21 +++++++++--------- .../LinearWithAriaValueText.tsx.preview | 2 +- .../progress/LinearWithValueLabel.js | 8 +++---- .../progress/LinearWithValueLabel.tsx | 5 +++-- 9 files changed, 37 insertions(+), 35 deletions(-) diff --git a/docs/data/material/components/progress/CircularCustomScale.js b/docs/data/material/components/progress/CircularCustomScale.js index 53acf5b1a2ebfa..ed841f69828851 100644 --- a/docs/data/material/components/progress/CircularCustomScale.js +++ b/docs/data/material/components/progress/CircularCustomScale.js @@ -17,8 +17,8 @@ export default function CircularCustomScale() { return ( diff --git a/docs/data/material/components/progress/CircularCustomScale.tsx b/docs/data/material/components/progress/CircularCustomScale.tsx index 53acf5b1a2ebfa..ed841f69828851 100644 --- a/docs/data/material/components/progress/CircularCustomScale.tsx +++ b/docs/data/material/components/progress/CircularCustomScale.tsx @@ -17,8 +17,8 @@ export default function CircularCustomScale() { return ( diff --git a/docs/data/material/components/progress/CircularCustomScale.tsx.preview b/docs/data/material/components/progress/CircularCustomScale.tsx.preview index 6ef492eb865db5..6f161b0601bc87 100644 --- a/docs/data/material/components/progress/CircularCustomScale.tsx.preview +++ b/docs/data/material/components/progress/CircularCustomScale.tsx.preview @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/docs/data/material/components/progress/CircularWithValueLabel.js b/docs/data/material/components/progress/CircularWithValueLabel.js index bbd7e6783918e6..9a1d3aca6e6130 100644 --- a/docs/data/material/components/progress/CircularWithValueLabel.js +++ b/docs/data/material/components/progress/CircularWithValueLabel.js @@ -39,7 +39,7 @@ function CircularProgressWithLabel(props) { CircularProgressWithLabel.propTypes = { /** * The value of the progress indicator for the determinate variant. - * Value between `minValue` and `maxValue`. + * Value between `min` and `max`. * @default 0 */ value: PropTypes.number.isRequired, diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.js b/docs/data/material/components/progress/LinearWithAriaValueText.js index 573e9684d5f127..552b545672bc88 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.js +++ b/docs/data/material/components/progress/LinearWithAriaValueText.js @@ -4,12 +4,13 @@ import LinearProgress from '@mui/material/LinearProgress'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; -function LinearProgressWithLabelAndValue({ maxValue, minValue, value, ...rest }) { - const progressText = `${value} out of ${maxValue} files`; +function LinearProgressWithLabelAndValue({ max, min, value, ...rest }) { + const progressText = `${value} out of ${max} files`; + const progressId = React.useId(); return (
@@ -43,16 +44,15 @@ LinearProgressWithLabelAndValue.propTypes = { * The maximum value for the progress indicator for the determinate and buffer variants. * @default 100 */ - maxValue: PropTypes.number.isRequired, + max: PropTypes.number.isRequired, /** * The minimum value for the progress indicator for the determinate and buffer variants. * @default 0 */ - minValue: PropTypes.number.isRequired, + min: PropTypes.number.isRequired, /** * The value of the progress indicator for the determinate and buffer variants. - * Value between `minValue` and `maxValue`. - * @default 0 + * Value between `min` and `max`. */ value: PropTypes.number.isRequired, }; @@ -71,7 +71,7 @@ export default function LinearWithAriaValueText() { return ( - + ); } diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.tsx b/docs/data/material/components/progress/LinearWithAriaValueText.tsx index 7af0ecdd66f161..91809875a1f409 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.tsx +++ b/docs/data/material/components/progress/LinearWithAriaValueText.tsx @@ -4,22 +4,23 @@ import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; type LinearProgressWithLabelAndValueProps = LinearProgressProps & { - minValue: number; - maxValue: number; + min: number; + max: number; value: number; }; function LinearProgressWithLabelAndValue({ - maxValue, - minValue, + max, + min, value, ...rest }: LinearProgressWithLabelAndValueProps) { - const progressText = `${value} out of ${maxValue} files`; + const progressText = `${value} out of ${max} files`; + const progressId = React.useId(); return (
@@ -62,7 +63,7 @@ export default function LinearWithAriaValueText() { return ( - + ); } diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview b/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview index 32be86105f538e..f1d0da76e75ae7 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview +++ b/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/data/material/components/progress/LinearWithValueLabel.js b/docs/data/material/components/progress/LinearWithValueLabel.js index ce63b778d2a409..4bb45a6ad23769 100644 --- a/docs/data/material/components/progress/LinearWithValueLabel.js +++ b/docs/data/material/components/progress/LinearWithValueLabel.js @@ -5,10 +5,11 @@ import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; function LinearProgressWithLabelAndValue(props) { + const progressId = React.useId(); return (
@@ -36,8 +37,7 @@ function LinearProgressWithLabelAndValue(props) { LinearProgressWithLabelAndValue.propTypes = { /** * The value of the progress indicator for the determinate and buffer variants. - * Value between `minValue` and `maxValue`. - * @default 0 + * Value between `min` and `max`. */ value: PropTypes.number.isRequired, }; diff --git a/docs/data/material/components/progress/LinearWithValueLabel.tsx b/docs/data/material/components/progress/LinearWithValueLabel.tsx index a884d0316caa64..a35eafeeb34512 100644 --- a/docs/data/material/components/progress/LinearWithValueLabel.tsx +++ b/docs/data/material/components/progress/LinearWithValueLabel.tsx @@ -6,10 +6,11 @@ import Box from '@mui/material/Box'; function LinearProgressWithLabelAndValue( props: LinearProgressProps & { value: number }, ) { + const progressId = React.useId(); return (
From 2fe3dd837326839fbe8af944b11beddf3200dd2a Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Mon, 6 Apr 2026 10:57:25 +0300 Subject: [PATCH 19/46] remove default --- docs/pages/material-ui/api/linear-progress.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/material-ui/api/linear-progress.json b/docs/pages/material-ui/api/linear-progress.json index c3b7b9e35b6659..7d8e28f3c14f49 100644 --- a/docs/pages/material-ui/api/linear-progress.json +++ b/docs/pages/material-ui/api/linear-progress.json @@ -17,7 +17,7 @@ }, "additionalInfo": { "sx": true } }, - "value": { "type": { "name": "number" }, "default": "0" }, + "value": { "type": { "name": "number" } }, "valueBuffer": { "type": { "name": "number" } }, "variant": { "type": { From a7fc26e5cf08653ee72d220aca2bab978113b9ee Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Tue, 7 Apr 2026 11:48:21 +0300 Subject: [PATCH 20/46] fix prop names --- docs/data/material/components/progress/progress.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/material/components/progress/progress.md b/docs/data/material/components/progress/progress.md index 3a10cb0c2fd045..38f1f5c2545a15 100644 --- a/docs/data/material/components/progress/progress.md +++ b/docs/data/material/components/progress/progress.md @@ -40,7 +40,7 @@ The animations of the components rely on CSS as much as possible to work even be ### Circular custom scale -By default, progress values are expected in the 0–100 range. You can customize this range by using the `minValue` and `maxValue` props. +By default, progress values are expected in the 0–100 range. You can customize this range by using the `min` and `max` props. {{"demo": "CircularCustomScale.js"}} From d10942238958753b4c63a05782c3a8f72f74fdcf Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 8 Apr 2026 11:52:44 +0300 Subject: [PATCH 21/46] improve circularprogress test --- .../src/CircularProgress/CircularProgress.test.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index e8c825cea2dfec..8cb105e3be262f 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -186,10 +186,14 @@ describe('', () => { }); it('min and max values should be used to calculate the circumference of the circle', () => { - render(); + const { container } = render( + , + ); + const [circle] = container.querySelectorAll('svg circle'); const progressbar = screen.getByRole('progressbar'); expect(progressbar).to.have.nested.property('style.transform', 'rotate(-90deg)'); + expect(circle.style.strokeDashoffset).to.equal('95.190px'); }); it('should error if min, max, and value props are invalid', () => { From 89cde5e43f1148755be4a68182161f557b90ac0a Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 8 Apr 2026 14:59:42 +0300 Subject: [PATCH 22/46] guard against division by 0 --- .../src/CircularProgress/CircularProgress.js | 18 ++++++++------- .../CircularProgress/CircularProgress.test.js | 13 +++++++++++ .../src/LinearProgress/LinearProgress.js | 18 +++++++++------ .../src/LinearProgress/LinearProgress.test.js | 23 +++++++++++++++++++ 4 files changed, 57 insertions(+), 15 deletions(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index c90e8235de84a3..529379d3564ee1 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -217,14 +217,6 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref if (variant === 'determinate') { const circumference = 2 * Math.PI * ((SIZE - thickness) / 2); - circleStyle.strokeDasharray = circumference.toFixed(3); - circleStyle.strokeDashoffset = `${(((max - value) / (max - min)) * circumference).toFixed(3)}px`; - rootStyle.transform = 'rotate(-90deg)'; - - rootProps['aria-valuenow'] = Math.round(value); - rootProps['aria-valuemin'] = min; - rootProps['aria-valuemax'] = max; - if (process.env.NODE_ENV !== 'production') { if (value < min || value > max || min >= max) { console.error( @@ -232,6 +224,16 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref ); } } + + const range = max - min; + circleStyle.strokeDasharray = circumference.toFixed(3); + circleStyle.strokeDashoffset = + range > 0 ? `${(((max - value) / range) * circumference).toFixed(3)}px` : '0px'; + rootStyle.transform = 'rotate(-90deg)'; + + rootProps['aria-valuenow'] = Math.round(value); + rootProps['aria-valuemin'] = min; + rootProps['aria-valuemax'] = max; } return ( diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index 8cb105e3be262f..ce8daf515adfc2 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -193,9 +193,22 @@ describe('', () => { const progressbar = screen.getByRole('progressbar'); expect(progressbar).to.have.nested.property('style.transform', 'rotate(-90deg)'); + expect(circle.style.strokeDasharray).to.equal('126.920'); expect(circle.style.strokeDashoffset).to.equal('95.190px'); }); + it('should fallback to 0px strokeDashoffset if max is less than min', () => { + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + + const { container } = render( + , + ); + const [circle] = container.querySelectorAll('svg circle'); + expect(circle.style.strokeDashoffset).to.equal('0px'); + + errorSpy.mockRestore(); + }); + it('should error if min, max, and value props are invalid', () => { expect(() => { render(); diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.js b/packages/mui-material/src/LinearProgress/LinearProgress.js index e8f1c998297203..c69306b13f1cf5 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.js @@ -385,14 +385,17 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { ); } } - rootProps['aria-valuenow'] = Math.round(value); - rootProps['aria-valuemin'] = min; - rootProps['aria-valuemax'] = max; - let transform = ((value - min) / (max - min)) * 100 - 100; + + const range = max - min; + let transform = ((value - min) / range) * 100 - 100; if (isRtl) { transform = -transform; } - inlineStyles.bar1.transform = `translateX(${transform}%)`; + inlineStyles.bar1.transform = range > 0 ? `translateX(${transform}%)` : undefined; + + rootProps['aria-valuenow'] = Math.round(value); + rootProps['aria-valuemin'] = min; + rootProps['aria-valuemax'] = max; } else if (process.env.NODE_ENV !== 'production') { console.error( 'MUI: You need to provide a value prop ' + @@ -410,11 +413,12 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { } } - let transform = ((valueBuffer - min) / (max - min)) * 100 - 100; + const range = max - min; + let transform = ((valueBuffer - min) / range) * 100 - 100; if (isRtl) { transform = -transform; } - inlineStyles.bar2.transform = `translateX(${transform}%)`; + inlineStyles.bar2.transform = range > 0 ? `translateX(${transform}%)` : undefined; } else if (process.env.NODE_ENV !== 'production') { console.error( 'MUI: You need to provide a valueBuffer prop ' + diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.test.js b/packages/mui-material/src/LinearProgress/LinearProgress.test.js index b102fcbb40b711..8d7d35c8712435 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.test.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.test.js @@ -217,6 +217,29 @@ describe('', () => { ); }); + it('should not add transform style to the progress bar when min is equal or larger than max', () => { + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + + render(); + const progressbar = screen.getByRole('progressbar'); + + expect(progressbar.children[0].style.transform).to.equal(''); + + errorSpy.mockRestore(); + }); + + it('should not add transform style to the buffer bar when min is equal or larger than max', () => { + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + + render(); + const progressbar = screen.getByRole('progressbar'); + + expect(progressbar.children[1].style.transform).to.equal(''); + expect(progressbar.children[2].style.transform).to.equal(''); + + errorSpy.mockRestore(); + }); + it('should warn if the value is out of range', () => { expect(() => { render(); From 2c8acddbeb5eadbd2fff30bd68cf2d8bd4fd478d Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 8 Apr 2026 15:23:41 +0300 Subject: [PATCH 23/46] warn when providing min/max with incorrect variant --- .../src/CircularProgress/CircularProgress.js | 15 +++++++++++-- .../CircularProgress/CircularProgress.test.js | 10 +++++++++ .../src/LinearProgress/LinearProgress.js | 18 +++++++++++++-- .../src/LinearProgress/LinearProgress.test.js | 22 +++++++++++++++++-- 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index 529379d3564ee1..f4bbd86f292d71 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -187,8 +187,8 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref color = 'primary', disableShrink = false, enableTrackSlot = false, - min = 0, - max = 100, + min: minProp, + max: maxProp, size = 40, style, thickness = 3.6, @@ -197,6 +197,17 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref ...other } = props; + if (process.env.NODE_ENV !== 'production') { + if (variant === 'indeterminate' && (minProp !== undefined || maxProp !== undefined)) { + console.error( + `MUI: You have provided the \`min\` or \`max\` props with a 'indeterminate' variant. These props will have no effect.`, + ); + } + } + + const min = minProp ?? 0; + const max = maxProp ?? 100; + const ownerState = { ...props, color, diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index ce8daf515adfc2..5fd47a7cb7c2d6 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -239,5 +239,15 @@ describe('', () => { 'MUI: The min, max, and value props in CircularProgress should be numbers where min < max and min <= value <= max. Received min=10, max=20, value=25.', ]); }); + + it('should error if min and max props are provided with an indeterminate variant', () => { + expect(() => { + render(); + }).toErrorDev([ + "MUI: You have provided the `min` or `max` props with a 'indeterminate' variant. These props will have no effect.", + !strictModeDoubleLoggingSuppressed && + "MUI: You have provided the `min` or `max` props with a 'indeterminate' variant. These props will have no effect.", + ]); + }); }); }); diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.js b/packages/mui-material/src/LinearProgress/LinearProgress.js index c69306b13f1cf5..bac01e666f0387 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.js @@ -357,8 +357,8 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { const { className, color = 'primary', - max = 100, - min = 0, + max: maxProp, + min: minProp, value, valueBuffer, variant = 'indeterminate', @@ -370,6 +370,20 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { variant, }; + if (process.env.NODE_ENV !== 'production') { + if ( + ['indeterminate', 'query'].includes(variant) && + (minProp !== undefined || maxProp !== undefined) + ) { + console.error( + `MUI: You have provided the \`min\` or \`max\` props with a 'indeterminate' or 'query' variant. These props will have no effect.`, + ); + } + } + + const min = minProp ?? 0; + const max = maxProp ?? 100; + const classes = useUtilityClasses(ownerState); const isRtl = useRtl(); diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.test.js b/packages/mui-material/src/LinearProgress/LinearProgress.test.js index 8d7d35c8712435..0fb27078f1a55d 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.test.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.test.js @@ -258,7 +258,7 @@ describe('', () => { ]); }); - it('should warn if the valueBuffer is out of range or less than the value prop', () => { + it('should error if the valueBuffer is out of range or less than the value prop', () => { expect(() => { render(); }).toErrorDev([ @@ -284,7 +284,7 @@ describe('', () => { ]); }); - it('should warn if min is equal or greater than max', () => { + it('should error if min is equal or greater than max', () => { expect(() => { render(); }).toErrorDev([ @@ -300,5 +300,23 @@ describe('', () => { 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=10, value=5.', ]); }); + + it('should error if variant is indeterminate or query and min or max props are provided', () => { + expect(() => { + render(); + }).toErrorDev([ + 'MUI: You have provided the `min` or `max` props with a \'indeterminate\' or \'query\' variant. These props will have no effect.', + !strictModeDoubleLoggingSuppressed && + 'MUI: You have provided the `min` or `max` props with a \'indeterminate\' or \'query\' variant. These props will have no effect.', + ]); + + expect(() => { + render(); + }).toErrorDev([ + 'MUI: You have provided the `min` or `max` props with a \'indeterminate\' or \'query\' variant. These props will have no effect.', + !strictModeDoubleLoggingSuppressed && + 'MUI: You have provided the `min` or `max` props with a \'indeterminate\' or \'query\' variant. These props will have no effect.', + ]); + }); }); }); From a3d921aa2cfe199934de526968de7c7425dc0002 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 8 Apr 2026 15:34:16 +0300 Subject: [PATCH 24/46] improve demos --- docs/data/material/components/progress/CircularCustomScale.js | 2 +- docs/data/material/components/progress/CircularCustomScale.tsx | 2 +- .../material/components/progress/LinearWithAriaValueText.js | 2 +- .../material/components/progress/LinearWithAriaValueText.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/data/material/components/progress/CircularCustomScale.js b/docs/data/material/components/progress/CircularCustomScale.js index ed841f69828851..1ade3f8f777fef 100644 --- a/docs/data/material/components/progress/CircularCustomScale.js +++ b/docs/data/material/components/progress/CircularCustomScale.js @@ -17,7 +17,7 @@ export default function CircularCustomScale() { return ( - + ); } diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.tsx b/docs/data/material/components/progress/LinearWithAriaValueText.tsx index 91809875a1f409..b96a2e11c321c3 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.tsx +++ b/docs/data/material/components/progress/LinearWithAriaValueText.tsx @@ -63,7 +63,7 @@ export default function LinearWithAriaValueText() { return ( - + ); } From 3cbd1664fc7560044eb332558787df6d5c9f1d7e Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 8 Apr 2026 15:37:23 +0300 Subject: [PATCH 25/46] update values in docs --- docs/data/material/components/progress/CircularCustomScale.js | 2 +- .../data/material/components/progress/CircularCustomScale.tsx | 2 +- .../components/progress/CircularCustomScale.tsx.preview | 4 ++-- .../components/progress/LinearWithAriaValueText.tsx.preview | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/data/material/components/progress/CircularCustomScale.js b/docs/data/material/components/progress/CircularCustomScale.js index 1ade3f8f777fef..3c04368c0237d1 100644 --- a/docs/data/material/components/progress/CircularCustomScale.js +++ b/docs/data/material/components/progress/CircularCustomScale.js @@ -17,7 +17,7 @@ export default function CircularCustomScale() { return ( \ No newline at end of file +/> diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview b/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview index f1d0da76e75ae7..02094bc24e8c5a 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview +++ b/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview @@ -1 +1 @@ - \ No newline at end of file + From cc5a819b838770c8edf68c7810a14a9f1bc04af8 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 8 Apr 2026 15:45:50 +0300 Subject: [PATCH 26/46] provide better examples in docs --- .../components/progress/CircularCustomScale.js | 4 ++-- .../components/progress/CircularCustomScale.tsx | 4 ++-- .../components/progress/LinearWithAriaValueText.js | 10 +++++----- .../components/progress/LinearWithAriaValueText.tsx | 10 +++++----- .../progress/LinearWithAriaValueText.tsx.preview | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/data/material/components/progress/CircularCustomScale.js b/docs/data/material/components/progress/CircularCustomScale.js index 3c04368c0237d1..4c1634a3fb50de 100644 --- a/docs/data/material/components/progress/CircularCustomScale.js +++ b/docs/data/material/components/progress/CircularCustomScale.js @@ -2,11 +2,11 @@ import * as React from 'react'; import CircularProgress from '@mui/material/CircularProgress'; export default function CircularCustomScale() { - const [progress, setProgress] = React.useState(0); + const [progress, setProgress] = React.useState(10); React.useEffect(() => { const timer = setInterval(() => { - setProgress((prevProgress) => (prevProgress >= 20 ? 0 : prevProgress + 2)); + setProgress((prevProgress) => (prevProgress >= 20 ? 10 : prevProgress + 2)); }, 800); return () => { diff --git a/docs/data/material/components/progress/CircularCustomScale.tsx b/docs/data/material/components/progress/CircularCustomScale.tsx index 3c04368c0237d1..4c1634a3fb50de 100644 --- a/docs/data/material/components/progress/CircularCustomScale.tsx +++ b/docs/data/material/components/progress/CircularCustomScale.tsx @@ -2,11 +2,11 @@ import * as React from 'react'; import CircularProgress from '@mui/material/CircularProgress'; export default function CircularCustomScale() { - const [progress, setProgress] = React.useState(0); + const [progress, setProgress] = React.useState(10); React.useEffect(() => { const timer = setInterval(() => { - setProgress((prevProgress) => (prevProgress >= 20 ? 0 : prevProgress + 2)); + setProgress((prevProgress) => (prevProgress >= 20 ? 10 : prevProgress + 2)); }, 800); return () => { diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.js b/docs/data/material/components/progress/LinearWithAriaValueText.js index 472897c87bd720..3aa59fda652f93 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.js +++ b/docs/data/material/components/progress/LinearWithAriaValueText.js @@ -5,7 +5,7 @@ import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; function LinearProgressWithLabelAndValue({ max, min, value, ...rest }) { - const progressText = `${value} out of ${max} files`; + const progressText = `Elevator at floor ${value} out of ${max}.`; const progressId = React.useId(); return (
@@ -15,7 +15,7 @@ function LinearProgressWithLabelAndValue({ max, min, value, ...rest }) { color="text.secondary" sx={{ mr: 1 }} > - Uploading photos… + Elevator status @@ -58,11 +58,11 @@ LinearProgressWithLabelAndValue.propTypes = { }; export default function LinearWithAriaValueText() { - const [progress, setProgress] = React.useState(0); + const [progress, setProgress] = React.useState(1); React.useEffect(() => { const timer = setInterval(() => { - setProgress((prevProgress) => (prevProgress >= 10 ? 0 : prevProgress + 1)); + setProgress((prevProgress) => (prevProgress >= 10 ? 1 : prevProgress + 1)); }, 800); return () => { clearInterval(timer); @@ -71,7 +71,7 @@ export default function LinearWithAriaValueText() { return ( - + ); } diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.tsx b/docs/data/material/components/progress/LinearWithAriaValueText.tsx index b96a2e11c321c3..0ec123cad46176 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.tsx +++ b/docs/data/material/components/progress/LinearWithAriaValueText.tsx @@ -15,7 +15,7 @@ function LinearProgressWithLabelAndValue({ value, ...rest }: LinearProgressWithLabelAndValueProps) { - const progressText = `${value} out of ${max} files`; + const progressText = `Elevator at floor ${value} out of ${max}.`; const progressId = React.useId(); return (
@@ -25,7 +25,7 @@ function LinearProgressWithLabelAndValue({ color="text.secondary" sx={{ mr: 1 }} > - Uploading photos… + Elevator status @@ -50,11 +50,11 @@ function LinearProgressWithLabelAndValue({ } export default function LinearWithAriaValueText() { - const [progress, setProgress] = React.useState(0); + const [progress, setProgress] = React.useState(1); React.useEffect(() => { const timer = setInterval(() => { - setProgress((prevProgress) => (prevProgress >= 10 ? 0 : prevProgress + 1)); + setProgress((prevProgress) => (prevProgress >= 10 ? 1 : prevProgress + 1)); }, 800); return () => { clearInterval(timer); @@ -63,7 +63,7 @@ export default function LinearWithAriaValueText() { return ( - + ); } diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview b/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview index 02094bc24e8c5a..522e6969e88b15 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview +++ b/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview @@ -1 +1 @@ - + From 8135b481066b28ba3df8a9d6fb3ab07c2d4ac6f0 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 8 Apr 2026 15:56:04 +0300 Subject: [PATCH 27/46] prettier --- .../src/LinearProgress/LinearProgress.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.test.js b/packages/mui-material/src/LinearProgress/LinearProgress.test.js index 0fb27078f1a55d..f299431fc49255 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.test.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.test.js @@ -305,17 +305,17 @@ describe('', () => { expect(() => { render(); }).toErrorDev([ - 'MUI: You have provided the `min` or `max` props with a \'indeterminate\' or \'query\' variant. These props will have no effect.', + "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", !strictModeDoubleLoggingSuppressed && - 'MUI: You have provided the `min` or `max` props with a \'indeterminate\' or \'query\' variant. These props will have no effect.', + "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", ]); expect(() => { render(); }).toErrorDev([ - 'MUI: You have provided the `min` or `max` props with a \'indeterminate\' or \'query\' variant. These props will have no effect.', + "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", !strictModeDoubleLoggingSuppressed && - 'MUI: You have provided the `min` or `max` props with a \'indeterminate\' or \'query\' variant. These props will have no effect.', + "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", ]); }); }); From 78b6482129394759ee2866589e136d54abd00ba2 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 8 Apr 2026 15:57:02 +0300 Subject: [PATCH 28/46] docs:typescript:formatted --- .../components/progress/CircularCustomScale.tsx.preview | 2 +- .../components/progress/LinearWithAriaValueText.tsx.preview | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/data/material/components/progress/CircularCustomScale.tsx.preview b/docs/data/material/components/progress/CircularCustomScale.tsx.preview index 7a8217afccd1c0..a7c766ecf33d4c 100644 --- a/docs/data/material/components/progress/CircularCustomScale.tsx.preview +++ b/docs/data/material/components/progress/CircularCustomScale.tsx.preview @@ -4,4 +4,4 @@ max={20} value={progress} aria-label="Loading" -/> +/> \ No newline at end of file diff --git a/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview b/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview index 522e6969e88b15..1595531620a5ba 100644 --- a/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview +++ b/docs/data/material/components/progress/LinearWithAriaValueText.tsx.preview @@ -1 +1 @@ - + \ No newline at end of file From 281d3383e3306c57a554f1f5cc2d199a0ed1bee2 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 8 Apr 2026 15:59:16 +0300 Subject: [PATCH 29/46] accept both values in test --- .../mui-material/src/CircularProgress/CircularProgress.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index 5fd47a7cb7c2d6..fd910802737e3e 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -193,7 +193,7 @@ describe('', () => { const progressbar = screen.getByRole('progressbar'); expect(progressbar).to.have.nested.property('style.transform', 'rotate(-90deg)'); - expect(circle.style.strokeDasharray).to.equal('126.920'); + expect(circle.style.strokeDasharray).to.match(/126\.920?(px)?/gm); expect(circle.style.strokeDashoffset).to.equal('95.190px'); }); From 7ed9b3e81d992251b5bfc1ff1fb17a88c0e4c15a Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 8 Apr 2026 16:21:14 +0300 Subject: [PATCH 30/46] only warn when min or max are provided with wrong variant --- .../mui-material/src/CircularProgress/CircularProgress.js | 2 +- .../src/CircularProgress/CircularProgress.test.js | 4 ++-- packages/mui-material/src/LinearProgress/LinearProgress.js | 2 +- .../mui-material/src/LinearProgress/LinearProgress.test.js | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index f4bbd86f292d71..953a45df7e6d71 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -199,7 +199,7 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref if (process.env.NODE_ENV !== 'production') { if (variant === 'indeterminate' && (minProp !== undefined || maxProp !== undefined)) { - console.error( + console.warn( `MUI: You have provided the \`min\` or \`max\` props with a 'indeterminate' variant. These props will have no effect.`, ); } diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index fd910802737e3e..9ca2bbbe156213 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -240,10 +240,10 @@ describe('', () => { ]); }); - it('should error if min and max props are provided with an indeterminate variant', () => { + it('should warn if min and max props are provided with an indeterminate variant', () => { expect(() => { render(); - }).toErrorDev([ + }).toWarnDev([ "MUI: You have provided the `min` or `max` props with a 'indeterminate' variant. These props will have no effect.", !strictModeDoubleLoggingSuppressed && "MUI: You have provided the `min` or `max` props with a 'indeterminate' variant. These props will have no effect.", diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.js b/packages/mui-material/src/LinearProgress/LinearProgress.js index bac01e666f0387..1f3c071e33665c 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.js @@ -375,7 +375,7 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { ['indeterminate', 'query'].includes(variant) && (minProp !== undefined || maxProp !== undefined) ) { - console.error( + console.warn( `MUI: You have provided the \`min\` or \`max\` props with a 'indeterminate' or 'query' variant. These props will have no effect.`, ); } diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.test.js b/packages/mui-material/src/LinearProgress/LinearProgress.test.js index f299431fc49255..f153820010dd7b 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.test.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.test.js @@ -301,10 +301,10 @@ describe('', () => { ]); }); - it('should error if variant is indeterminate or query and min or max props are provided', () => { + it('should warn if variant is indeterminate or query and min or max props are provided', () => { expect(() => { render(); - }).toErrorDev([ + }).toWarnDev([ "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", !strictModeDoubleLoggingSuppressed && "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", @@ -312,7 +312,7 @@ describe('', () => { expect(() => { render(); - }).toErrorDev([ + }).toWarnDev([ "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", !strictModeDoubleLoggingSuppressed && "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", From 165ac99cd68e2ac78efd1f2d69e7290acb573c21 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 8 Apr 2026 16:40:43 +0300 Subject: [PATCH 31/46] regex for dashoffset too --- .../mui-material/src/CircularProgress/CircularProgress.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index 9ca2bbbe156213..0cad1c6017a708 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -194,7 +194,7 @@ describe('', () => { expect(progressbar).to.have.nested.property('style.transform', 'rotate(-90deg)'); expect(circle.style.strokeDasharray).to.match(/126\.920?(px)?/gm); - expect(circle.style.strokeDashoffset).to.equal('95.190px'); + expect(circle.style.strokeDashoffset).to.match(/95\.190?(px)?/gm); }); it('should fallback to 0px strokeDashoffset if max is less than min', () => { From 656d608b5bd6cb8bd9260a9f339b643fb2e5f3d4 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Tue, 14 Apr 2026 14:05:25 +0300 Subject: [PATCH 32/46] fix error messages --- .../mui-material/src/CircularProgress/CircularProgress.js | 2 +- .../src/CircularProgress/CircularProgress.test.js | 4 ++-- .../mui-material/src/LinearProgress/LinearProgress.js | 2 +- .../src/LinearProgress/LinearProgress.test.js | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index 953a45df7e6d71..ec7ec0d8b961ef 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -200,7 +200,7 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref if (process.env.NODE_ENV !== 'production') { if (variant === 'indeterminate' && (minProp !== undefined || maxProp !== undefined)) { console.warn( - `MUI: You have provided the \`min\` or \`max\` props with a 'indeterminate' variant. These props will have no effect.`, + `MUI: You have provided the \`min\` or \`max\` props with an 'indeterminate' variant. These props will have no effect.`, ); } } diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index 0cad1c6017a708..170ba6e691d3e5 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -244,9 +244,9 @@ describe('', () => { expect(() => { render(); }).toWarnDev([ - "MUI: You have provided the `min` or `max` props with a 'indeterminate' variant. These props will have no effect.", + "MUI: You have provided the `min` or `max` props with an 'indeterminate' variant. These props will have no effect.", !strictModeDoubleLoggingSuppressed && - "MUI: You have provided the `min` or `max` props with a 'indeterminate' variant. These props will have no effect.", + "MUI: You have provided the `min` or `max` props with an 'indeterminate' variant. These props will have no effect.", ]); }); }); diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.js b/packages/mui-material/src/LinearProgress/LinearProgress.js index 1f3c071e33665c..46c0d475049d23 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.js @@ -376,7 +376,7 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { (minProp !== undefined || maxProp !== undefined) ) { console.warn( - `MUI: You have provided the \`min\` or \`max\` props with a 'indeterminate' or 'query' variant. These props will have no effect.`, + `MUI: You have provided the \`min\` or \`max\` props with an 'indeterminate' or 'query' variant. These props will have no effect.`, ); } } diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.test.js b/packages/mui-material/src/LinearProgress/LinearProgress.test.js index f153820010dd7b..8a2a304dba85b0 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.test.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.test.js @@ -305,17 +305,17 @@ describe('', () => { expect(() => { render(); }).toWarnDev([ - "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", + "MUI: You have provided the `min` or `max` props with an 'indeterminate' or 'query' variant. These props will have no effect.", !strictModeDoubleLoggingSuppressed && - "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", + "MUI: You have provided the `min` or `max` props with an 'indeterminate' or 'query' variant. These props will have no effect.", ]); expect(() => { render(); }).toWarnDev([ - "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", + "MUI: You have provided the `min` or `max` props with an 'indeterminate' or 'query' variant. These props will have no effect.", !strictModeDoubleLoggingSuppressed && - "MUI: You have provided the `min` or `max` props with a 'indeterminate' or 'query' variant. These props will have no effect.", + "MUI: You have provided the `min` or `max` props with an 'indeterminate' or 'query' variant. These props will have no effect.", ]); }); }); From ab46e751a7be38636abac1637a82564aee69e17c Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Tue, 14 Apr 2026 14:09:33 +0300 Subject: [PATCH 33/46] remove not needed margin --- .../material/components/progress/LinearWithValueLabel.js | 7 +------ .../material/components/progress/LinearWithValueLabel.tsx | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/docs/data/material/components/progress/LinearWithValueLabel.js b/docs/data/material/components/progress/LinearWithValueLabel.js index 4bb45a6ad23769..da8e5aa0169a36 100644 --- a/docs/data/material/components/progress/LinearWithValueLabel.js +++ b/docs/data/material/components/progress/LinearWithValueLabel.js @@ -8,12 +8,7 @@ function LinearProgressWithLabelAndValue(props) { const progressId = React.useId(); return (
- + Uploading photos… diff --git a/docs/data/material/components/progress/LinearWithValueLabel.tsx b/docs/data/material/components/progress/LinearWithValueLabel.tsx index a35eafeeb34512..e7362decef5287 100644 --- a/docs/data/material/components/progress/LinearWithValueLabel.tsx +++ b/docs/data/material/components/progress/LinearWithValueLabel.tsx @@ -9,12 +9,7 @@ function LinearProgressWithLabelAndValue( const progressId = React.useId(); return (
- + Uploading photos… From eed6fbec5b3ff0a727fee159f9412d0be1e8d067 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Tue, 14 Apr 2026 14:13:21 +0300 Subject: [PATCH 34/46] fix the value default with min --- .../mui-material/src/CircularProgress/CircularProgress.js | 2 +- .../src/CircularProgress/CircularProgress.test.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index ec7ec0d8b961ef..b23d9b33ea920a 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -192,7 +192,7 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref size = 40, style, thickness = 3.6, - value = 0, + value = minProp ?? 0, variant = 'indeterminate', ...other } = props; diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index 170ba6e691d3e5..c8ab0cecb15852 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -197,6 +197,12 @@ describe('', () => { expect(circle.style.strokeDashoffset).to.match(/95\.190?(px)?/gm); }); + it('should fallback value to min if min is passed ', () => { + render(); + + expect(screen.getByRole('progressbar')).to.have.attribute('aria-valuenow', '10'); + }); + it('should fallback to 0px strokeDashoffset if max is less than min', () => { const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); From 5704bb05d5bfc270b128d9ebb611c7f2fa66b018 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Tue, 14 Apr 2026 14:22:55 +0300 Subject: [PATCH 35/46] remove rounding of value --- .../src/CircularProgress/CircularProgress.js | 2 +- .../src/CircularProgress/CircularProgress.test.js | 9 +++++++++ .../mui-material/src/LinearProgress/LinearProgress.js | 2 +- .../src/LinearProgress/LinearProgress.test.js | 9 +++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index b23d9b33ea920a..3d5406fc18a0d6 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -242,7 +242,7 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref range > 0 ? `${(((max - value) / range) * circumference).toFixed(3)}px` : '0px'; rootStyle.transform = 'rotate(-90deg)'; - rootProps['aria-valuenow'] = Math.round(value); + rootProps['aria-valuenow'] = value; rootProps['aria-valuemin'] = min; rootProps['aria-valuemax'] = max; } diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index c8ab0cecb15852..6fd72726a78cb1 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -203,6 +203,15 @@ describe('', () => { expect(screen.getByRole('progressbar')).to.have.attribute('aria-valuenow', '10'); }); + it('should be able to use decimal min, max and value props', () => { + render(); + const progressbar = screen.getByRole('progressbar'); + + expect(progressbar).to.have.attribute('aria-valuenow', '5.5'); + expect(progressbar).to.have.attribute('aria-valuemin', '2.5'); + expect(progressbar).to.have.attribute('aria-valuemax', '10.3'); + }); + it('should fallback to 0px strokeDashoffset if max is less than min', () => { const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.js b/packages/mui-material/src/LinearProgress/LinearProgress.js index 46c0d475049d23..a6da57539d2aa0 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.js @@ -407,7 +407,7 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { } inlineStyles.bar1.transform = range > 0 ? `translateX(${transform}%)` : undefined; - rootProps['aria-valuenow'] = Math.round(value); + rootProps['aria-valuenow'] = value; rootProps['aria-valuemin'] = min; rootProps['aria-valuemax'] = max; } else if (process.env.NODE_ENV !== 'production') { diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.test.js b/packages/mui-material/src/LinearProgress/LinearProgress.test.js index 8a2a304dba85b0..a1f403e78ec213 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.test.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.test.js @@ -193,6 +193,15 @@ describe('', () => { expect(progressbar).to.have.attribute('aria-valuemax', '10'); }); + it('should be able to use decimal min, max and value props', () => { + render(); + const progressbar = screen.getByRole('progressbar'); + + expect(progressbar).to.have.attribute('aria-valuenow', '5.5'); + expect(progressbar).to.have.attribute('aria-valuemin', '2.5'); + expect(progressbar).to.have.attribute('aria-valuemax', '10.3'); + }); + it('min and max values should be used to calculate the width of the bar', () => { render(); const progressbar = screen.getByRole('progressbar'); From 6a1b88f7430efc8067eea4ddcb08dfac37c59126 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Tue, 14 Apr 2026 14:27:18 +0300 Subject: [PATCH 36/46] fix lint --- .../mui-material/src/CircularProgress/CircularProgress.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index 6fd72726a78cb1..f7623debf09c85 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -197,7 +197,7 @@ describe('', () => { expect(circle.style.strokeDashoffset).to.match(/95\.190?(px)?/gm); }); - it('should fallback value to min if min is passed ', () => { + it('should fallback value to min if min is passed', () => { render(); expect(screen.getByRole('progressbar')).to.have.attribute('aria-valuenow', '10'); From 8e97de0dafaed9acfd6fbc8570c0f073acbf1c7a Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Tue, 14 Apr 2026 15:15:36 +0300 Subject: [PATCH 37/46] update jsdoc --- .../mui-material/src/CircularProgress/CircularProgress.d.ts | 2 +- packages/mui-material/src/CircularProgress/CircularProgress.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts index 5b0bd16bb2f0db..296045f3150dd9 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts +++ b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts @@ -69,7 +69,7 @@ export interface CircularProgressProps extends StandardProps< /** * The value of the progress indicator for the determinate variant. * Value between `min` and `max`. - * @default 0 + * @default min ?? 0 */ value?: number | undefined; /** diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index 3d5406fc18a0d6..bf08ea64747a7e 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -370,7 +370,7 @@ CircularProgress.propTypes /* remove-proptypes */ = { /** * The value of the progress indicator for the determinate variant. * Value between `min` and `max`. - * @default 0 + * @default min ?? 0 */ value: PropTypes.number, /** From 4f637da7171a4f6f82494eee8b72807eb1318f52 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Tue, 14 Apr 2026 15:19:57 +0300 Subject: [PATCH 38/46] fix again jsdoc --- .../mui-material/src/CircularProgress/CircularProgress.d.ts | 2 +- packages/mui-material/src/CircularProgress/CircularProgress.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts index 296045f3150dd9..46c5f5db0c5745 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts +++ b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts @@ -69,7 +69,7 @@ export interface CircularProgressProps extends StandardProps< /** * The value of the progress indicator for the determinate variant. * Value between `min` and `max`. - * @default min ?? 0 + * @default minProp ?? 0 */ value?: number | undefined; /** diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index bf08ea64747a7e..55e00fdd221a28 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -370,7 +370,7 @@ CircularProgress.propTypes /* remove-proptypes */ = { /** * The value of the progress indicator for the determinate variant. * Value between `min` and `max`. - * @default min ?? 0 + * @default minProp ?? 0 */ value: PropTypes.number, /** From 843ead20c369ab79b9131de7a2624606d813fa63 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Tue, 14 Apr 2026 15:24:28 +0300 Subject: [PATCH 39/46] fix jsdoc in examples --- .../data/material/components/progress/CircularWithValueLabel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/material/components/progress/CircularWithValueLabel.js b/docs/data/material/components/progress/CircularWithValueLabel.js index 9a1d3aca6e6130..578a770c0ab13f 100644 --- a/docs/data/material/components/progress/CircularWithValueLabel.js +++ b/docs/data/material/components/progress/CircularWithValueLabel.js @@ -40,7 +40,7 @@ CircularProgressWithLabel.propTypes = { /** * The value of the progress indicator for the determinate variant. * Value between `min` and `max`. - * @default 0 + * @default minProp ?? 0 */ value: PropTypes.number.isRequired, }; From 2e29524d2fa3bfe94b76c4b4bc6f5869a508cdb3 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Tue, 14 Apr 2026 15:40:36 +0300 Subject: [PATCH 40/46] update docs --- docs/pages/material-ui/api/circular-progress.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/material-ui/api/circular-progress.json b/docs/pages/material-ui/api/circular-progress.json index fc7517c646aa5e..babf76a701aef2 100644 --- a/docs/pages/material-ui/api/circular-progress.json +++ b/docs/pages/material-ui/api/circular-progress.json @@ -24,7 +24,7 @@ "additionalInfo": { "sx": true } }, "thickness": { "type": { "name": "number" }, "default": "3.6" }, - "value": { "type": { "name": "number" }, "default": "0" }, + "value": { "type": { "name": "number" }, "default": "minProp ?? 0" }, "variant": { "type": { "name": "enum", "description": "'determinate'
| 'indeterminate'" }, "default": "'indeterminate'" From b36a42de9497df4d6a12a7ae736cd98d5b18a644 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 15 Apr 2026 11:00:49 +0300 Subject: [PATCH 41/46] updates for docs page --- .../material/components/progress/progress.md | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/data/material/components/progress/progress.md b/docs/data/material/components/progress/progress.md index 38f1f5c2545a15..40e8e38bdc6ed7 100644 --- a/docs/data/material/components/progress/progress.md +++ b/docs/data/material/components/progress/progress.md @@ -24,6 +24,8 @@ The animations of the components rely on CSS as much as possible to work even be ### Circular indeterminate +The default version of CircularProgress renders an indeterminate spinner. + {{"demo": "CircularIndeterminate.js"}} ### Circular color @@ -36,6 +38,8 @@ The animations of the components rely on CSS as much as possible to work even be ### Circular determinate +To specify the loading progress of an operation, use the `determinate` value for the `variant` prop. To show the actual progress, use the `value` prop. + {{"demo": "CircularDeterminate.js"}} ### Circular custom scale @@ -46,24 +50,34 @@ By default, progress values are expected in the 0–100 range. You can customize ### Circular track +To have the circular track always visible, pass the `enableTrackSlot` prop. + {{"demo": "CircularEnableTrack.js"}} ### Interactive integration +The following examples show how to integrate the CircularProgress with the Button and FAB components, creating loading states that can be triggered by user actions. + {{"demo": "CircularIntegration.js"}} ### Circular with label +The example shows how to integrate the visual progress value with the CircularProgress component. + {{"demo": "CircularWithValueLabel.js"}} ## Linear ### Linear indeterminate +LinearProgress shows an indeterminate progress bar by default. + {{"demo": "LinearIndeterminate.js"}} ### Linear query +To reverse the direction of the indeterminate animation, use the `query` value for the `variant` prop. + {{"demo": "LinearQuery.js"}} ### Linear color @@ -72,13 +86,19 @@ By default, progress values are expected in the 0–100 range. You can customize ### Linear determinate +To show the progress on the loading bar, use the `determinate` value for the `variant` prop, along with the `value` prop. + {{"demo": "LinearDeterminate.js"}} ### Linear buffer +Use the `buffer` value for the `variant` prop to show a buffer progress alongside the actual progress value. The `valueBuffer` prop should be greater than the `value` prop. + {{"demo": "LinearBuffer.js"}} -### Linear with label and value label +### Linear with label + +The progress `value` can also be displayed alongside the progress bar. {{"demo": "LinearWithValueLabel.js"}} From 19331168fb9c559c48218f2c6d2d49fd6dcbb416 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 15 Apr 2026 11:18:40 +0300 Subject: [PATCH 42/46] add MUI error prefix --- .../src/LinearProgress/LinearProgress.test.js | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.test.js b/packages/mui-material/src/LinearProgress/LinearProgress.test.js index a1f403e78ec213..23a2bb51501a8e 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.test.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.test.js @@ -253,17 +253,17 @@ describe('', () => { expect(() => { render(); }).toErrorDev([ - 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=-1.', + 'MUI: The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=-1.', !strictModeDoubleLoggingSuppressed && - 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=-1.', + 'MUI: The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=-1.', ]); expect(() => { render(); }).toErrorDev([ - 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=11.', + 'MUI: The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=11.', !strictModeDoubleLoggingSuppressed && - 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=11.', + 'MUI: The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=0, max=10, value=11.', ]); }); @@ -271,25 +271,25 @@ describe('', () => { expect(() => { render(); }).toErrorDev([ - 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=4.', + 'MUI: The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=4.', !strictModeDoubleLoggingSuppressed && - 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=4.', + 'MUI: The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=4.', ]); expect(() => { render(); }).toErrorDev([ - 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=11.', + 'MUI: The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=11.', !strictModeDoubleLoggingSuppressed && - 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=11.', + 'MUI: The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=11.', ]); expect(() => { render(); }).toErrorDev([ - 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=-1.', + 'MUI: The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=-1.', !strictModeDoubleLoggingSuppressed && - 'The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=-1.', + 'MUI: The min, max, value, and valueBuffer props in LinearProgress should be numbers where min < max and min <= value <= valueBuffer <= max. Received min=0, max=10, value=5, valueBuffer=-1.', ]); }); @@ -297,16 +297,16 @@ describe('', () => { expect(() => { render(); }).toErrorDev([ - 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=0, value=5.', + 'MUI: The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=0, value=5.', !strictModeDoubleLoggingSuppressed && - 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=0, value=5.', + 'MUI: The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=0, value=5.', ]); expect(() => { render(); }).toErrorDev([ - 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=10, value=5.', + 'MUI: The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=10, value=5.', !strictModeDoubleLoggingSuppressed && - 'The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=10, value=5.', + 'MUI: The min, max, and value props in LinearProgress should be numbers where min < max and min <= value <= max. Received min=10, max=10, value=5.', ]); }); From 6972abaf5512ae9e253c70c6ffbbbe6d46e4f142 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 15 Apr 2026 11:35:17 +0300 Subject: [PATCH 43/46] safer fallbacks for min > max --- .../mui-material/src/CircularProgress/CircularProgress.js | 4 +++- .../src/CircularProgress/CircularProgress.test.js | 4 ++-- packages/mui-material/src/LinearProgress/LinearProgress.js | 4 ++-- .../mui-material/src/LinearProgress/LinearProgress.test.js | 6 +++--- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index 55e00fdd221a28..fc5ec5c814f004 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -239,7 +239,9 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref const range = max - min; circleStyle.strokeDasharray = circumference.toFixed(3); circleStyle.strokeDashoffset = - range > 0 ? `${(((max - value) / range) * circumference).toFixed(3)}px` : '0px'; + range > 0 + ? `${(((max - value) / range) * circumference).toFixed(3)}px` + : `${circumference.toFixed(3)}px`; // empty-state fallback when range is invalid rootStyle.transform = 'rotate(-90deg)'; rootProps['aria-valuenow'] = value; diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.test.js b/packages/mui-material/src/CircularProgress/CircularProgress.test.js index f7623debf09c85..094aa6a454a0b0 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.test.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.test.js @@ -212,14 +212,14 @@ describe('', () => { expect(progressbar).to.have.attribute('aria-valuemax', '10.3'); }); - it('should fallback to 0px strokeDashoffset if max is less than min', () => { + it('should fallback to a full circumference strokeDashoffset (empty state) if max is less than min', () => { const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); const { container } = render( , ); const [circle] = container.querySelectorAll('svg circle'); - expect(circle.style.strokeDashoffset).to.equal('0px'); + expect(circle.style.strokeDashoffset).to.match(/126\.920?(px)?/gm); errorSpy.mockRestore(); }); diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.js b/packages/mui-material/src/LinearProgress/LinearProgress.js index a6da57539d2aa0..666dc0599cea19 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.js @@ -405,7 +405,7 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { if (isRtl) { transform = -transform; } - inlineStyles.bar1.transform = range > 0 ? `translateX(${transform}%)` : undefined; + inlineStyles.bar1.transform = range > 0 ? `translateX(${transform}%)` : 'translateX(-100%)'; // empty-state fallback when range is invalid rootProps['aria-valuenow'] = value; rootProps['aria-valuemin'] = min; @@ -432,7 +432,7 @@ const LinearProgress = React.forwardRef(function LinearProgress(inProps, ref) { if (isRtl) { transform = -transform; } - inlineStyles.bar2.transform = range > 0 ? `translateX(${transform}%)` : undefined; + inlineStyles.bar2.transform = range > 0 ? `translateX(${transform}%)` : 'translateX(-100%)'; // empty-state fallback when range is invalid } else if (process.env.NODE_ENV !== 'production') { console.error( 'MUI: You need to provide a valueBuffer prop ' + diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.test.js b/packages/mui-material/src/LinearProgress/LinearProgress.test.js index 23a2bb51501a8e..69d3ab1cb39223 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.test.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.test.js @@ -237,14 +237,14 @@ describe('', () => { errorSpy.mockRestore(); }); - it('should not add transform style to the buffer bar when min is equal or larger than max', () => { + it('should fallback to an empty state (translateX(-100%)) for the buffer bar when min is equal or larger than max', () => { const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); render(); const progressbar = screen.getByRole('progressbar'); - expect(progressbar.children[1].style.transform).to.equal(''); - expect(progressbar.children[2].style.transform).to.equal(''); + expect(progressbar.children[1].style.transform).to.equal('translateX(-100%)'); + expect(progressbar.children[2].style.transform).to.equal('translateX(-100%)'); errorSpy.mockRestore(); }); From c19fc2744d4870c33125d2686fa6f35fa43945ee Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 15 Apr 2026 11:40:39 +0300 Subject: [PATCH 44/46] fix the other test --- packages/mui-material/src/LinearProgress/LinearProgress.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.test.js b/packages/mui-material/src/LinearProgress/LinearProgress.test.js index 69d3ab1cb39223..bc9936b2149e92 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.test.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.test.js @@ -232,7 +232,7 @@ describe('', () => { render(); const progressbar = screen.getByRole('progressbar'); - expect(progressbar.children[0].style.transform).to.equal(''); + expect(progressbar.children[0].style.transform).to.equal('translateX(-100%)'); errorSpy.mockRestore(); }); From 5f8524a03eaa246d31c2a5613a66bc98ef121ff0 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 15 Apr 2026 13:14:24 +0300 Subject: [PATCH 45/46] fix jsdoc min reference --- .../material/components/progress/CircularWithValueLabel.js | 2 +- .../mui-material/src/CircularProgress/CircularProgress.d.ts | 2 +- .../mui-material/src/CircularProgress/CircularProgress.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/data/material/components/progress/CircularWithValueLabel.js b/docs/data/material/components/progress/CircularWithValueLabel.js index 578a770c0ab13f..fbb9d0b12882f8 100644 --- a/docs/data/material/components/progress/CircularWithValueLabel.js +++ b/docs/data/material/components/progress/CircularWithValueLabel.js @@ -40,7 +40,7 @@ CircularProgressWithLabel.propTypes = { /** * The value of the progress indicator for the determinate variant. * Value between `min` and `max`. - * @default minProp ?? 0 + * @default props.min ?? 0 */ value: PropTypes.number.isRequired, }; diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts index 46c5f5db0c5745..7399f2351f6336 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.d.ts +++ b/packages/mui-material/src/CircularProgress/CircularProgress.d.ts @@ -69,7 +69,7 @@ export interface CircularProgressProps extends StandardProps< /** * The value of the progress indicator for the determinate variant. * Value between `min` and `max`. - * @default minProp ?? 0 + * @default props.min ?? 0 */ value?: number | undefined; /** diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index fc5ec5c814f004..8101edb0f7c2d9 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -192,7 +192,7 @@ const CircularProgress = React.forwardRef(function CircularProgress(inProps, ref size = 40, style, thickness = 3.6, - value = minProp ?? 0, + value = props.min ?? 0, variant = 'indeterminate', ...other } = props; @@ -372,7 +372,7 @@ CircularProgress.propTypes /* remove-proptypes */ = { /** * The value of the progress indicator for the determinate variant. * Value between `min` and `max`. - * @default minProp ?? 0 + * @default props.min ?? 0 */ value: PropTypes.number, /** From f93b11f857d635a0cbe534dbe26ef3d348382394 Mon Sep 17 00:00:00 2001 From: Silviu Alexandru Avram Date: Wed, 15 Apr 2026 13:17:14 +0300 Subject: [PATCH 46/46] docs:api --- docs/pages/material-ui/api/circular-progress.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/material-ui/api/circular-progress.json b/docs/pages/material-ui/api/circular-progress.json index babf76a701aef2..f36c3e57fd79b9 100644 --- a/docs/pages/material-ui/api/circular-progress.json +++ b/docs/pages/material-ui/api/circular-progress.json @@ -24,7 +24,7 @@ "additionalInfo": { "sx": true } }, "thickness": { "type": { "name": "number" }, "default": "3.6" }, - "value": { "type": { "name": "number" }, "default": "minProp ?? 0" }, + "value": { "type": { "name": "number" }, "default": "props.min ?? 0" }, "variant": { "type": { "name": "enum", "description": "'determinate'
| 'indeterminate'" }, "default": "'indeterminate'"