Passed
Push — feature/timeline-myfit-step ( 6743fb )
by Yonathan
05:13
created

resources/assets/js/components/WordCounter/WordCounter.tsx   A

Complexity

Total Complexity 3
Complexity/F 0

Size

Lines of Code 73
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 3
eloc 57
c 0
b 0
f 0
dl 0
loc 73
rs 10
mnd 3
bc 3
fnc 0
bpm 0
cpm 0
noi 0
1
import React, { useState, useEffect } from "react";
2
import { countNumberOfWords } from "./helpers";
3
4
export interface WordCounterProps {
5
  /** Id of textarea element */
6
  elementId: string;
7
  /** Maximum amount of words before passing the optimal range. The Progress Ring color correlates with this number. */
8
  maxWords: number;
9
  /** Minimum amount of words to reach the optimal range. The Progress Ring color correlates with this number. */
10
  minWords: number;
11
  /** Keep absolute value of max words - number of words */
12
  absoluteValue?: boolean;
13
  /** String before current number of words */
14
  beforeText?: string;
15
  /** String after counter when user is under the max */
16
  underMaxMessage?: string;
17
  /** String after counter when user is over the max */
18
  overMaxMessage?: string;
19
  /** List of clone data style attributes */
20
  dataAttributes?: { [key: string]: string };
21
}
22
23
const WordCounter: React.FunctionComponent<WordCounterProps> = ({
24
  elementId,
25
  minWords,
26
  maxWords,
27
  absoluteValue,
28
  beforeText,
29
  underMaxMessage,
30
  overMaxMessage,
31
  dataAttributes,
32
}): React.ReactElement => {
33
  const [numOfWords, setNumOfWords] = useState(0);
34
35
  useEffect((): (() => void) => {
36
    const element: HTMLTextAreaElement = document.getElementById(
37
      elementId,
38
    ) as HTMLTextAreaElement;
39
40
    setNumOfWords(countNumberOfWords(element.value));
41
42
    const handleInputChange = (e: Event): void => {
43
      const target = e.target as HTMLTextAreaElement;
44
      setNumOfWords(countNumberOfWords(target.value));
45
    };
46
47
    element.addEventListener("input", handleInputChange);
48
49
    return function cleanup(): void {
50
      element.removeEventListener("input", handleInputChange, false);
51
    };
52
  }, [elementId]);
53
54
  return (
55
    <span
56
      role="progressbar"
57
      aria-valuenow={numOfWords}
58
      aria-valuemin={minWords}
59
      aria-valuemax={maxWords}
60
    >
61
      {beforeText && <span>{beforeText} </span>}
62
      <span data-c-color={`${numOfWords <= maxWords ? "go" : "stop"}`}>
63
        {absoluteValue
64
          ? Math.abs(maxWords - numOfWords)
65
          : maxWords - numOfWords}
66
      </span>
67
      <span> {numOfWords <= maxWords ? underMaxMessage : overMaxMessage}</span>
68
    </span>
69
  );
70
};
71
72
export default WordCounter;
73