Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[WC-2841] - Rich Text Fullscreen #1502

Merged
merged 15 commits into from
Apr 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/pluggableWidgets/rich-text-web/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Added

- We added fullscreen functionality in rich text editor.

## [4.4.0] - 2025-04-01

### Added
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/pluggableWidgets/rich-text-web/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@mendix/rich-text-web",
"widgetName": "RichText",
"version": "4.4.0",
"version": "4.5.0",
"description": "Rich inline or toolbar text editing",
"copyright": "© Mendix Technology BV 2025. All rights reserved.",
"repository": {
Expand Down
5 changes: 5 additions & 0 deletions packages/pluggableWidgets/rich-text-web/src/RichText.xml
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@
<caption>Content type</caption>
<description />
</property>
<property key="view" type="boolean" defaultValue="true">
<caption>View</caption>
<description />
</property>
<property key="remove" type="boolean" defaultValue="true">
<caption>Removal</caption>
<description />
Expand Down Expand Up @@ -260,6 +264,7 @@
<enumerationValue key="color">Color</enumerationValue>
<enumerationValue key="background">Background</enumerationValue>
<enumerationValue key="header">Header</enumerationValue>
<enumerationValue key="fullscreen">Full screen</enumerationValue>
<enumerationValue key="clean">Clean</enumerationValue>
</enumerationValues>
</property>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe("Rich Text", () => {
list: true,
remove: true,
header: true,
view: true,
advancedConfig: [],
readOnlyStyle: "text",
tabIndex: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,17 @@ exports[`Rich Text renders richtext widget with different config 1`] = `
title="Clear formatting"
/>
</span>
<span
class="ql-formats"
tabindex="-1"
>
<button
aria-label="Fullscreen"
class="icons icon-Expand"
tabindex="-1"
title="Fullscreen"
/>
</span>
</div>
<div
class="widget-rich-text-container"
Expand Down
24 changes: 12 additions & 12 deletions packages/pluggableWidgets/rich-text-web/src/assets/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export function IconLowerAlpha(): ReactElement {
/>
<path
id="Vector (Stroke)"
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M4.56001 14.868L4.56002 14.8679C4.48153 14.7828 4.44043 14.6761 4.44043 14.5576C4.44043 14.4391 4.48153 14.3323 4.56002 14.2472L4.56008 14.2472C4.64019 14.1604 4.74285 14.1129 4.85905 14.1129C4.97513 14.1129 5.0785 14.1592 5.15929 14.2462C5.23925 14.3307 5.28205 14.4377 5.28205 14.5576C5.28205 14.6779 5.23892 14.7853 5.15837 14.87C5.07701 14.9555 4.97385 15 4.85905 15C4.74459 15 4.64248 14.9547 4.56192 14.87L4.56001 14.868ZM5.03388 14.3761C4.98581 14.324 4.92753 14.298 4.85905 14.298C4.79203 14.298 4.73448 14.324 4.68641 14.3761C4.63978 14.4266 4.61647 14.4871 4.61647 14.5576C4.61647 14.628 4.63978 14.6885 4.68641 14.7391C4.73448 14.7896 4.79203 14.8149 4.85905 14.8149C4.92753 14.8149 4.98581 14.7896 5.03388 14.7391C5.08196 14.6885 5.106 14.628 5.106 14.5576C5.106 14.4871 5.08196 14.4266 5.03388 14.3761Z"
fill="#444444"
/>
Expand All @@ -27,8 +27,8 @@ export function IconLowerAlpha(): ReactElement {
/>
<path
id="Vector (Stroke)_2"
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M3.84808 14.757L3.76279 14.811C3.55959 14.9395 3.32378 15 3.06233 15C2.70245 15 2.3972 14.8753 2.16391 14.6174L2.16304 14.6164C1.93312 14.3584 1.82367 14.0283 1.82367 13.6428C1.82367 13.2195 1.94011 12.8608 2.18748 12.5862C2.43613 12.3087 2.76608 12.1757 3.15814 12.1757C3.37601 12.1757 3.57586 12.2182 3.75327 12.3088L3.85243 12.3594V13.2158L3.57526 13.0114C3.43717 12.9095 3.29497 12.8618 3.14508 12.8618C2.96527 12.8618 2.82647 12.9271 2.7146 13.0587M2.31545 12.7133C2.10496 12.9469 1.99971 13.2567 1.99971 13.6428C1.99971 13.9892 2.09697 14.2716 2.2915 14.4898C2.48747 14.7066 2.74442 14.8149 3.06233 14.8149C3.2975 14.8149 3.50074 14.7607 3.67203 14.6524V14.2952C3.61465 14.3407 3.55597 14.3786 3.49599 14.4089C3.3769 14.469 3.25267 14.499 3.1233 14.499C2.89249 14.499 2.70813 14.4196 2.57022 14.2609C2.43376 14.1022 2.36553 13.8855 2.36553 13.6107C2.36553 13.3315 2.43812 13.1063 2.58328 12.9354C2.7299 12.7629 2.91717 12.6767 3.14508 12.6767C3.26846 12.6767 3.38689 12.7028 3.50034 12.755C3.56042 12.7826 3.6191 12.8176 3.67639 12.8599V12.4753C3.52687 12.3989 3.35412 12.3608 3.15814 12.3608C2.80684 12.3608 2.52594 12.4783 2.31545 12.7133ZM3.84808 14.757V14.6524ZM3.84808 14.6524V13.9238ZM3.84808 13.9238L3.56603 14.1475ZM2.7146 13.0587C2.60426 13.1886 2.54158 13.3665 2.54158 13.6107C2.54158 13.8528 2.60105 14.0205 2.70051 14.1364C2.80055 14.2514 2.93509 14.3139 3.1233 14.3139C3.27561 14.3139 3.42195 14.2617 3.56603 14.1475"
fill="#444444"
/>
Expand All @@ -42,8 +42,8 @@ export function IconLowerAlpha(): ReactElement {
/>
<path
id="Vector (Stroke)_3"
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M4.55995 10.2399L4.55996 10.2399C4.48147 10.1548 4.44037 10.0481 4.44037 9.92953C4.44037 9.81101 4.48147 9.70428 4.55996 9.61917L4.56002 9.61911C4.64013 9.53233 4.74279 9.48482 4.85899 9.48482C4.97506 9.48482 5.07844 9.5311 5.15923 9.61812C5.23919 9.70266 5.28199 9.80965 5.28199 9.92953C5.28199 10.0499 5.23886 10.1572 5.15831 10.2419C5.07695 10.3274 4.97378 10.3719 4.85899 10.3719C4.74453 10.3719 4.64242 10.3266 4.56186 10.2419L4.55995 10.2399ZM5.03382 9.74802C4.98575 9.69594 4.92747 9.6699 4.85899 9.6699C4.79197 9.6699 4.73442 9.69594 4.68634 9.74802C4.63972 9.79857 4.61641 9.85907 4.61641 9.92953C4.61641 9.99999 4.63972 10.0605 4.68634 10.111C4.73442 10.1616 4.79197 10.1869 4.85899 10.1869C4.92747 10.1869 4.98575 10.1616 5.03382 10.111C5.0819 10.0605 5.10594 9.99999 5.10594 9.92953C5.10594 9.85907 5.0819 9.79857 5.03382 9.74802Z"
fill="#444444"
/>
Expand All @@ -54,8 +54,8 @@ export function IconLowerAlpha(): ReactElement {
/>
<path
id="Vector (Stroke)_4"
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M2.43225 9.79138C2.43632 9.79738 2.44051 9.80333 2.44483 9.80923C2.46014 9.83015 2.47698 9.85038 2.49535 9.86991C2.60684 9.98567 2.74788 10.0435 2.91846 10.0435C3.1186 10.0435 3.27508 9.96857 3.38791 9.81861C3.50208 9.66865 3.55917 9.46015 3.55917 9.19312C3.55917 8.96818 3.50611 8.79191 3.4 8.66431C3.29389 8.53671 3.15016 8.47291 2.96883 8.47291C2.78063 8.47291 2.62853 8.53606 2.51254 8.66235C2.51016 8.66495 2.50778 8.66758 2.50543 8.67023C2.49703 8.67959 2.48893 8.68912 2.48114 8.69883C2.45839 8.72715 2.43821 8.75695 2.42061 8.78822C2.3603 8.89535 2.33014 9.01979 2.33014 9.16155V9.44371C2.33014 9.57505 2.36418 9.69094 2.43225 9.79138ZM2.33014 8.60314H2.3382C2.35063 8.58262 2.3635 8.56288 2.37681 8.54393C2.37672 8.54405 2.37689 8.54382 2.37681 8.54393C2.41603 8.48812 2.45932 8.43878 2.50618 8.39659C2.65131 8.26594 2.83307 8.20062 3.05144 8.20062C3.31605 8.20062 3.5229 8.29138 3.672 8.47291C3.82244 8.65313 3.89765 8.89517 3.89765 9.19904C3.89765 9.5371 3.8137 9.80809 3.6458 10.012C3.4779 10.2146 3.24822 10.3158 2.95674 10.3158C2.77798 10.3158 2.62779 10.2672 2.50618 10.17C2.4423 10.1189 2.38631 10.0544 2.3382 9.97646H2.33014V10.2685H1.99971V7.27718H2.33014V8.60314ZM2.50618 8.16789V7.09209H1.82367V10.4536H2.50618V10.3895C2.63726 10.4638 2.78859 10.5009 2.95674 10.5009C3.29116 10.5009 3.57231 10.3824 3.77853 10.1336C3.98062 9.88816 4.0737 9.56994 4.0737 9.19904C4.0737 8.86291 3.98998 8.57356 3.80477 8.35138C3.61677 8.12283 3.3579 8.01553 3.05144 8.01553C2.84483 8.01553 2.66175 8.06659 2.50618 8.16789ZM2.61979 9.73898C2.69513 9.81684 2.79008 9.85847 2.91846 9.85847C3.07096 9.85847 3.17405 9.80451 3.24984 9.70379L3.25047 9.70295C3.33149 9.59654 3.38312 9.43429 3.38312 9.19312C3.38312 8.99811 3.33744 8.87027 3.26747 8.78613C3.19917 8.70401 3.10645 8.65799 2.96883 8.65799C2.81896 8.65799 2.71342 8.70726 2.63408 8.79656L2.63348 8.79724C2.55071 8.88948 2.50618 9.0062 2.50618 9.16155V9.44371C2.50618 9.56245 2.54326 9.65729 2.61979 9.73898Z"
fill="#444444"
/>
Expand All @@ -69,8 +69,8 @@ export function IconLowerAlpha(): ReactElement {
/>
<path
id="Vector (Stroke)_5"
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M4.55995 5.58999L4.55996 5.58997C4.48147 5.50487 4.44037 5.39814 4.44037 5.27962C4.44037 5.1611 4.48147 5.05437 4.55996 4.96926L4.56002 4.9692C4.64013 4.88242 4.74279 4.83491 4.85899 4.83491C4.97506 4.83491 5.07844 4.88119 5.15923 4.96821C5.23919 5.05275 5.28199 5.15974 5.28199 5.27962C5.28199 5.39996 5.23886 5.50731 5.15831 5.592C5.07695 5.67753 4.97378 5.72203 4.85899 5.72203C4.74453 5.72203 4.64242 5.67669 4.56186 5.592L4.55995 5.58999ZM5.03382 5.09811C4.98575 5.04603 4.92747 5.01999 4.85899 5.01999C4.79197 5.01999 4.73442 5.04603 4.68634 5.09811C4.63972 5.14866 4.61641 5.20916 4.61641 5.27962C4.61641 5.35008 4.63972 5.41058 4.68634 5.46113C4.73442 5.51168 4.79197 5.53695 4.85899 5.53695C4.92747 5.53695 4.98575 5.51168 5.03382 5.46113C5.0819 5.41058 5.10594 5.35008 5.10594 5.27962C5.10594 5.20916 5.0819 5.14866 5.03382 5.09811Z"
fill="#444444"
/>
Expand All @@ -87,8 +87,8 @@ export function IconLowerAlpha(): ReactElement {
/>
<path
id="Vector (Stroke)_6"
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M3.83909 5.76935H3.12989V5.67317C2.9824 5.77298 2.80854 5.82429 2.61131 5.82429C2.35791 5.82429 2.13616 5.7531 1.96875 5.58923L1.96801 5.5885C1.80295 5.42506 1.7254 5.20957 1.7254 4.96158C1.7254 4.70411 1.79879 4.47951 1.96171 4.31026C2.12087 4.1449 2.34609 4.05269 2.61315 4.01364C2.61316 4.01364 2.61313 4.01364 2.61315 4.01364L3.11841 3.93924C3.10481 3.85571 3.08064 3.80116 3.05417 3.76674C3.0194 3.72152 2.96141 3.68609 2.84648 3.68609C2.62195 3.68609 2.41928 3.76506 2.23287 3.93078L1.94315 4.18835V3.3032L2.02475 3.24867C2.275 3.0814 2.56103 3 2.87697 3C3.16875 3 3.41926 3.08166 3.59447 3.27659C3.76792 3.46955 3.83909 3.74209 3.83909 4.05959V5.76935ZM3.30593 4.09851L2.63744 4.19695C2.14678 4.26868 1.90145 4.52356 1.90145 4.96158C1.90145 5.16609 1.96387 5.33015 2.08871 5.45377C2.21501 5.5774 2.38921 5.63921 2.61131 5.63921C2.81878 5.63921 2.99164 5.57292 3.12989 5.44034C3.19284 5.37996 3.24862 5.30584 3.29722 5.21798H3.30593V5.58426H3.66304V4.05959C3.66304 3.47659 3.40102 3.18508 2.87697 3.18508C2.59099 3.18508 2.3384 3.25834 2.1192 3.40485V3.78946C2.17607 3.73889 2.23475 3.69497 2.29524 3.65771C2.46479 3.55324 2.64854 3.501 2.84648 3.501C3.15278 3.501 3.30593 3.70017 3.30593 4.09851ZM3.20252 5.03289C3.19145 5.05108 3.17949 5.06875 3.16664 5.08589C3.15565 5.10054 3.14402 5.11481 3.13173 5.12869C3.01705 5.25842 2.87116 5.32328 2.69406 5.32328C2.56486 5.32328 2.46106 5.28742 2.38267 5.21569C2.30574 5.14243 2.26727 5.04857 2.26727 4.9341C2.26727 4.77691 2.30936 4.66778 2.39356 4.60673C2.47776 4.54416 2.6026 4.50066 2.76809 4.47624L3.30593 4.39841V4.63192C3.30593 4.78596 3.27146 4.91962 3.20252 5.03289ZM3.12989 4.61071L2.79256 4.65953C2.79248 4.65954 2.79264 4.65952 2.79256 4.65953C2.63966 4.68212 2.54646 4.71975 2.49518 4.75787L2.49351 4.75911C2.47636 4.77154 2.44331 4.80787 2.44331 4.9341C2.44331 4.99845 2.46231 5.04124 2.49955 5.07726C2.53866 5.11243 2.5977 5.1382 2.69406 5.1382C2.82506 5.1382 2.92329 5.09262 3.00278 5.00269C3.08503 4.90973 3.12989 4.79091 3.12989 4.63192V4.61071Z"
fill="#444444"
/>
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { createElement, ReactElement, useCallback, useContext } from "react";
import { ToolbarButton } from "./ToolbarWrapper";
import { CustomToolbarProps } from "./customToolbars";
import { ACTION_DISPATCHER } from "../../utils/helpers";
import { SET_FULLSCREEN_ACTION } from "../../store/store";
import { EditorContext } from "../../store/EditorProvider";
import classNames from "classnames";

export function FullscreenButton({ quill }: CustomToolbarProps): ReactElement {
const handleClick = useCallback(() => {
quill?.emitter.emit(ACTION_DISPATCHER, { type: SET_FULLSCREEN_ACTION });
}, [quill]);

const { isFullscreen } = useContext(EditorContext);

return (
<ToolbarButton
className={classNames(`icons icon-Expand`, { "ql-active": isFullscreen })}
title={"Fullscreen"}
onClick={handleClick}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { FONT_LIST } from "../../utils/formats/fonts";
import { FONT_SIZE_LIST } from "../../utils/formats/fontsize";
import { ToolbarButton, ToolbarDropdown } from "./ToolbarWrapper";
import { RedoToolbar, UndoToolbar } from "./UndoRedo";

import { FullscreenButton } from "./Fullscreen";
type DefaultComponentProps = {
className?: string;
value?: string | any[];
Expand Down Expand Up @@ -152,7 +152,12 @@ export const TOOLBAR_MAPPING: toolbarMappingType = {
value: ["1", "2", "3", "4", "5", "6", false],
title: "Font header"
},
clean: { component: ToolbarButton, className: "ql-clean icons icon-Clear-formating", title: "Clear formatting" }
clean: { component: ToolbarButton, className: "ql-clean icons icon-Clear-formating", title: "Clear formatting" },
fullscreen: {
component: FullscreenButton,
title: "Fullscreen",
custom: true
}
};

type ToolbarGroupType = {
Expand All @@ -170,7 +175,8 @@ export const TOOLBAR_GROUP: ToolbarGroupType = {
embed: ["link", "image", "video", "formula"],
header: ["header"],
code: ["blockquote", "code", "codeBlock", "viewCode"],
remove: ["clean"]
remove: ["clean"],
view: ["fullscreen"]
};

export type toolbarContentType = {
Expand Down Expand Up @@ -222,6 +228,10 @@ export const DEFAULT_TOOLBAR: toolbarContentType[] = [
{
presetValue: 1,
children: TOOLBAR_GROUP.remove
},
{
presetValue: 2,
children: TOOLBAR_GROUP.view
}
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { MutableRefObject } from "react";
import { Range } from "quill/core/selection";
import Keyboard, { Context } from "quill/modules/keyboard";
import { Scope } from "parchment";
import { ACTION_DISPATCHER } from "../../utils/helpers";
import { SET_FULLSCREEN_ACTION } from "../../store/store";

/**
* give custom indent handler to use our custom "indent-left" and "indent-right" formats (formats/indent.ts)
*/
Expand Down Expand Up @@ -86,3 +89,11 @@ export function gotoStatusBarKeyboardHandler(this: Keyboard, _range: Range, cont
this.quill.blur();
}
}

/**
* Keyboard handler for exiting fullscreen mode when the Escape key is pressed
*/
export function exitFullscreenKeyboardHandler(this: Keyboard, _range: Range, _context: Context): boolean | void {
this.quill.emitter.emit(ACTION_DISPATCHER, { type: SET_FULLSCREEN_ACTION, value: false });
return true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
forwardRef,
Fragment,
MutableRefObject,
useContext,
useEffect,
useLayoutEffect,
useRef
Expand All @@ -14,14 +15,18 @@ import "../utils/customPluginRegisters";
import MxQuill from "../utils/MxQuill";
import {
enterKeyKeyboardHandler,
exitFullscreenKeyboardHandler,
getIndentHandler,
gotoStatusBarKeyboardHandler,
gotoToolbarKeyboardHandler
} from "./CustomToolbars/toolbarHandlers";
import { useEmbedModal } from "./CustomToolbars/useEmbedModal";
import Dialog from "./ModalDialog/Dialog";
import { RESIZE_MODULE_CONFIG } from "../utils/formats/resizeModuleConfig";
import { EDIT_DIALOG_EVENT } from "../utils/helpers";
import { ACTION_DISPATCHER } from "../utils/helpers";
import { EditorDispatchContext } from "../store/EditorProvider";
import { SET_FULLSCREEN_ACTION } from "../store/store";

export interface EditorProps {
defaultValue?: string;
onTextChange?: (...args: [delta: Delta, oldContent: Delta, source: EmitterSource]) => void;
Expand All @@ -40,6 +45,7 @@ const Editor = forwardRef((props: EditorProps, ref: MutableRefObject<Quill | nul
const modalRef = useRef<HTMLDivElement>(null);
const onTextChangeRef = useRef(onTextChange);
const onSelectionChangeRef = useRef(onSelectionChange);
const contextDispatch = useContext(EditorDispatchContext);

const {
showDialog,
Expand Down Expand Up @@ -98,6 +104,10 @@ const Editor = forwardRef((props: EditorProps, ref: MutableRefObject<Quill | nul
tab: {
key: "Tab",
handler: gotoStatusBarKeyboardHandler
},
escape: {
key: "Escape",
handler: exitFullscreenKeyboardHandler
}
}
},
Expand Down Expand Up @@ -125,7 +135,7 @@ const Editor = forwardRef((props: EditorProps, ref: MutableRefObject<Quill | nul
quill.on(Quill.events.SELECTION_CHANGE, (...arg) => {
onSelectionChangeRef.current?.(...arg);
});
quill.on(EDIT_DIALOG_EVENT, (...arg: any[]) => {
quill.on(ACTION_DISPATCHER, (...arg: any[]) => {
if (arg[0]) {
if (arg[0].href) {
customLinkHandler(arg[0]);
Expand All @@ -135,6 +145,12 @@ const Editor = forwardRef((props: EditorProps, ref: MutableRefObject<Quill | nul
} else {
customImageUploadHandler(arg[0]);
}
} else if (arg[0].type) {
if (arg[0].type === SET_FULLSCREEN_ACTION) {
if (contextDispatch) {
contextDispatch(arg[0]);
}
}
}
}
});
Expand Down
Loading