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

CBIIT / crdc-datahub-ui / 18789341118

24 Oct 2025 06:57PM UTC coverage: 78.178% (+15.5%) from 62.703%
18789341118

push

github

web-flow
Merge pull request #888 from CBIIT/3.4.0

3.4.0 Release

4977 of 5488 branches covered (90.69%)

Branch coverage included in aggregate %.

8210 of 9264 new or added lines in 257 files covered. (88.62%)

6307 existing lines in 120 files now uncovered.

30203 of 39512 relevant lines covered (76.44%)

213.36 hits per line

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

10.28
/src/components/Questionnaire/TableTextInput.tsx
1
import { Input, InputProps, Tooltip, TooltipProps, styled } from "@mui/material";
1✔
2
import React, { FC, useEffect, useId, useState, useRef } from "react";
1✔
3

4
import useFormMode from "../../hooks/useFormMode";
1✔
5
import { updateInputValidity } from "../../utils";
1✔
6

7
type Props = {
8
  /**
9
   * Pass in a regex pattern if you want this field to have custom validation checking
10
   */
11
  pattern?: string;
12
  patternValidityMessage?: string;
13
  maxLength?: number;
14
  filter?: (input: string) => string;
15
} & InputProps;
16

17
const StyledTooltip = styled((props: TooltipProps) => (
1✔
18
  <Tooltip classes={{ popper: props.className }} {...props} />
×
19
))(() => ({
1✔
UNCOV
20
  "& .MuiTooltip-tooltip": {
×
UNCOV
21
    color: "#C93F08",
×
UNCOV
22
    background: "#FFFFFF",
×
UNCOV
23
    border: "1px solid #2B528B",
×
UNCOV
24
  },
×
UNCOV
25
  "& .MuiTooltip-arrow": {
×
UNCOV
26
    color: "#2B528B",
×
UNCOV
27
  },
×
28
}));
1✔
29

30
const StyledInput = styled(Input)(() => ({
1✔
UNCOV
31
  "&.MuiInputBase-root": {
×
UNCOV
32
    "& .MuiInputBase-input": {
×
UNCOV
33
      padding: "0px",
×
UNCOV
34
      color: "#083A50",
×
UNCOV
35
      fontWeight: 400,
×
UNCOV
36
      fontSize: "16px",
×
UNCOV
37
      fontFamily: "'Nunito', 'Rubik', sans-serif",
×
UNCOV
38
      height: "20px",
×
UNCOV
39
      width: "100%",
×
UNCOV
40
    },
×
UNCOV
41
    "& ::placeholder": {
×
UNCOV
42
      color: "#87878C",
×
UNCOV
43
      fontWeight: 400,
×
UNCOV
44
      opacity: 1,
×
UNCOV
45
      height: "20px",
×
UNCOV
46
    },
×
UNCOV
47
    "& .MuiInputBase-input:read-only": {
×
UNCOV
48
      backgroundColor: "#E5EEF4",
×
UNCOV
49
      color: "#083A50",
×
UNCOV
50
      cursor: "not-allowed",
×
UNCOV
51
    },
×
UNCOV
52
  },
×
53
}));
1✔
54

55
/**
56
 * Generates a generic text input with a label and help text
57
 *
58
 * NOTE:
59
 * - We're using a custom wrapper for Material UI's OutlinedInput component
60
 *   instead of using the TextField component because of the forced
61
 *   floating label behavior of TextField.
62
 *
63
 * @param {Props} props
64
 * @returns {JSX.Element}
65
 */
66
const TableTextInput: FC<Props> = ({
1✔
UNCOV
67
  classes,
×
UNCOV
68
  value,
×
UNCOV
69
  patternValidityMessage,
×
UNCOV
70
  maxLength,
×
UNCOV
71
  pattern,
×
UNCOV
72
  readOnly,
×
UNCOV
73
  filter,
×
UNCOV
74
  ...rest
×
UNCOV
75
}) => {
×
76
  const id = useId();
×
77
  const { readOnlyInputs } = useFormMode();
×
78

79
  const [val, setVal] = useState(value);
×
80
  const regex = new RegExp(pattern);
×
81
  const inputRef = useRef<HTMLInputElement>(null);
×
82
  const [showError, setShowError] = useState<boolean>(false);
×
83
  useEffect(() => {
×
84
    const invalid = () => {
×
85
      setShowError(true);
×
UNCOV
86
    };
×
87

88
    inputRef.current?.addEventListener("invalid", invalid);
×
89
    return () => {
×
90
      inputRef.current?.removeEventListener("invalid", invalid);
×
UNCOV
91
    };
×
UNCOV
92
  }, [inputRef]);
×
93

94
  const onChange = (newVal) => {
×
95
    setShowError(false);
×
96
    if (typeof filter === "function") {
×
97
      newVal = filter(newVal);
×
UNCOV
98
    }
×
99
    if (typeof maxLength === "number" && newVal.length > maxLength) {
×
100
      newVal = newVal.slice(0, maxLength);
×
UNCOV
101
    }
×
102
    if (!newVal.match(regex)) {
×
103
      updateInputValidity(
×
UNCOV
104
        inputRef,
×
UNCOV
105
        patternValidityMessage || "Please enter input in the correct format"
×
UNCOV
106
      );
×
UNCOV
107
    } else {
×
108
      updateInputValidity(inputRef);
×
UNCOV
109
    }
×
110
    setVal(newVal);
×
UNCOV
111
  };
×
112

113
  useEffect(() => {
×
114
    onChange(value.toString().trim());
×
UNCOV
115
  }, [value]);
×
116
  return (
×
UNCOV
117
    <StyledTooltip
×
UNCOV
118
      title="Missing required field"
×
UNCOV
119
      arrow
×
UNCOV
120
      disableHoverListener
×
UNCOV
121
      disableFocusListener
×
UNCOV
122
      disableTouchListener
×
UNCOV
123
      open={showError}
×
124
    >
UNCOV
125
      <StyledInput
×
UNCOV
126
        inputRef={inputRef}
×
UNCOV
127
        sx={{ width: "100%", display: "flex", alignItems: "center" }}
×
UNCOV
128
        id={id}
×
UNCOV
129
        size="small"
×
UNCOV
130
        value={val}
×
131
        onChange={(e) => onChange(e.target.value)}
×
UNCOV
132
        {...rest}
×
UNCOV
133
        disableUnderline
×
UNCOV
134
        readOnly={readOnlyInputs || readOnly}
×
135
      />
UNCOV
136
    </StyledTooltip>
×
137
  );
UNCOV
138
};
×
139

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

© 2026 Coveralls, Inc