diff --git a/packages/pluggableWidgets/rich-text-web/CHANGELOG.md b/packages/pluggableWidgets/rich-text-web/CHANGELOG.md
index 21a204b37b..5f2c0c59c6 100644
--- a/packages/pluggableWidgets/rich-text-web/CHANGELOG.md
+++ b/packages/pluggableWidgets/rich-text-web/CHANGELOG.md
@@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Added
+- We added support to add custom font families to Rich Text.
- We added table support to Rich Text, now it is possible to add tables and configure their layout.
### Fixed
diff --git a/packages/pluggableWidgets/rich-text-web/src/RichText.xml b/packages/pluggableWidgets/rich-text-web/src/RichText.xml
index 13ccde87c1..b7b4ad71ba 100644
--- a/packages/pluggableWidgets/rich-text-web/src/RichText.xml
+++ b/packages/pluggableWidgets/rich-text-web/src/RichText.xml
@@ -163,6 +163,22 @@
Enable spell checking
+
+ Custom fonts
+
+
+
+ Font name
+ Item
+ A title for this font combination (e.g., Arial).
+
+
+ Font style
+ Item
+ The full CSS font-family declaration that will be applied (e.g., arial, helvetica, sans-serif).
+
+
+
diff --git a/packages/pluggableWidgets/rich-text-web/src/__tests__/RichText.spec.tsx b/packages/pluggableWidgets/rich-text-web/src/__tests__/RichText.spec.tsx
index 5c61e1523c..985627b886 100644
--- a/packages/pluggableWidgets/rich-text-web/src/__tests__/RichText.spec.tsx
+++ b/packages/pluggableWidgets/rich-text-web/src/__tests__/RichText.spec.tsx
@@ -43,7 +43,8 @@ describe("Rich Text", () => {
maxHeightUnit: "none",
maxHeight: 0,
minHeight: 75,
- OverflowY: "auto"
+ OverflowY: "auto",
+ customFonts: []
};
});
diff --git a/packages/pluggableWidgets/rich-text-web/src/components/Editor.tsx b/packages/pluggableWidgets/rich-text-web/src/components/Editor.tsx
index 959bc33ec5..7a893cd380 100644
--- a/packages/pluggableWidgets/rich-text-web/src/components/Editor.tsx
+++ b/packages/pluggableWidgets/rich-text-web/src/components/Editor.tsx
@@ -11,9 +11,15 @@ import {
useLayoutEffect,
useRef
} from "react";
-import QuillTableBetter from "../utils/formats/quill-table-better/quill-table-better";
-import "../utils/formats/quill-table-better/assets/css/quill-table-better.scss";
+import { CustomFontsType } from "../../typings/RichTextProps";
+import { EditorDispatchContext } from "../store/EditorProvider";
+import { SET_FULLSCREEN_ACTION } from "../store/store";
import "../utils/customPluginRegisters";
+import { FontStyleAttributor, formatCustomFonts } from "../utils/formats/fonts";
+import "../utils/formats/quill-table-better/assets/css/quill-table-better.scss";
+import QuillTableBetter from "../utils/formats/quill-table-better/quill-table-better";
+import { RESIZE_MODULE_CONFIG } from "../utils/formats/resizeModuleConfig";
+import { ACTION_DISPATCHER } from "../utils/helpers";
import MxQuill from "../utils/MxQuill";
import {
enterKeyKeyboardHandler,
@@ -24,12 +30,9 @@ import {
} from "./CustomToolbars/toolbarHandlers";
import { useEmbedModal } from "./CustomToolbars/useEmbedModal";
import Dialog from "./ModalDialog/Dialog";
-import { RESIZE_MODULE_CONFIG } from "../utils/formats/resizeModuleConfig";
-import { ACTION_DISPATCHER } from "../utils/helpers";
-import { EditorDispatchContext } from "../store/EditorProvider";
-import { SET_FULLSCREEN_ACTION } from "../store/store";
export interface EditorProps {
+ customFonts: CustomFontsType[];
defaultValue?: string;
onTextChange?: (...args: [delta: Delta, oldContent: Delta, source: EmitterSource]) => void;
onSelectionChange?: (...args: [range: Range, oldRange: Range, source: EmitterSource]) => void;
@@ -42,6 +45,9 @@ export interface EditorProps {
// Editor is an uncontrolled React component
const Editor = forwardRef((props: EditorProps, ref: MutableRefObject) => {
+ const fonts = formatCustomFonts(props.customFonts);
+ const FontStyle = new FontStyleAttributor(fonts);
+ Quill.register(FontStyle, true);
const { theme, defaultValue, style, className, toolbarId, onTextChange, onSelectionChange, readOnly } = props;
const containerRef = useRef(null);
const modalRef = useRef(null);
diff --git a/packages/pluggableWidgets/rich-text-web/src/components/EditorWrapper.tsx b/packages/pluggableWidgets/rich-text-web/src/components/EditorWrapper.tsx
index 2152a9610a..c8977ea3b9 100644
--- a/packages/pluggableWidgets/rich-text-web/src/components/EditorWrapper.tsx
+++ b/packages/pluggableWidgets/rich-text-web/src/components/EditorWrapper.tsx
@@ -185,6 +185,7 @@ function EditorWrapperInner(props: EditorWrapperProps): ReactElement {
preset={preset}
quill={quillRef.current}
toolbarContent={toolbarPreset}
+ customFonts={props.customFonts}
/>
{enableStatusBar && (
diff --git a/packages/pluggableWidgets/rich-text-web/src/components/Toolbar.tsx b/packages/pluggableWidgets/rich-text-web/src/components/Toolbar.tsx
index d3ba938665..cc21aec182 100644
--- a/packages/pluggableWidgets/rich-text-web/src/components/Toolbar.tsx
+++ b/packages/pluggableWidgets/rich-text-web/src/components/Toolbar.tsx
@@ -1,15 +1,17 @@
import classNames from "classnames";
import Quill from "quill";
import { CSSProperties, ReactElement, RefObject, createElement, forwardRef } from "react";
-import { PresetEnum } from "typings/RichTextProps";
+import { CustomFontsType, PresetEnum } from "../../typings/RichTextProps";
+import { formatCustomFonts } from "../utils/formats/fonts";
import { FormatsContainer, ToolbarContext, presetToNumberConverter } from "./CustomToolbars/ToolbarWrapper";
import { TOOLBAR_MAPPING, toolbarContentType } from "./CustomToolbars/constants";
export interface ToolbarProps {
+ customFonts?: CustomFontsType[];
id: string;
preset: PresetEnum;
- style?: CSSProperties;
quill?: Quill | null;
+ style?: CSSProperties;
toolbarContent: toolbarContentType[];
}
@@ -65,6 +67,16 @@ const Toolbar = forwardRef((props: ToolbarProps, ref: RefObject)
{toolbarGroup.children.map((toolbar, idx) => {
const currentToolbar = TOOLBAR_MAPPING[toolbar];
const key = `toolbar_${id}_${index}_${idx}`;
+ let value = currentToolbar.value;
+
+ if (currentToolbar.title === "Font type") {
+ type FontListType = Array<{ value: string; description: string; style: string }>;
+ value = [
+ ...(currentToolbar.value as FontListType),
+ ...formatCustomFonts(props.customFonts ?? [])
+ ].sort((a, b) => (a.value ?? "").localeCompare(b.value ?? ""));
+ }
+
return currentToolbar.custom
? createElement(currentToolbar.component, {
key,
@@ -77,7 +89,7 @@ const Toolbar = forwardRef((props: ToolbarProps, ref: RefObject)
key,
className: classNames(currentToolbar.className),
presetValue: currentToolbar.presetValue,
- value: currentToolbar.value,
+ value,
title: currentToolbar.title
},
currentToolbar.children && createElement(currentToolbar.children)
diff --git a/packages/pluggableWidgets/rich-text-web/src/utils/formats/fonts.ts b/packages/pluggableWidgets/rich-text-web/src/utils/formats/fonts.ts
index 3a520cd6ba..6b3e445bc0 100644
--- a/packages/pluggableWidgets/rich-text-web/src/utils/formats/fonts.ts
+++ b/packages/pluggableWidgets/rich-text-web/src/utils/formats/fonts.ts
@@ -1,5 +1,5 @@
import { Scope, StyleAttributor } from "parchment";
-import Quill from "quill";
+import { CustomFontsType } from "../../../typings/RichTextProps";
import "./fonts.scss";
export const FONT_LIST = [
@@ -22,13 +22,21 @@ const config = {
scope: Scope.INLINE
};
-class FontStyleAttributor extends StyleAttributor {
+export class FontStyleAttributor extends StyleAttributor {
+ private fontList: typeof FONT_LIST = [];
+
+ constructor(fontList: typeof FONT_LIST) {
+ super("font", "font-family", config);
+ this.fontList = fontList;
+ }
+
add(node: HTMLElement, value: any): boolean {
if (!this.canAdd(node, value)) {
return false;
}
node.dataset.value = value;
- const style = FONT_LIST.find(x => x.value === value)?.style;
+ const allFonts = [...FONT_LIST, ...this.fontList];
+ const style = allFonts.find(x => x.value === value)?.style;
if (style) {
super.add(node, style);
} else {
@@ -46,6 +54,10 @@ class FontStyleAttributor extends StyleAttributor {
}
}
-const FontStyle = new FontStyleAttributor("font", "font-family", config);
-
-Quill.register(FontStyle, true);
+export function formatCustomFonts(fonts: CustomFontsType[] = []): typeof FONT_LIST {
+ return fonts.map(font => ({
+ value: font.fontName?.toLowerCase().split(" ").join("-") ?? "",
+ description: font.fontName ?? "",
+ style: font.fontStyle ?? ""
+ }));
+}
diff --git a/packages/pluggableWidgets/rich-text-web/typings/RichTextProps.d.ts b/packages/pluggableWidgets/rich-text-web/typings/RichTextProps.d.ts
index 0380ae4691..7aa3da5485 100644
--- a/packages/pluggableWidgets/rich-text-web/typings/RichTextProps.d.ts
+++ b/packages/pluggableWidgets/rich-text-web/typings/RichTextProps.d.ts
@@ -23,6 +23,11 @@ export type OverflowYEnum = "auto" | "scroll" | "hidden";
export type OnChangeTypeEnum = "onLeave" | "onDataChange";
+export interface CustomFontsType {
+ fontName: string;
+ fontStyle: string;
+}
+
export type ToolbarConfigEnum = "basic" | "advanced";
export type CtItemTypeEnum = "separator" | "undo" | "redo" | "bold" | "italic" | "underline" | "strike" | "superScript" | "subScript" | "orderedList" | "bulletList" | "lowerAlphaList" | "checkList" | "minIndent" | "plusIndent" | "direction" | "link" | "image" | "video" | "formula" | "blockquote" | "code" | "codeBlock" | "viewCode" | "align" | "centerAlign" | "rightAlign" | "font" | "size" | "color" | "background" | "header" | "fullscreen" | "clean" | "tableBetter";
@@ -31,6 +36,11 @@ export interface AdvancedConfigType {
ctItemType: CtItemTypeEnum;
}
+export interface CustomFontsPreviewType {
+ fontName: string;
+ fontStyle: string;
+}
+
export interface AdvancedConfigPreviewType {
ctItemType: CtItemTypeEnum;
}
@@ -59,6 +69,7 @@ export interface RichTextContainerProps {
onLoad?: ActionValue;
onChangeType: OnChangeTypeEnum;
spellCheck: boolean;
+ customFonts: CustomFontsType[];
toolbarConfig: ToolbarConfigEnum;
history: boolean;
fontStyle: boolean;
@@ -100,6 +111,7 @@ export interface RichTextPreviewProps {
onLoad: {} | null;
onChangeType: OnChangeTypeEnum;
spellCheck: boolean;
+ customFonts: CustomFontsPreviewType[];
toolbarConfig: ToolbarConfigEnum;
history: boolean;
fontStyle: boolean;