import type JoditEditor from "jodit-react"; import type { ComponentProps, ElementType, Ref } from "react"; type JoditEditorProps = ComponentProps; /** A field a template can reference; `path` is what the stored token carries. */ export type EditorMergeField = { /** Dotted path the backend resolves, e.g. `candidate.name`. */ path: string; /** Text shown on the chip and in the Insert field menu. */ label: string; /** Heading the field is listed under in the Insert field menu. */ group?: string; /** Example value, shown on the chip's hover title. */ sample?: string; /** Record the field belongs to (e.g. `employee`); carried for a field browser, not read by `Editor`. */ object?: string; /** What `object` is, shown beside its heading in a field browser. */ objectDescription?: string; /** What the field holds, shown in a field browser. */ description?: string; /** Longer illustrative value for a field browser; `sample` stays the chip title. */ example?: string; /** Where the value comes from (e.g. a module or API), shown in a field browser. */ source?: string; /** True when the field resolves to an image, not text. */ image?: boolean; }; /** How a token is written in the stored HTML. */ export type EditorTokenSyntax = { /** Opening delimiter, e.g. `${`; matched literally. */ open: string; /** Closing delimiter, e.g. `}`; matched literally. */ close: string; }; /** Imperative handle for toolbar buttons and `apiRef`; every method works on the live editor. */ export interface EditorApi { /** Inserts raw HTML at the last remembered caret position, or at the cursor if none was recorded. */ insertHTML(html: string): void; /** Inserts a chip for the merge field `path` (a raw token when `mergeFields` is unset); an unknown path renders as an unknown-field chip. */ insertField(path: string): void; /** Returns the trimmed text of the last remembered selection, or an empty string when there is none. */ getSelectionText(): string; /** Replaces every plain-text occurrence outside tokens and tags; returns the count. */ replaceAll(text: string, path: string): number; /** Counts plain-text occurrences of `text` outside tokens and tags that `replaceAll` would replace. */ countOccurrences(text: string): number; /** Moves keyboard focus into the editing area. */ focus(): void; } /** An extra button in the strip above the editor. */ export type EditorToolbarButton = { /** Unique key; also forms the button's test id `editor-button-`. */ id: string; /** Visible button text. */ label: string; /** Icon component reference (e.g. `Star`), not a rendered element; shown before the label. */ icon?: ElementType; /** Read through a ref — a new function each render never re-creates the editor. */ onClick: (api: EditorApi) => void; /** Disables this button; it is also disabled while the editor is loading or read-only. */ isDisabled?: boolean; }; /** Every visible string of the merge-field UI; omit a key to keep its English default. */ export type EditorLabels = Partial<{ /** Accessible name of the editing area when no visible `label` is given. */ editor: string; /** Placeholder and accessible name of the Insert field menu. */ insertField: string; /** Text shown in the Insert field menu when it has no options. */ noFields: string; /** Text of the Make dynamic toolbar button. */ makeDynamic: string; /** Title of the Make dynamic dialog. */ dynamicTitle: string; /** Label of the field picker in the Make dynamic dialog. */ dynamicField: string; /** Placeholder of the field picker in the Make dynamic dialog. */ dynamicFieldPlaceholder: string; /** Receives the number of matches and returns the line shown under the picker, e.g. "3 occurrences will be replaced". */ dynamicCount: (n: number) => string; /** Text of the confirm button in the Make dynamic dialog. */ dynamicReplace: string; /** Message shown in the Make dynamic dialog when no text was selected. */ dynamicNoSelection: string; /** Receives the comma-joined unmatched token paths and returns the validation message shown under the editor. */ unknownTokens: (list: string) => string; /** Text of the cancel button in the Make dynamic dialog. */ cancel: string; /** Caption above the selected text in the Make dynamic dialog. */ dynamicSelected: string; /** Accessible name of the toolbar strip above the editor. */ toolbar: string; /** Receives a field label and returns the accessible name of its chip, e.g. "Field: Name". */ fieldChip: (label: string) => string; }>; /** Props for the lazy-loaded Jodit wrapper; a `config.theme`/`config.popupRoot` you pass overrides this library's own dark-mode fix. */ export type EditorProps = Pick & { /** Jodit config; set sourceEditor "area" and beautifyHTML false to avoid cdnjs calls under CSP. */ config?: JoditEditorProps["config"]; /** `key` is dead (React reserves it, never reaches Jodit); `editorRef.current` stays null until the lazy chunk loads. */ editorRef?: JoditEditorProps["ref"]; /** Reserved by React and never reaches Jodit; has no effect, so do not rely on it to remount the editor. */ key?: string | number; /** Visible label above the editor; clicking it focuses the editor, and it becomes the editor's accessible name. */ label?: string; /** Shows a required asterisk and sets `aria-required`; does not validate. */ isRequired?: boolean; /** Hint under the editor; replaced by `errorMessage` while `error` is true. */ helperText?: string; /** Marks the editor invalid; `errorMessage` shows only while this is true. */ error?: boolean; /** Message shown instead of `helperText` while `error` is true. */ errorMessage?: string; /** Enables the Insert field menu, token chips and Make dynamic. */ mergeFields?: EditorMergeField[]; /** Token syntax in the stored HTML; default `{ open: "${", close: "}" }`. */ tokenSyntax?: EditorTokenSyntax; /** Shows the Make dynamic button; defaults to true when `mergeFields` is set. */ showMakeDynamic?: boolean; /** Extra buttons beside Insert field; handlers are read through refs. */ toolbarButtons?: EditorToolbarButton[]; /** Fires with the paths of tokens that match no merge field, when that set changes. */ onUnknownTokens?: (paths: string[]) => void; /** Imperative API, available after the lazy chunk loads (`onReady` fires then). */ apiRef?: Ref; /** Fires once the lazy Jodit chunk has loaded and the editor is ready, when `apiRef` becomes usable. */ onReady?: () => void; /** Overrides any subset of the UI strings; unset keys keep their English default. */ labels?: EditorLabels; /** Test id placed on the root wrapper. */ "data-testid"?: string; }; export {};