diff --git a/docs/src/pages/components/selects/NativeSelects.js b/docs/src/pages/components/selects/NativeSelects.js index 550e6d4e23ba46..d3945d59fe3056 100644 --- a/docs/src/pages/components/selects/NativeSelects.js +++ b/docs/src/pages/components/selects/NativeSelects.js @@ -23,12 +23,6 @@ export default function NativeSelects() { name: 'hai', }); - const inputLabel = React.useRef(null); - const [labelWidth, setLabelWidth] = React.useState(0); - React.useEffect(() => { - setLabelWidth(inputLabel.current.offsetWidth); - }, []); - const handleChange = name => event => { setState({ ...state, @@ -200,14 +194,12 @@ export default function NativeSelects() { Required - - Age - + Age { - setLabelWidth(inputLabel.current.offsetWidth); - }, []); - const handleChange = event => { setAge(event.target.value); }; @@ -195,15 +189,13 @@ export default function SimpleSelect() { Required - - Age - + Age None diff --git a/docs/src/pages/components/text-fields/ComposedTextField.js b/docs/src/pages/components/text-fields/ComposedTextField.js index b84468afc078e7..7d32e96003fd38 100644 --- a/docs/src/pages/components/text-fields/ComposedTextField.js +++ b/docs/src/pages/components/text-fields/ComposedTextField.js @@ -18,15 +18,9 @@ const useStyles = makeStyles(theme => ({ })); export default function ComposedTextField() { - const [labelWidth, setLabelWidth] = React.useState(0); const [name, setName] = React.useState('Composed TextField'); - const labelRef = React.useRef(null); const classes = useStyles(); - React.useEffect(() => { - setLabelWidth(labelRef.current.offsetWidth); - }, []); - const handleChange = event => { setName(event.target.value); }; @@ -63,15 +57,8 @@ export default function ComposedTextField() { Error - - Name - - + Name + Name diff --git a/docs/src/pages/components/text-fields/ComposedTextField.tsx b/docs/src/pages/components/text-fields/ComposedTextField.tsx index 7b15ceed818170..ea00f8b113424d 100644 --- a/docs/src/pages/components/text-fields/ComposedTextField.tsx +++ b/docs/src/pages/components/text-fields/ComposedTextField.tsx @@ -20,15 +20,9 @@ const useStyles = makeStyles((theme: Theme) => ); export default function ComposedTextField() { - const [labelWidth, setLabelWidth] = React.useState(0); const [name, setName] = React.useState('Composed TextField'); - const labelRef = React.useRef(null); const classes = useStyles(); - React.useEffect(() => { - setLabelWidth(labelRef.current!.offsetWidth); - }, []); - const handleChange = (event: React.ChangeEvent) => { setName(event.target.value); }; @@ -65,14 +59,14 @@ export default function ComposedTextField() { Error - + Name diff --git a/docs/src/pages/components/text-fields/InputAdornments.js b/docs/src/pages/components/text-fields/InputAdornments.js index f8efb3efe2f838..435a341ce85fcb 100644 --- a/docs/src/pages/components/text-fields/InputAdornments.js +++ b/docs/src/pages/components/text-fields/InputAdornments.js @@ -178,7 +178,6 @@ export default function InputAdornments() { inputProps={{ 'aria-label': 'weight', }} - labelWidth={0} /> Weight @@ -200,7 +199,7 @@ export default function InputAdornments() { } - labelWidth={70} + label="Password" /> @@ -210,7 +209,7 @@ export default function InputAdornments() { value={values.amount} onChange={handleChange('amount')} startAdornment={$} - labelWidth={60} + labelWidth="Amount" /> diff --git a/docs/src/pages/components/text-fields/InputAdornments.tsx b/docs/src/pages/components/text-fields/InputAdornments.tsx index 3a828a9380ddc7..d3890fb7d89e84 100644 --- a/docs/src/pages/components/text-fields/InputAdornments.tsx +++ b/docs/src/pages/components/text-fields/InputAdornments.tsx @@ -188,7 +188,6 @@ export default function InputAdornments() { inputProps={{ 'aria-label': 'weight', }} - labelWidth={0} /> Weight @@ -210,7 +209,7 @@ export default function InputAdornments() { } - labelWidth={70} + label="Password" /> @@ -220,7 +219,7 @@ export default function InputAdornments() { value={values.amount} onChange={handleChange('amount')} startAdornment={$} - labelWidth={60} + labelWidth="Amount" /> diff --git a/packages/material-ui/src/OutlinedInput/NotchedOutline.d.ts b/packages/material-ui/src/OutlinedInput/NotchedOutline.d.ts index 8d72fa235ef81d..ddb163e30db876 100644 --- a/packages/material-ui/src/OutlinedInput/NotchedOutline.d.ts +++ b/packages/material-ui/src/OutlinedInput/NotchedOutline.d.ts @@ -6,7 +6,7 @@ export interface NotchedOutlineProps disabled?: boolean; error?: boolean; focused?: boolean; - labelWidth: number; + label?: React.ReactNode; notched: boolean; } diff --git a/packages/material-ui/src/OutlinedInput/NotchedOutline.js b/packages/material-ui/src/OutlinedInput/NotchedOutline.js index 4f9881539d892f..d63483cd3467d8 100644 --- a/packages/material-ui/src/OutlinedInput/NotchedOutline.js +++ b/packages/material-ui/src/OutlinedInput/NotchedOutline.js @@ -3,50 +3,53 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import withStyles from '../styles/withStyles'; import useTheme from '../styles/useTheme'; -import capitalize from '../utils/capitalize'; -export const styles = theme => { - const align = theme.direction === 'rtl' ? 'right' : 'left'; - - return { - /* Styles applied to the root element. */ - root: { - position: 'absolute', - bottom: 0, - right: 0, - top: -5, - left: 0, - margin: 0, - padding: 0, - pointerEvents: 'none', - borderRadius: 'inherit', - borderStyle: 'solid', - borderWidth: 1, - // Match the Input Label - transition: theme.transitions.create([`padding-${align}`, 'border-color', 'border-width'], { - duration: theme.transitions.duration.shorter, - easing: theme.transitions.easing.easeOut, - }), - }, - /* Styles applied to the legend element. */ - legend: { - textAlign: 'left', - padding: 0, - lineHeight: '11px', - fontSize: '0.75rem', - maxWidth: 0, - transition: theme.transitions.create('max-width', { - duration: theme.transitions.duration.shorter, - easing: theme.transitions.easing.easeOut, - }), - visibility: 'hidden', - '& span': { - paddingLeft: 4, - paddingRight: 6, - }, +export const styles = theme => ({ + /* Styles applied to the root element. */ + root: { + position: 'absolute', + bottom: 0, + right: 0, + top: -5, + left: 0, + margin: 0, + padding: 0, + paddingLeft: 8, + pointerEvents: 'none', + borderRadius: 'inherit', + borderStyle: 'solid', + borderWidth: 1, + // Match the Input Label + transition: theme.transitions.create(['border-color', 'border-width'], { + duration: theme.transitions.duration.shorter, + easing: theme.transitions.easing.easeOut, + }), + }, + /* Styles applied to the legend element. */ + legend: { + textAlign: 'left', + padding: 0, + lineHeight: '11px', + fontSize: '0.75rem', + visibility: 'hidden', + maxWidth: 0, + transition: theme.transitions.create('max-width', { + duration: 50, + delay: 0, + }), + '& span': { + paddingLeft: 4, + paddingRight: 6, }, - }; -}; + }, + legendNotched: { + maxWidth: 1000, + transition: theme.transitions.create('max-width', { + duration: 100, + delay: 60, + }), + }, +}); /** * @ignore - internal component. @@ -56,31 +59,22 @@ const NotchedOutline = React.forwardRef(function NotchedOutline(props, ref) { children, classes, className, - label = '\u200B', - labelWidth: labelWidthProp, + label, notched, style, ...other } = props; - const theme = useTheme(); - const align = theme.direction === 'rtl' ? 'right' : 'left'; - const labelWidth = labelWidthProp > 0 ? labelWidthProp * 0.75 + 8 : 0; return ( -
- +
+ {/* Use the nominal use case of the legend, avoid rendering artefacts. */} {/* eslint-disable-next-line react/no-danger */} - {label} + {label ? {label} : }
); @@ -101,9 +95,9 @@ NotchedOutline.propTypes = { */ className: PropTypes.string, /** - * The width of the label. + * The label. */ - labelWidth: PropTypes.number.isRequired, + label: PropTypes.node, /** * If `true`, the outline is notched to accommodate the label. */ diff --git a/packages/material-ui/src/OutlinedInput/OutlinedInput.d.ts b/packages/material-ui/src/OutlinedInput/OutlinedInput.d.ts index eb2da9c7ae7913..d78591bfd0ef20 100644 --- a/packages/material-ui/src/OutlinedInput/OutlinedInput.d.ts +++ b/packages/material-ui/src/OutlinedInput/OutlinedInput.d.ts @@ -3,8 +3,8 @@ import { StandardProps } from '..'; import { InputBaseProps } from '../InputBase'; export interface OutlinedInputProps extends StandardProps { + label?: React.ReactNode; notched?: boolean; - labelWidth: number; } export type OutlinedInputClassKey = diff --git a/packages/material-ui/src/OutlinedInput/OutlinedInput.js b/packages/material-ui/src/OutlinedInput/OutlinedInput.js index 2fbdd2c058b5d1..6574f48bc2840a 100644 --- a/packages/material-ui/src/OutlinedInput/OutlinedInput.js +++ b/packages/material-ui/src/OutlinedInput/OutlinedInput.js @@ -108,7 +108,6 @@ const OutlinedInput = React.forwardRef(function OutlinedInput(props, ref) { fullWidth = false, inputComponent = 'input', label, - labelWidth = 0, multiline = false, notched, type = 'text', @@ -121,7 +120,6 @@ const OutlinedInput = React.forwardRef(function OutlinedInput(props, ref) { ; multiple?: boolean; native?: boolean; diff --git a/packages/material-ui/src/Select/Select.js b/packages/material-ui/src/Select/Select.js index df92490cff0efc..61c1076c7c55d6 100644 --- a/packages/material-ui/src/Select/Select.js +++ b/packages/material-ui/src/Select/Select.js @@ -34,7 +34,6 @@ const Select = React.forwardRef(function Select(props, ref) { renderValue, SelectDisplayProps, variant: variantProps = 'standard', - labelWidth = 0, ...other } = props; @@ -53,7 +52,7 @@ const Select = React.forwardRef(function Select(props, ref) { input || { standard: , - outlined: , + outlined: , filled: , }[variant]; @@ -142,16 +141,16 @@ Select.propTypes = { * When `native` is `true`, the attributes are applied on the `select` element. */ inputProps: PropTypes.object, + /** + * The label to be used on OutlinedInput. + * This prop is required when the `variant` prop is `outlined`. + */ + label: PropTypes.node, /** * The idea of an element that acts as an additional label. The Select will * be labelled by the additional label and the selected value. */ labelId: PropTypes.string, - /** - * The label width to be used on OutlinedInput. - * This prop is required when the `variant` prop is `outlined`. - */ - labelWidth: PropTypes.number, /** * Props applied to the [`Menu`](/api/menu/) element. */ diff --git a/packages/material-ui/src/TextField/TextField.js b/packages/material-ui/src/TextField/TextField.js index ab8d0d12de8a13..16d08c2ff0e094 100644 --- a/packages/material-ui/src/TextField/TextField.js +++ b/packages/material-ui/src/TextField/TextField.js @@ -93,16 +93,6 @@ const TextField = React.forwardRef(function TextField(props, ref) { ...other } = props; - const [labelWidth, setLabelWidth] = React.useState(0); - const labelRef = React.useRef(null); - React.useEffect(() => { - if (variant === 'outlined') { - // #StrictMode ready - const labelNode = ReactDOM.findDOMNode(labelRef.current); - setLabelWidth(labelNode != null ? labelNode.offsetWidth : 0); - } - }, [variant, required, label]); - if (process.env.NODE_ENV !== 'production') { if (select && !children) { console.error( @@ -119,7 +109,6 @@ const TextField = React.forwardRef(function TextField(props, ref) { } InputMore.label = `${label}${required ? ' *' : ''}`; - InputMore.labelWidth = labelWidth; } if (select) { // unset defaults from textbox inputs @@ -171,7 +160,7 @@ const TextField = React.forwardRef(function TextField(props, ref) { {...other} > {label && ( - + {label} )}