Bin
2025-12-16 9e0b2ba2c317b1a86212f24cbae3195ad1f3dbfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { type FC, type RefObject, useCallback, useRef } from "react";
import { cn } from "../../utils/bem";
import { IconSend } from "@humansignal/icons";
 
import { TextArea } from "../../common/TextArea/TextArea";
import { observer } from "mobx-react";
import { Button } from "@humansignal/ui";
 
export type CommentFormProps = {
  value?: string;
  onChange?: (value: string) => void;
  onSubmit?: (value: string) => void;
  onBlur?: (e: FocusEvent) => void;
  inline?: boolean;
  rows?: number;
  maxRows?: number;
  classifications?: object | null;
};
 
export const CommentFormBase: FC<CommentFormProps> = observer(
  ({ value = "", inline = true, onChange, onSubmit, onBlur, rows = 1, maxRows = 4, classifications }) => {
    const formRef = useRef<HTMLFormElement>(null);
    const actionRef = useRef<{ update?: (text?: string) => void; el?: RefObject<HTMLTextAreaElement> }>({});
 
    const submitHandler = useCallback(
      async (e?: any) => {
        e?.preventDefault?.();
 
        if (!formRef.current) return;
 
        const comment = (new FormData(formRef.current).get("comment") as string)?.trim();
 
        if (!comment && !classifications) return;
 
        onSubmit?.(comment);
      },
      [onSubmit],
    );
 
    const onInput = useCallback(
      (comment: string) => {
        onChange?.(comment || "");
      },
      [onChange],
    );
 
    return (
      <form ref={formRef as any} className={cn("comment-form").mod({ inline }).toClassName()} onSubmit={submitHandler}>
        <TextArea
          actionRef={actionRef}
          name="comment"
          placeholder="Add a comment"
          value={value}
          rows={rows}
          maxRows={maxRows}
          onChange={onChange}
          onInput={onInput}
          onSubmit={(newValue) => {
            if (!inline) return;
 
            newValue = newValue.trim();
            if (!newValue) return;
 
            onSubmit?.(newValue);
          }}
          onBlur={(e) => onBlur?.(e)}
        />
        <div className={cn("comment-form").elem("primary-action").toClassName()}>
          <Button type="submit" aria-label="Submit comment" variant="neutral" look="string">
            <IconSend />
          </Button>
        </div>
      </form>
    );
  },
);