froala / react-froala-wysiwyg

React component for Froala WYSIWYG HTML Rich Text Editor.
https://froala.com/wysiwyg-editor
561 stars 130 forks source link

Problem with custom buttons #316

Open staubt opened 2 years ago

staubt commented 2 years ago

Hello

I tried to customize some buttons but if I try to import Froalaeditor from 'froala-editor' I get TS7016: Could not find a declaration file for module 'froala-editor'. 'C:/project/U/aris-yukon/apps/mining/mining-plugin/node_modules/froala-editor/js/froala_editor.min.js' implicitly has an 'any' type.

I added "froala-editor": "4.0.8", "react-froala-wysiwyg": "4.0.8" to the dependencies in package.json. I use the editor in a react functional component with

import FroalaEditor from 'react-froala-wysiwyg';
<FroalaEditor config=.... and it works as expected.

Only registring icons and commands (FroalaEditor.DefineIcon, FroalaEditor.RegisterCommand) is not possible because the failing import. Is there a new way to define these things in react-froala-wysiwyg?

Thanks Thomas

Rajesh-kumar-r commented 2 years ago

Try this i used this long time ago it could help you. i just updated it to latest version. https://codesandbox.io/s/froala-editor-custom-button-mfd190

SimonGolms commented 3 months ago

I wanted to leave my code snippet here, as I have successfully integrated the mui icons with this approach

import {
  FormatBold,
  FormatClear,
  FormatColorFill,
  FormatColorText,
  FormatItalic,
  FormatListBulleted,
  FormatListNumbered,
  FormatStrikethrough,
  FormatUnderlined,
  Redo,
  Undo,
} from "@mui/icons-material";
import type { SxProps, Theme } from "@mui/material";
import { Box } from "@mui/material";
import FroalaEditor from "froala-editor";
import { renderToString } from "react-dom/server";
import FroalaEditorComponent from "react-froala-wysiwyg";
import "froala-editor/css/froala_editor.pkgd.min.css";
import "froala-editor/css/froala_style.min.css";
import "froala-editor/js/plugins/colors.min.js";
import "froala-editor/js/plugins/lists.min.js";
import "froala-editor/js/plugins/paragraph_format.min.js";

/**
 * WORKAROUND: The React Component from Froala Editor does not support rendering of custom icons out of the box.
 *
 * FroalaEditor.DefineIconTemplate is used to define a new icon template. This is necessary because
 * the default icons provided by Froala Editor might not match the design language of Material-UI (MUI).
 * By defining a new icon template, we can use a MUI icon in the Froala Editor toolbar.
 * The SVG markup is obtained by rendering the MUI icon to a string using ReactDOMServer.renderToString.
 *
 * FroalaEditor.DefineIcon is used to associate an icon in the Froala Editor toolbar with an icon template.
 * By setting the template to one of the templates we defined earlier, we can replace the default Froala Editor icons with MUI icons.
 */
FroalaEditor.DefineIconTemplate("mui-FormatBold", renderToString(<FormatBold />));
FroalaEditor.DefineIcon("bold", { template: "mui-FormatBold" });

FroalaEditor.DefineIconTemplate("mui-FormatItalic", renderToString(<FormatItalic />));
FroalaEditor.DefineIcon("italic", { template: "mui-FormatItalic" });

FroalaEditor.DefineIconTemplate("mui-FormatUnderlined", renderToString(<FormatUnderlined />));
FroalaEditor.DefineIcon("underline", { template: "mui-FormatUnderlined" });

FroalaEditor.DefineIconTemplate("mui-FormatStrikethrough", renderToString(<FormatStrikethrough />));
FroalaEditor.DefineIcon("strikeThrough", { template: "mui-FormatStrikethrough" });

FroalaEditor.DefineIconTemplate("mui-FormatListNumbered", renderToString(<FormatListNumbered />));
FroalaEditor.DefineIcon("formatOL", { template: "mui-FormatListNumbered" });

FroalaEditor.DefineIconTemplate("mui-FormatListBulleted", renderToString(<FormatListBulleted />));
FroalaEditor.DefineIcon("formatUL", { template: "mui-FormatListBulleted" });

FroalaEditor.DefineIconTemplate("mui-textColor", renderToString(<FormatColorText />));
FroalaEditor.DefineIcon("textColor", { template: "mui-textColor" });

FroalaEditor.DefineIconTemplate("mui-FormatColorFill", renderToString(<FormatColorFill />));
FroalaEditor.DefineIcon("backgroundColor", { template: "mui-FormatColorFill" });

FroalaEditor.DefineIconTemplate("mui-FormatClear", renderToString(<FormatClear />));
FroalaEditor.DefineIcon("clearFormatting", { template: "mui-FormatClear" });

FroalaEditor.DefineIconTemplate("mui-Undo", renderToString(<Undo />));
FroalaEditor.DefineIcon("undo", { template: "mui-Undo" });

FroalaEditor.DefineIconTemplate("mui-Redo", renderToString(<Redo />));
FroalaEditor.DefineIcon("redo", { template: "mui-Redo" });

const FROALA_EDITOR_COMPONENT_CONFIG = {
  attribution: false,
  listAdvancedTypes: true,
  paragraphFormatSelection: true,
  toolbarBottom: false,
  toolbarButtons: [
    ["paragraphFormat", "bold", "italic", "underline", "strikeThrough", "formatOL", "formatUL"],
    ["textColor", "backgroundColor", "clearFormatting"],
    ["undo", "redo"],
  ],
};

const sx: SxProps<Theme> = {
  ".fr-box": {
    "*, >.fr-wrapper": {
      borderColor: "secondary.light",
      borderWidth: 2,
    },
    ".fr-second-toolbar": {
      borderBottomLeftRadius: ({ spacing }) => spacing(0.5),
      borderBottomRightRadius: ({ spacing }) => spacing(0.5),
    },
    ".fr-toolbar": {
      ".fr-newline": {
        backgroundColor: "divider",
      },
      borderTopLeftRadius: ({ spacing }) => spacing(0.5),
      borderTopRightRadius: ({ spacing }) => spacing(0.5),
    },
    ".fr-wrapper": {
      ".fr-view": {
        "*:first-of-type": {
          marginBlockStart: 0,
        },
        padding: ({ spacing }) => spacing(1.5, 2),
      },
      borderBottom: "unset",
      height: ({ spacing }) => spacing(50),
      maxHeight: ({ spacing }) => spacing(50),
      overflow: "auto",
    },
  },
};

export const FroalaTextEditor = ({ model = "", onModelChange = () => undefined }: FroalaTextEditorProps) => {
  return (
    <Box sx={sx}>
      <FroalaEditorComponent
        config={FROALA_EDITOR_COMPONENT_CONFIG}
        model={model}
        tag="textarea"
        onModelChange={onModelChange}
      />
    </Box>
  );
};

type FroalaTextEditorProps = {
  model?: string;
  onModelChange?: (event: string) => void;
};

Good luck on your further journey with froala.