Skip to content

Commit

Permalink
[TextareaAutosize] Fix wrong height measurement (#37185)
Browse files Browse the repository at this point in the history
Co-authored-by: weipeng <[email protected]>
Co-authored-by: quanzheng <[email protected]>
  • Loading branch information
3 people authored Jun 29, 2023
1 parent 23f0b52 commit 2fa8d6c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
49 changes: 46 additions & 3 deletions packages/mui-base/src/TextareaAutosize/TextareaAutosize.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import {
} from 'test/utils';
import TextareaAutosize from '@mui/base/TextareaAutosize';

function getStyleValue(value: string) {
return parseInt(value, 10) || 0;
}

describe('<TextareaAutosize />', () => {
const { clock, render } = createRenderer();
const mount = createMount();
Expand Down Expand Up @@ -39,22 +43,24 @@ describe('<TextareaAutosize />', () => {
shadow: Element,
{
getComputedStyle,
scrollHeight,
scrollHeight: scrollHeightArg,
lineHeight: lineHeightArg,
}: {
getComputedStyle: Partial<CSSStyleDeclaration>;
scrollHeight?: number;
scrollHeight?: number | (() => number);
lineHeight?: number | (() => number);
},
) {
const lineHeight = typeof lineHeightArg === 'function' ? lineHeightArg : () => lineHeightArg;
const scrollHeight =
typeof scrollHeightArg === 'function' ? scrollHeightArg : () => scrollHeightArg;

getComputedStyleStub.set(input, getComputedStyle);

let index = 0;
stub(shadow, 'scrollHeight').get(() => {
index += 1;
return index % 2 === 1 ? scrollHeight : lineHeight();
return index % 2 === 1 ? scrollHeight() : lineHeight();
});
}

Expand Down Expand Up @@ -288,6 +294,43 @@ describe('<TextareaAutosize />', () => {
expect(input.style).to.have.property('overflow', 'hidden');
});

it('should compute the correct height if padding-right is greater than 0px', () => {
const paddingRight = 50;
const { container, forceUpdate } = render(<TextareaAutosize style={{ paddingRight }} />);
const input = container.querySelector<HTMLTextAreaElement>('textarea[aria-hidden=null]')!;
const shadow = container.querySelector('textarea[aria-hidden=true]')! as HTMLTextAreaElement;
const contentWidth = 100;
const lineHeight = 15;
const width = contentWidth + paddingRight;
setLayout(input, shadow, {
getComputedStyle: {
boxSizing: 'border-box',
width: `${width}px`,
},
scrollHeight: () => {
// assuming that the width of the word is 1px, and substract the width of the paddingRight
const lineNum = Math.ceil(
input.value.length / (width - getStyleValue(shadow.style.paddingRight)),
);
return lineNum * lineHeight;
},
lineHeight,
});

act(() => {
input.focus();
});
const activeElement = document.activeElement!;
// set the value of the input to be 1 larger than its content width
fireEvent.change(activeElement, {
target: { value: new Array(contentWidth + 1).fill('a').join('') },
});
forceUpdate();

// the input should be 2 lines
expect(input.style).to.have.property('height', `${lineHeight * 2}px`);
});

describe('warnings', () => {
it('warns if layout is unstable but not crash', () => {
const { container, forceUpdate } = render(<TextareaAutosize maxRows={3} />);
Expand Down
3 changes: 2 additions & 1 deletion packages/mui-base/src/TextareaAutosize/TextareaAutosize.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ const TextareaAutosize = React.forwardRef(function TextareaAutosize(
style={{
...styles.shadow,
...style,
padding: 0,
paddingTop: 0,
paddingBottom: 0,
}}
/>
</React.Fragment>
Expand Down

0 comments on commit 2fa8d6c

Please sign in to comment.