Skip to content

[interactive elements] remove duplicated disabled prop#3650

Merged
atomiks merged 7 commits intomui:masterfrom
seongminn:remove-unappropriate-disabled
Jan 2, 2026
Merged

[interactive elements] remove duplicated disabled prop#3650
atomiks merged 7 commits intomui:masterfrom
seongminn:remove-unappropriate-disabled

Conversation

@seongminn
Copy link
Contributor

getButtonProps selects and applies either disabled or aria-disabled appropriately. But the disabled attribute was always being added separately, meaning it was always present regardless.

Fixes #3649

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 31, 2025

  • vite-css-base-ui-example

    pnpm add https://pkg.pr.new/mui/base-ui/@base-ui/react@3650
    
    pnpm add https://pkg.pr.new/mui/base-ui/@base-ui/utils@3650
    

commit: 0edf41e

@mui-bot
Copy link

mui-bot commented Dec 31, 2025

Bundle size report

Bundle Parsed size Gzip size
@base-ui/react ▼-282B(-0.07%) ▼-91B(-0.07%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@netlify
Copy link

netlify bot commented Dec 31, 2025

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 0edf41e
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/695720f2bc246300086204c9
😎 Deploy Preview https://deploy-preview-3650--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@seongminn seongminn marked this pull request as draft December 31, 2025 11:08
@seongminn seongminn marked this pull request as ready for review January 1, 2026 07:33
@seongminn
Copy link
Contributor Author

When focusableWhenDisabled is true, aria-disabled should be applied instead of disabled. Accordingly, I modified the test code for ComboboxChipRemove.

Additionally, when the disabled attribute was added to ComboboxChipRemove, it was not composing with the disabled attribute passed to ComboboxRoot. So I fixed that as well.

Comment on lines +55 to +66
@@ -63,7 +63,7 @@ export const NumberFieldIncrement = React.forwardRef(function NumberFieldIncreme
maxWithDefault,
value,
inputValue,
disabled,
disabled: composedDisabled,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fixes - what is this particular file (and Decrement) changed for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with other components, it appropriately merges the disabled passed from the Root component and the disabled passed from the Increment component.

And unlike other components, NumberField recalculates disabled within useNumberFieldButton. Therefore, it separately creates composedDisabled. If declaring this variable is unnecessary, directly assigning it as shown below is also valid.

const { disabled = false, ...props } = useNumberFieldButton({
    // ....
    disabled: disabledProp || contextDisabled,
});

Copy link
Contributor

@atomiks atomiks Jan 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see that you're checking the result of the internal calculation:

disabled: disabled || (isIncrement ? isMax : isMin),

I would do this calculation before passing to useNumberFieldButton, that way it's composed of all the states and NumberFieldIncrement.State has the correct disabled state, without needing the destructure props collection?

Furthermore, I realized that the Number Field buttons should use focusableWhenDisabled: true in useButton so focus isn't lost when it reaches the min/max value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before passing it to the useNumberFieldButton hook, completing the calculation of the disabled property would look like this:

const composedDisabled = disabledProp || contextDisabled;
const isMax = value != null && value >= maxWithDefault;

```ts
const { disabled = false, ...props } = useNumberFieldButton({
    // ...
    disabled: composedDisabled || isMax,
});

However, doing this might allow the isDisabled value to change when calculated inside useNumberFieldButton.

// current
const isDisabled = disabled || readOnly || (isIncrement ? isMax : isMin);

// changed
const isDisabled = disabled || readOnly;

But I don't think this difference is particularly significant. So, I think it would be okay to change the internal logic of the useNumberFieldButton hook. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's better as it reduces the repetition in the event handlers

It should look like this:

const isMax = value != null && value >= maxWithDefault;
const disabled = disabledProp || contextDisabled || isMax;

const props = useNumberFieldButton({
    disabled,
});

Then internally,

const isDisabled = disabled || readOnly;

Since disabled has the min/max condition

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your feedback. I did it here

@zannager zannager added the scope: all components Widespread work has an impact on almost all components. label Jan 1, 2026
Copy link
Contributor

@atomiks atomiks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you - pnpm prettier needs to be run

@seongminn
Copy link
Contributor Author

I did it here!

@atomiks atomiks merged commit 49cfd5e into mui:master Jan 2, 2026
22 of 23 checks passed
atomiks pushed a commit to atomiks/base-ui that referenced this pull request Jan 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: all components Widespread work has an impact on almost all components.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

disabled attribute applied inappropriately.

4 participants