• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

alma-oss / spirit-design-system / 28939730421

08 Jul 2026 11:07AM UTC coverage: 86.38% (+1.8%) from 84.534%
28939730421

push

github

dlouhak
test(repo): update E2E tests

2710 of 3624 branches covered (74.78%)

Branch coverage included in aggregate %.

7412 of 8094 relevant lines covered (91.57%)

221.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.47
/packages/web-react/src/components/TextArea/TextArea.tsx
1
'use client';
2

3
import React, { type ForwardedRef, type RefObject, forwardRef, useEffect, useRef } from 'react';
170✔
4
import { warning } from '../../common/utilities';
170✔
5
import { type ForwardRefComponent, type SpiritTextAreaProps } from '../../types';
6
import { normalizeStringValue } from '../../utils';
170✔
7
import { useCharacterCounterState } from '../CharacterCounter';
170✔
8
import { TextFieldBase } from '../TextFieldBase';
170✔
9
import { TEXTAREA_MAX_SAFE_LENGTH } from './constants';
170✔
10
import { useAdjustHeight } from './useAdjustHeight';
170✔
11

12
const isCounterActive = (hasCounter: boolean | undefined, counterThreshold: number | undefined): boolean =>
170✔
13
  hasCounter === true || counterThreshold !== undefined;
31✔
14

15
const resolveCounterNativeMaxLength = (consumerMaxLength: number | undefined): number =>
170✔
16
  consumerMaxLength === undefined ? TEXTAREA_MAX_SAFE_LENGTH : consumerMaxLength;
×
17

18
const _TextArea = (props: SpiritTextAreaProps, ref: ForwardedRef<HTMLTextAreaElement>): JSX.Element => {
170✔
19
  const {
20
    onInput,
21
    isAutoResizing,
22
    autoResizingMaxHeight = 400,
31✔
23
    counterThreshold,
24
    hasCounter,
25
    onChange,
26
    value,
27
    defaultValue,
28
    helperText,
29
    isDisabled,
30
    id,
31
    ...restProps
32
  } = props;
31✔
33

34
  const elementReference = useRef(ref);
31✔
35
  const { adjustHeightOnAutoresize, onInput: onInputHandler } = useAdjustHeight({
31✔
36
    elementReference,
37
    onInput,
38
    isAutoResizing,
39
    maxHeight: autoResizingMaxHeight,
40
  });
41

42
  const normalizedValue = normalizeStringValue(value);
31✔
43
  const normalizedDefaultValue = normalizeStringValue(defaultValue);
31✔
44

45
  const { counterProps, handleChange } = useCharacterCounterState({
31✔
46
    value: normalizedValue,
47
    defaultValue: normalizedDefaultValue,
48
    counterThreshold,
49
    hasCounter,
50
    onChange,
51
  });
52

53
  const counterOn = isCounterActive(hasCounter, counterThreshold);
31✔
54
  const nativeMaxLength = counterOn ? resolveCounterNativeMaxLength(restProps.maxLength) : undefined;
31!
55
  const changeHandler = counterOn ? handleChange : onChange;
31!
56

57
  const didWarnMaxLengthLowerThanThresholdRef = useRef(false);
31✔
58
  useEffect(() => {
31✔
59
    if (
31!
60
      counterThreshold !== undefined &&
31!
61
      restProps.maxLength !== undefined &&
62
      restProps.maxLength < counterThreshold &&
63
      !didWarnMaxLengthLowerThanThresholdRef.current
64
    ) {
65
      didWarnMaxLengthLowerThanThresholdRef.current = true;
×
66
      warning(
×
67
        false,
68
        'TextArea: `maxLength` should be greater than or equal to `counterThreshold` to keep visible counter and hard input limit aligned.',
69
      );
70
    }
71
  }, [counterThreshold, restProps.maxLength]);
72

73
  return (
74
    <TextFieldBase
75
      id={id}
76
      isMultiline
77
      ref={elementReference as RefObject<HTMLTextAreaElement>}
78
      onInput={onInputHandler}
79
      onFocus={adjustHeightOnAutoresize}
80
      onChange={changeHandler}
81
      value={value}
82
      defaultValue={defaultValue}
83
      helperText={helperText}
84
      isDisabled={isDisabled}
85
      counterProps={counterProps}
86
      {...restProps}
87
      {...(nativeMaxLength !== undefined && { maxLength: nativeMaxLength })}
31!
88
    />
89
  );
90
};
91

92
const TextArea = forwardRef<HTMLTextAreaElement, SpiritTextAreaProps>(_TextArea) as ForwardRefComponent<
170✔
93
  HTMLTextAreaElement,
94
  SpiritTextAreaProps
95
>;
96

97
TextArea.spiritComponent = 'TextArea';
170✔
98
TextArea.displayName = 'TextArea';
170✔
99

100
export default TextArea;
170✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc