[TextControl] First element in container margin interferes with label absolute positioning
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 99.1k
- Forks
- 32.5k
- Avg merge
- 2d 17h
- Merged PRs (30d)
- 106
Description
Duplicates
- I have searched the existing issues
Latest version
- I have tested the latest version
Current behavior 😯
When placing a TextField or FormControl component inside of a container element such as a stack or DialogContent element, the first TextField element doesn't have any margin-top applied to it. This causes the label, onFocus to render outside the bounding box of the input element, and since there is no margin-top outside the parent container as well, resulting in the label being cut off.
A working (non-working) example is included here: https://codesandbox.io/s/react-mui-forked-fpt0xl?file=/dialog.tsx where the Enter title form input becomes cutoff.
Expected behavior 🤔
I would expect the first element in a Stack or DialogContent, if it were an input element with an animated lable, to have enough margin for the label to be rendered outside the bounding box of the component and not be cutoff from the parent component. The code at issue seems to be similar to the following from mui-material/src/Stack/Stack.js lines 95-104:
const styleFromPropValue = (propValue, breakpoint) => {
return {
'& > :not(style) + :not(style)': {
margin: 0,
[`margin${getSideFromDirection(
breakpoint ? directionValues[breakpoint] : ownerState.direction,
)}`]: getValue(transformer, propValue),
},
};
};
I'm not sure how to solve this. On one hand, overriding the margin: 0 seems to be the answer so that input elements with labels always have the room to animate into the margin area, but on the other hand, this seems to be heavy-handed and would disrupt the layouts of many other first child elements in a Stack that don't require the margin to work properly. Perhaps all Inputs should be wrapped in a parent div that has padding of the appropriate number of pixels, to contain the Input element and leave room for the animation to work properly.
Steps to reproduce 🕹
Steps:
Follow the link to a code sandbox example of this issue:
https://codesandbox.io/s/react-mui-forked-fpt0xl?file=/dialog.tsx
OR
Run this file within a React application:
import * as React from 'react';
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import Stack from '@mui/material/Stack';
import DialogContent from '@mui/material/DialogContent';
import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon';
import { DesktopDatePicker } from '@mui/x-date-pickers';
import { LocalizationProvider } from '@mui/x-date-pickers';
import { FormControl, InputLabel, Input, FormHelperText } from '@mui/material';
import DialogTitle from '@mui/material/DialogTitle';
import Backdrop from '@mui/material/Backdrop';
import Paper, { PaperProps } from '@mui/material/Paper';
import Draggable from 'react-draggable';
import TextField from '@mui/material/TextField';
import { DateTime } from 'luxon';
function PaperComponent(props: PaperProps) {
return (
<Draggable
handle="#draggable-dialog-title"
cancel={'[class*="MuiDialogContent-root"]'}
>
<Paper {...props} />
);
}
export default function DraggableDialog() {
const [postDate, setPostDate] = React.useState<DateTime | null>(
DateTime.now()
);
const [summary, setSummary] = React.useState('');
return (
<Dialog
maxWidth="lg"
fullWidth
open={true}
onClose={() => {}}
PaperComponent={PaperComponent}
aria-labelledby="draggable-dialog-title"
>
<DialogTitle style={{ cursor: 'move' }} id="draggable-dialog-title">
Add Story
Title
Enter title
<DesktopDatePicker
label="Date"
renderInput={(props) => <TextField {...props} />}
value={postDate}
onChange={(newValue: DateTime | null) => {
setPostDate(newValue);
}}
/>
Summary
<Input
id="story-summary"
aria-describedby="story-summary-text"
value={summary}
multiline
minRows={5}
onChange={(e) => {
const { value } = e.target;
if (value.length <= 1000) setSummary(e.target.value);
}}
/>
{Enter Summary: (${summary.length}/1000}
<Button autoFocus onClick={() => {}}>
Cancel
<Button onClick={() => {}}>Add Story
);
}
Context 🔦
I've run into this issue trying to design a basic pop-up form for a personal project and cannot help but think I'm not the first person that has run into the issue of having an input element cutoff from its label. I believe that as a software package that focuses on layout and expressiveness and provides a lot of styling out of the box, that this is just one of those things that should work without having to provide sx styles on a per-component basis.
Your environment 🌎
npx @mui/envinfo
Don't forget to mention which browser you used.
Found on chrome- Version 104.0.5112.102 (Official Build) (64-bit)
System:
OS: Windows 10 10.0.22000
Binaries:
Node: 16.14.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.17 - ~\AppData\Roaming\npm\yarn.CMD
npm: 8.3.1 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: Not Found
Edge: Spartan (44.22000.120.0), Chromium (104.0.1293.70)
npmPackages:
@emotion/react: ^11.5.0 => 11.5.0
@emotion/styled: ^11.3.0 => 11.3.0
@mui/core: 5.0.0-alpha.51
@mui/docs: ^5.8.4 => 5.8.4
@mui/icons-material: ^5.0.4 => 5.0.4
@mui/material: ^5.0.4 => 5.0.4
@mui/private-theming: 5.0.1
@mui/styled-engine: 5.0.1
@mui/system: 5.0.4
@mui/types: 7.0.0
@mui/utils: 5.0.1
@mui/x-date-pickers: ^5.0.0-beta.6 => 5.0.0-beta.6
@types/react: ^17.0.0 => 17.0.2
react: ^17.0.1 => 17.0.1
react-dom: ^17.0.1 => 17.0.1
typescript: ^4.1.2 => 4.1.5
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the cutoff in the linked CodeSandbox and inspect mui-material/src/Stack/Stack.js around lines 95-104, alongside the TextField and FormControl layout used in the example. Determine a focused behavior that preserves Stack spacing while keeping animated input labels visible; done means the first labeled input is no longer clipped without disrupting other Stack children.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100