Skip to content

Commit 15806e0

Browse files
committed
feat: max visible rows option to autosizing textarea
1 parent 2dbc001 commit 15806e0

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

src/components/fields/TextArea/TextArea.tsx

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { useEvent } from '../../../_internal';
1515
export interface CubeTextAreaProps extends CubeTextInputBaseProps {
1616
/** Whether the textarea should change its size depends on content */
1717
autoSize?: boolean;
18+
/** Max number of visible rows when autoSize is `true` */
19+
maxVisibleRows?: number;
1820
/** The rows attribute in HTML is used to specify the number of visible text lines for the
1921
* control i.e. the number of rows to display. */
2022
rows?: number;
@@ -36,6 +38,7 @@ function TextArea(props: WithNullableValue<CubeTextAreaProps>, ref) {
3638
isReadOnly = false,
3739
isRequired = false,
3840
onChange,
41+
maxVisibleRows,
3942
rows = 3,
4043
...otherProps
4144
} = props;
@@ -50,19 +53,30 @@ function TextArea(props: WithNullableValue<CubeTextAreaProps>, ref) {
5053
let onHeightChange = useEvent(() => {
5154
if (autoSize && inputRef.current) {
5255
let input = inputRef.current;
53-
let prevAlignment = input.style.alignSelf;
54-
let computedStyle = getComputedStyle(input);
56+
const prevAlignment = input.style.alignSelf;
57+
const computedStyle = getComputedStyle(input);
58+
59+
const lineHeight = parseFloat(computedStyle.lineHeight);
60+
const paddingTop = parseFloat(computedStyle.paddingTop);
61+
const paddingBottom = parseFloat(computedStyle.paddingBottom);
62+
const borderTop = parseFloat(computedStyle.borderTopWidth);
63+
const borderBottom = parseFloat(computedStyle.borderBottomWidth);
64+
5565
input.style.alignSelf = 'start';
5666
input.style.height = 'auto';
57-
input.style.height = input.scrollHeight
58-
? `calc(${input.scrollHeight}px + (2 * var(--border-width)))`
59-
: `${
60-
parseFloat(computedStyle.paddingTop) +
61-
parseFloat(computedStyle.paddingBottom) +
62-
parseFloat(computedStyle.lineHeight) * (rows || 3) +
63-
2
64-
}px`;
67+
68+
const scrollHeight = input.scrollHeight;
69+
input.style.height = `calc(${scrollHeight}px + (2 * var(--border-width)))`;
70+
6571
input.style.alignSelf = prevAlignment;
72+
73+
const contentHeight =
74+
scrollHeight - paddingTop - paddingBottom - borderTop - borderBottom;
75+
const rowCount = Math.round(contentHeight / lineHeight);
76+
77+
if (autoSize && maxVisibleRows != null && rowCount > maxVisibleRows) {
78+
input.style.height = `${maxVisibleRows * lineHeight + paddingTop + paddingBottom}px`;
79+
}
6680
}
6781
});
6882

0 commit comments

Comments
 (0)