Skip to content

Label overlapping set value in certain scenarios if initial value was null #48824

Description

@chenaviv

Steps to reproduce

Steps:

  1. Open this link to live example: https://codesandbox.io/p/sandbox/9f5wc6
  2. You'll see a set of 3 plain text inputs and 3 select inputs.
  3. These inputs all have a value of "20" set programmatically a little after they are mounted with a falsy initial value ('', null or undefined).
  4. Notice that in the text fields, when the initial value was null or undefined the late value setting does not trigger a shrinking of the label.
  5. Notice that in the select inputs, the same happens when the initial value is null. When the initial value is undefined, the programmatic value setting does not "take" (which is understandable, as an undefined initial value suggests the input is not controlled).

Note that when removing the timeout, the buggy behavior does not reproduce in any of the plain text fields, but does still reproduce in the select fields.

Also, in this reproduction, for some reason, once the input is clicked and its focused state is activated, it does not deactivate when clicking outside the input. However, when navigating the inputs with a keyboard, you can observe that the faulty labels' shrink state does not survive when tabbing away from the focused inputs.

Current behavior

When the initial value of a select field is set to null, and shortly after that value changes programmatically (i.e. without actual user interaction) to a truthy value, the label does not shrink, and the value and label overlap each other.

Image

Expected behavior

Unlike undefined, a null initial value should be regarded as a controlled value, and as such, when programmatically changing it before any actual user interaction, the label should shrink and not overlap the set value.

Context

We recently added a feature of auto-selecting a select option if it is the only option available.

Following this change, we encountered an issue in some fields that had their initial value set to null, where this auto-selection did not trigger the label shrink state.

Since the auto-selected option is the only option available in this scenario, and the user had no means of manually selecting a different option, the label remained unshrunk unless the input was actively focused.

We fixed the issue locally by activating the label's shrink state when we find that the input is "filled".

Our front end codebase is very outdated, and we are still using MUI v4, but the issue reproduces in current version as well.

Possible lead:
InputBase has its isControlled boolean set to "initial value being equal to null or undefined", and that isControlled boolean is later used to determine whether to run checkDirty({ value }) in a useEnhancedEffect.

Not sure if this is the culprit in this case, but since the useControlled hook sets its isControlled boolean to "initial value being equal to undefined and undefined only", this seems like an inconsistency nonetheless.

Your environment

npx @mui/envinfo

System:
OS: macOS 26.5.2
Binaries:
Node: 20.10.0
npm: 10.5.0
pnpm: Not Found
Browsers:
Chrome: 150.0.7871.125
Edge: Not Found
Firefox: 152.0.6
Safari: 26.5.2
npmPackages:
@emotion/react: ^11.7.1 => 11.7.1
@emotion/styled: ^11.6.0 => 11.6.0
@mui/base: 5.0.0-alpha.63
@mui/icons-material: ^5.2.5 => 5.2.5
@mui/material: ^5.2.7 => 5.2.7
@mui/private-theming: 5.2.3
@mui/styled-engine: 5.2.6
@mui/system: 5.2.6
@mui/types: 7.1.0
@mui/utils: 5.2.3
@types/react: ^17.0.0 => 17.0.75
react: ^17.0.2 => 17.0.2
react-dom: ^17.0.2 => 17.0.2
typescript: ^5.8.3 => 5.8.3

(We have both MUI 5 and 4 installed at the moment)

Search keywords: label shrink initialValue initial null select programmatically set value

Metadata

Metadata

Assignees

No one assigned

    Labels

    scope: selectChanges related to the select.scope: text fieldChanges related to the text field.

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions