diff --git a/packages/mui-material/src/Select/Select.test.js b/packages/mui-material/src/Select/Select.test.js
index 4d6817f9ad0c13..a36065667dc939 100644
--- a/packages/mui-material/src/Select/Select.test.js
+++ b/packages/mui-material/src/Select/Select.test.js
@@ -468,6 +468,36 @@ describe('', () => {
expect(getByRole('combobox')).not.to.have.attribute('aria-disabled');
});
+ it('sets aria-required="true" when component is required', () => {
+ const { getByRole } = render();
+
+ expect(getByRole('combobox')).to.have.attribute('aria-required', 'true');
+ });
+
+ it('aria-required is not present if component is not required', () => {
+ const { getByRole } = render();
+
+ expect(getByRole('combobox')).not.to.have.attribute('aria-required');
+ });
+
+ it('sets required attribute in input when component is required', () => {
+ const { container } = render();
+
+ expect(container.querySelector('input')).to.have.property('required', true);
+ });
+
+ it('sets aria-invalid="true" when component is in the error state', () => {
+ const { getByRole } = render();
+
+ expect(getByRole('combobox')).to.have.attribute('aria-invalid', 'true');
+ });
+
+ it('aria-invalid is not present if component is not in an error state', () => {
+ const { getByRole } = render();
+
+ expect(getByRole('combobox')).not.to.have.attribute('aria-invalid');
+ });
+
it('indicates that activating the button displays a listbox', () => {
const { getByRole } = render();
diff --git a/packages/mui-material/src/Select/SelectInput.js b/packages/mui-material/src/Select/SelectInput.js
index c38b326cd13d21..fd48bd5d44b08d 100644
--- a/packages/mui-material/src/Select/SelectInput.js
+++ b/packages/mui-material/src/Select/SelectInput.js
@@ -124,6 +124,7 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
open: openProp,
readOnly,
renderValue,
+ required,
SelectDisplayProps = {},
tabIndex: tabIndexProp,
// catching `type` from Input which makes no sense for SelectInput
@@ -503,6 +504,8 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
aria-label={ariaLabel}
aria-labelledby={[labelId, buttonId].filter(Boolean).join(' ') || undefined}
aria-describedby={ariaDescribedby}
+ aria-required={required ? 'true' : undefined}
+ aria-invalid={error ? 'true' : undefined}
onKeyDown={handleKeyDown}
onMouseDown={disabled || readOnly ? null : handleMouseDown}
onBlur={handleBlur}
@@ -534,6 +537,7 @@ const SelectInput = React.forwardRef(function SelectInput(props, ref) {
disabled={disabled}
className={classes.nativeInput}
autoFocus={autoFocus}
+ required={required}
{...other}
ownerState={ownerState}
/>
@@ -700,6 +704,10 @@ SelectInput.propTypes = {
* @returns {ReactNode}
*/
renderValue: PropTypes.func,
+ /**
+ * If `true`, the component is required.
+ */
+ required: PropTypes.bool,
/**
* Props applied to the clickable div element.
*/