tinymce / tinymce-react

Offical TinyMCE React component
MIT License
938 stars 151 forks source link

how to update content_style after editor is loaded. #416

Closed SymntxHomendra51 closed 8 months ago

SymntxHomendra51 commented 1 year ago

I'm trying to display an html page in editor with CSS. The page data is changeable through API. i can pass CSS on first render but when page change i cant change the CSS also. How to do this with react tinymce?

exalate-issue-sync[bot] commented 1 year ago

Ref: INT-3070

yacodes commented 1 year ago

@SymntxHomendra51 I've reproduced the issue. We will discuss the issue and look into auto-updating the editor after its parameters were updated. Right now you can use a workaround like this:

import { v4 as uuid } from "uuid";

const EditorContainer = React.memo(() => {
  const [key, setKey] = React.useState(uuid());

  // Re-render the whole editor when styles were changed
  const onStylesChange = () => setKey(uuid());

  return (
    <Editor key={key} init={init} />
  );
});
tiny-james commented 1 year ago

We've long resisted re-rending the editor on init parameter changes.

The reasons are:

  1. The init object can change by accident, for example things like function references can change every render.
  2. To avoid accidental updates all updates would have to be implemented on a per-setting basis which over-complicates the implementation
  3. It is very easy to workaround with the key change trick.

I have suggested to the editor team that with the new editor.options.set('option', value) API they could support some options being changed at runtime by firing an event which the plugins (and the core) could hook but so far that has not been implemented. If they do implement that then I would try to pass through updates to settings using that API, though it would be done in a generic way not on a per setting basis.

kolserdav commented 1 year ago

I have the same problem, my content styles depend on the theme of the application, but when I change the theme, the editor styles are not re-rendered. Is there any way to force content_style to change during the life cycle?

/* eslint-disable no-unused-vars */
import React, { useRef } from 'react';
import { Editor } from '@tinymce/tinymce-react';
import { TINY_API_KEY } from '../../utils/constants';
import { Theme } from '../../Theme';

export type EditorOnChange = (e: {
  readonly type: string;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  readonly target: any;
  readonly isDefaultPrevented: () => boolean;
  readonly preventDefault: () => void;
  readonly isPropagationStopped: () => boolean;
  readonly stopPropagation: () => void;
  readonly isImmediatePropagationStopped: () => boolean;
  readonly stopImmediatePropagation: () => void;
}) => void;

export default function App({
  value,
  onChange,
  theme,
}: {
  value: string;
  onChange: EditorOnChange;
  theme: Theme;
}) {
  const editorRef = useRef(null);

  return (
    <Editor
      onInit={(evt, editor) => {
        if (editorRef.current) {
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          editorRef.current = editor as any;
        }
      }}
      value={value}
      onChange={onChange}
      apiKey={TINY_API_KEY}
      init={{
        language: 'ru',
        height: 500,
        skin: 'oxide-dark',
        menubar: false,
        plugins: [
          'advlist',
          'advcode',
          'advtable',
          'autolink',
          'checklist',
          'export',
          'lists',
          'link',
          'image',
          'charmap',
          'preview',
          'anchor',
          'searchreplace',
          'visualblocks',
          'powerpaste',
          'fullscreen',
          'formatpainter',
          'insertdatetime',
          'media',
          'table',
          'wordcount',
          'image',
        ],
        toolbar:
          'undo redo | casechange blocks | bold italic backcolor | ' +
          'alignleft aligncenter alignright alignjustify | ' +
          'bullist numlist checklist outdent indent | table image |  removeformat',
        content_style: `body { font-family:Helvetica,Arial,sans-serif; font-size:14px; background-color: ${theme.paper}; color: ${theme.text}}`,
      }}
    />
  );
}
tiny-james commented 1 year ago

Just make the key of the editor dependent on the theme name. When the key of the <Editor../> changes it will force a re-init of the editor.

kolserdav commented 1 year ago

Just make the key of the editor dependent on the theme name. When the key of the <Editor../> changes it will force a re-init of the editor.

This is what I needed, thanks!

vinayak-vayuz commented 11 months ago

Just make the key of the editor dependent on the theme name. When the key of the <Editor../> changes it will force a re-init of the editor.

This is what I needed, thanks!

Can you provide the updated code? @kolserdav