Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TextControl] First element in container margin interferes with label absolute positioning #34113

Open
2 tasks done
wjonesusna2012 opened this issue Aug 28, 2022 · 2 comments
Open
2 tasks done
Labels
bug 馃悰 Something doesn't work component: text field This is the name of the generic UI component, not the React module!

Comments

@wjonesusna2012
Copy link

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
@wjonesusna2012 wjonesusna2012 added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Aug 28, 2022
@siriwatknp siriwatknp added the component: text field This is the name of the generic UI component, not the React module! label Aug 30, 2022
@michaldudak
Copy link
Member

Hi, thanks for the report. I don't think we can add margins or padding now without breaking existing designs. The workaround can be applied in userland and is pretty simple - add a top padding to the Stack or other container that has a TextField showing this issue.

@michaldudak michaldudak added bug 馃悰 Something doesn't work and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Aug 30, 2022
@michaldudak michaldudak removed their assignment Aug 30, 2022
@YASHBRO
Copy link

YASHBRO commented Oct 9, 2022

Is this issue still up for grabs?

What if we add a pixel-perfect margin on top of the Text field which exactly covers the label
Or, if we use CSS selectors to look for TextFields as the 1st child of Stack, etc and add padding there
Is it a feasible solution, because it might break existing designs which already have padding for the above

According to me, making changes to the Label/Textfield is less design-breaking than doing anything to the Stacks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 馃悰 Something doesn't work component: text field This is the name of the generic UI component, not the React module!
Projects
None yet
Development

No branches or pull requests

4 participants