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

CBIIT / crdc-datahub-ui / 15497092546

06 Jun 2025 06:19PM UTC coverage: 65.179% (+2.5%) from 62.708%
15497092546

push

github

web-flow
Merge pull request #726 from CBIIT/CRDCDH-2817

CRDCDH-2817 Vite/Vitest Migration & Upgrade dependencies

3529 of 3882 branches covered (90.91%)

Branch coverage included in aggregate %.

167 of 224 new or added lines in 82 files covered. (74.55%)

7620 existing lines in 126 files now uncovered.

22012 of 35304 relevant lines covered (62.35%)

101.98 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 React, { FC, useEffect, useId, useState, useRef } from "react";
1✔
2
import { Input, InputProps, Tooltip, TooltipProps, styled } from "@mui/material";
1✔
3
import useFormMode from "../../hooks/useFormMode";
1✔
4
import { updateInputValidity } from "../../utils";
1✔
5

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

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

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

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

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

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

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

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

139
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