import React, { useRef } from "react"; import { Box, IconButton, TextField, Tooltip } from "@mui/material"; import FormatBoldIcon from "@mui/icons-material/FormatBold"; import FormatItalicIcon from "@mui/icons-material/FormatItalic"; import FormatUnderlinedIcon from "@mui/icons-material/FormatUnderlined"; import LinkIcon from "@mui/icons-material/Link"; import { wrapSelection } from "../cvBuilder"; import { useI18n } from "../i18n/I18nProvider"; // Lightweight rich text: a plain textarea plus a markdown toolbar. Storage stays plain text // (**bold**, *italic*, __underline__, [text](url)); the server renderer converts the same whitelist // to safe HTML. No RTE dependency, no HTML sanitisation surface. Bullet lists are the field itself — // one line per bullet — so there is no separate list button. export default function RichTextField({ value, onChange, label, placeholder, minRows = 2, ariaLabel, disabled = false, }: { value: string; onChange: (v: string) => void; label?: string; placeholder?: string; minRows?: number; ariaLabel?: string; disabled?: boolean; }) { const { t } = useI18n(); const ref = useRef(null); const apply = (before: string, after: string, placeholderText: string) => { const el = ref.current; if (!el) return; const { text, selStart, selEnd } = wrapSelection(value, el.selectionStart, el.selectionEnd, before, after, placeholderText); onChange(text); requestAnimationFrame(() => { el.focus(); el.setSelectionRange(selStart, selEnd); }); }; const btn = (title: string, icon: React.ReactNode, before: string, after: string, ph: string) => ( e.preventDefault()} onClick={() => apply(before, after, ph)}> {icon} ); return ( {btn(t("richTextBold"), , "**", "**", t("richTextBoldPlaceholder"))} {btn(t("richTextItalic"), , "*", "*", t("richTextItalicPlaceholder"))} {btn(t("richTextUnderline"), , "__", "__", t("richTextUnderlinePlaceholder"))} {btn(t("richTextLink"), , "[", "](https://)", t("richTextLinkPlaceholder"))} onChange(e.target.value)} slotProps={{ htmlInput: { "aria-label": ariaLabel ?? label } }} /> ); }