react-email-composer-widget-r18
v1.0.2
Published
React 18 compatible build of react-email-composer-widget.
Maintainers
Readme
React Email Composer Widget R18
Note: This is the React 18 compatible build of
react-email-composer-widget. It externalizes the modernreact/jsx-runtimeto guarantee compatibility with React 18 applications without causing JSX runtime conflicts.
🚀 Key Features
- Decoupled Architecture: Logic is separated from UI using an adapter pattern.
- Dual Mode Support:
- Simple Mode: Use built-in Frappe-compatible logic with simple props (
baseURL,token, etc.). - Advanced Mode: Provide your own full
apiAdapterandconfigfor complete control.
- Simple Mode: Use built-in Frappe-compatible logic with simple props (
- Built-in Rich Text Editor: Integrated Quill-hosted editor (no
primereactrequired). - Threading Support: Built-in support for
in_reply_toand email thread quoting. - Modular Components:
EmailComposerTrigger: Complete Button + Modal combo for instant integration.EmailComposerModal: Direct Modal for custom triggering logic.EmailComposer: The raw composer UI for custom layout needs.
- Attachment Management: Built-in file upload handling (integrated with your API).
- Template Support: Fetch and select from your own system templates.
- State Management Friendly: Supports external visibility control via global stores (e.g., Zustand).
🛠️ Installation
npm install react-email-composer-widget-r18Peer Dependencies
This widget requires the following dependencies to be installed in your project:
npm install quill@^2.0.2 @phosphor-icons/react📋 Usage
1. Simple Mode (Using Built-in Adapter)
The easiest way to integrate. The widget handles all API calls internally using the provided baseURL and token.
import { EmailComposerTrigger } from "react-email-composer-widget-r18";
import "react-email-composer-widget-r18/styles.css";
const MyComponent = () => {
return (
<EmailComposerTrigger
buttonLabel="Email"
baseURL="https://your-api.com"
token="your-auth-token"
currentUserFullName="John Doe"
defaultToEmails={["[email protected]"]}
referenceName="Milan Pethani" // Contact name (used for template references)
referenceDoctype="Contact"
activeLeadName="LEAD-001" // If a lead is active
activeLeadDoctype="CRM Lead"
activeTaskName="585" // Falls back to task when no active lead
activeTaskDoctype="CRM Task"
showNotification={(title, msg) => toast.success(msg)}
showWarning={(title, msg) => toast.warn(msg)}
showError={(title, msg) => toast.error(msg)}
/>
);
};2. Advanced Mode (Using External Adapters)
Provide your own full apiAdapter and config for maximum flexibility.
import { EmailComposerTrigger } from "react-email-composer-widget-r18";
import { myApiAdapter, myConfig } from "./my-adapters";
const MyComponent = () => {
return <EmailComposerTrigger buttonLabel="Send Email" apiAdapter={myApiAdapter} config={myConfig} />;
};3. Manual Modal Control (with Zustand)
import { EmailComposerTrigger } from "react-email-composer-widget-r18";
import { useEmailReplyStore } from "./my-store";
const MyComponent = () => {
const { isOpen, openModal, closeModal } = useEmailReplyStore();
return <EmailComposerTrigger baseURL="https://api.com" token="xyz" isOpen={isOpen} onOpen={openModal} onClose={closeModal} />;
};4. Trigger Variants (Plain Button)
import { EmailComposerTrigger } from "react-email-composer-widget-r18";
import "react-email-composer-widget-r18/styles.css";
<EmailComposerTrigger
buttonLabel="Email"
variant="plain"
btnClassName="contact-button"
baseURL={CONSTANTS.API_BASE_URL}
token={token}
currentUserFullName={userFullName}
defaultToEmails={[customerEmail]}
activeLeadName={activeLeadName}
activeLeadDoctype="CRM Lead"
showNotification={(title, msg) => toast.success(msg)}
showWarning={(title, msg) => toast.warn(msg)}
showError={(title, msg) => toast.error(msg)}
/>;5. Use Composer Only (No Trigger)
import { EmailComposer } from "react-email-composer-widget-r18";
const MyEmailDialog = ({ isOpen, onClose, ...composerProps }: any) => {
if (!isOpen) return null;
return (
<EmailComposer
{...composerProps}
onClose={onClose}
/>
);
};6. Use Built-in Modal (EmailComposerModal)
import { EmailComposerModal } from "react-email-composer-widget-r18";
<EmailComposerModal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
baseURL={CONSTANTS.API_BASE_URL}
token={token}
currentUserFullName={userFullName}
defaultToEmails={[customerEmail]}
activeLeadName={activeLeadName}
activeLeadDoctype="CRM Lead"
referenceName={referenceName}
replyData={replyData}
showNotification={(title, msg) => toast.success(msg)}
showWarning={(title, msg) => toast.warn(msg)}
showError={(title, msg) => toast.error(msg)}
/>⚙️ Properties (Props)
These props are available on EmailComposerTrigger, EmailComposerModal, and EmailComposer (unless specified).
| Prop | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| Core (Simple Mode) | | | |
| baseURL | string | - | Base URL for the internal API calls. |
| token | string | - | Authorization token for the API calls. |
| currentUserFullName | string | "" | The name of the sender. |
| defaultToEmails | string[] | [] | List of pre-filled recipient email addresses. |
| referenceName | string \| null | null | Primary document ID (e.g., "Milan Pethani"). Also used as the Contact reference name for template fetching. |
| referenceDoctype | string | - | Primary document type. |
| activeLeadName | string \| null | null | Context ID for the lead. When present, templates are fetched with CRM Lead + Contact references. |
| activeLeadDoctype | string | "CRM Lead" | Context doctype for the lead. |
| activeTaskName | string \| null | null | Context ID for the task (e.g., "585"). Used for template references when no active lead is present. |
| activeTaskDoctype | string | "CRM Task" | Context doctype for the task. |
| links | EmailComposerLink[] | [] | Related records to link in the communication log. |
| replyData | EmailReplyData \| null | null | Threading data for replies. |
| Advanced Mode | | | |
| apiAdapter | EmailWidgetApiAdapter | - | External API logic provider. Overrides simple mode. |
| config | EmailWidgetConfig | - | External configuration object. Overrides simple mode. |
| Components & Styling | | | |
| RichTextEditor | React.ComponentType<RichTextEditorProps> | - | Custom editor component (e.g., PrimeReact Editor). |
| buttonLabel | string | "Email" | Label for the trigger button. |
| className | string | "" | CSS class for the trigger button container. |
| modalSize | string | "800px" | Width of the modal (e.g., "800px", "50%"). |
| variant | "default" \| "plain" | "default" | Trigger button style (EmailComposerTrigger only). |
| btnClassName | string | "" | Optional class for the button (variant="plain") or container. |
| Control & Callbacks | | | |
| isOpen | boolean | - | Controls the visibility of the modal. |
| onOpen | () => void | - | Callback when the modal is opened. |
| onClose | () => void | - | Callback when requested to close. |
| onEmailSent | () => void | - | Callback after a successful email send. |
| showNotification | (title: string, msg: string) => void | - | Success toast handler. |
| showWarning | (title: string, msg: string) => void | - | Warning toast handler. |
| showError | (title: string, msg: string) => void | - | Error toast handler. |
Dynamic Email Template References
When the user opens the template selector, the widget automatically builds a references array and passes it to the getTemplates API:
| Scenario | References Sent |
| :--- | :--- |
| Active lead exists | [{"reference_doctype": "CRM Lead", "reference_name": "<leadName>"}, {"reference_doctype": "Contact", "reference_name": "<contactName>"}] |
| No active lead, task exists | [{"reference_doctype": "CRM Task", "reference_name": "<taskName>"}, {"reference_doctype": "Contact", "reference_name": "<contactName>"}] |
| Neither | No references sent (default behavior) |
API Example:
GET /api/method/crm_integration.crm_integration.api.email.get_email_templates?references=[{"reference_doctype":"CRM Lead","reference_name":"LEAD-001"},{"reference_doctype":"Contact","reference_name":"Milan Pethani"}]📄 License
MIT
