v3: code quality and visual consistency pass (refactored all forms across the app), fixed filename-related upload bug
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 47s

This commit is contained in:
khannurien
2026-06-26 22:20:07 +00:00
parent 26f5abfa4e
commit 73e0114bf7
30 changed files with 2369 additions and 2120 deletions

View File

@@ -0,0 +1,81 @@
import { useId } from "react";
import {
Controller,
type FieldValues,
type Path,
type RegisterOptions,
useFormContext,
} from "react-hook-form";
import { TextEditor, type TextEditorHandle } from "../TextEditor.tsx";
interface RichTextFieldProps<T extends FieldValues> {
name: Path<T>;
label?: string;
placeholder?: string;
rows?: number;
maxLength?: number;
autoResize?: boolean;
disabled?: boolean;
rules?: RegisterOptions<T, Path<T>>;
/** Forwarded to the underlying TextEditor so callers can focus it. */
editorRef?: React.Ref<TextEditorHandle>;
/** Ctrl/Cmd+Enter handler (e.g. submit the comment). */
onSubmit?: () => void;
}
/**
* Rich-text field: a `Controller`-wrapped {@link TextEditor} (mentions, emoji,
* image upload, char count) bound to react-hook-form via the surrounding
* `FormProvider`.
*/
export function RichTextField<T extends FieldValues>({
name,
label,
placeholder,
rows,
maxLength,
autoResize,
disabled,
rules,
editorRef,
onSubmit,
}: RichTextFieldProps<T>) {
const id = useId();
const { control, formState: { errors } } = useFormContext<T>();
const error = errors[name];
return (
<div className="form-field">
{label && (
<label className="form-label" htmlFor={id}>
{label}
</label>
)}
<Controller
name={name}
control={control}
rules={rules}
render={({ field }) => (
<TextEditor
ref={editorRef}
id={id}
value={field.value ?? ""}
onChange={field.onChange}
placeholder={placeholder}
rows={rows}
maxLength={maxLength}
autoResize={autoResize}
disabled={disabled}
onSubmit={onSubmit}
/>
)}
/>
{error?.message && (
<span className="form-hint form-hint--error">
{String(error.message)}
</span>
)}
</div>
);
}