tinymce-react icon indicating copy to clipboard operation
tinymce-react copied to clipboard

dropdown is offside

Open heruwaspodov opened this issue 5 months ago • 2 comments

What is the current behavior?

Image

Please provide the steps to reproduce and if possible a minimal demo of the problem via codesandbox.io or similar.

import { useEffect, useState } from 'react';
import { useField } from 'formik';
import { Text } from '@chakra-ui/react';
import InputContainer from '@/components/Atoms/InputContainer';
import { useDebounce } from '@/hooks/debounce';
import type { InputContainerProps } from '@/components/Atoms/InputContainer';
import { Editor } from '@tinymce/tinymce-react';

interface TextareaFormProps extends Omit<InputContainerProps, 'children'> {
  placeholder?: string;
  descriptionRichText?: string;
  editorHeight?: string;
  debounceMs?: number | boolean;
}

export default function TextareaRichForm({
  name,
  id,
  label,
  descriptionRichText = 'Write your description here!',
  placeholder = '',
  description = '',
  isDisabled = false,
  isReadOnly = false,
  debounceMs = false,
  editorHeight = '22rem',
}: TextareaFormProps) {
  const [, { value }, { setValue }] = useField(name);
  const [internalValue, setInternalValue] = useState(value);

  useEffect(() => {
    setInternalValue(value);
  }, [value]);

  const debounceOnChange = useDebounce(
    (e: string) => {
      void setValue(e);
    },
    parseInt(debounceMs.toString()) ?? 400
  );

  const handleChange = (e: string) => {
    setInternalValue(e);
    if (debounceMs !== false) {
      debounceOnChange(e);
    } else {
      void setValue(e);
    }
  };

  return (
    <InputContainer
      id={id}
      name={name}
      label={label}
      description={description}
      isDisabled={isDisabled}
      isReadOnly={isReadOnly}
      position="relative"
    >
      {descriptionRichText && (
        <Text fontSize="12px" color="gray.500" mb={2}>
          {descriptionRichText}
        </Text>
      )}

      <Editor
        apiKey={
          process.env.NEXT_PUBLIC_SECRET_TINY_MCE 
        }
        value={internalValue ?? ''}
        onEditorChange={(newValue: string) => handleChange(newValue)}
        init={{
          dropdowns_container: 'body',
          toolbar_mode: 'wrap',
          height: editorHeight,
          width: '100%',
          menubar: false,
          statusbar: false,
          placeholder: placeholder,
          selector: 'textarea',
          font_size_input_default_unit: 'px',
          plugins: [
            'autolink',
            'code',
            'insertdatetime',
            // ...plugin lainnya kalau dibutuhkan
          ],
          formats: {
            parent: {
              block: 'section',
              classes: 'parent-wrapper',
              wrapper: true,
              merge_siblings: false,
            },
            child: {
              block: 'div',
              classes: 'child-wrapper',
              wrapper: true,
              merge_siblings: false,
            },
          },
          style_formats: [
            {
              title: 'Res Content',
              items: [
                {
                  title: 'Container',
                  format: 'parent',
                  wrapper: true,
                  merge_siblings: false,
                },
                {
                  title: 'Column',
                  format: 'child',
                  wrapper: true,
                  merge_siblings: false,
                },
              ],
            },
            {
              title: 'Headings',
              items: [
                { title: 'Heading 1', format: 'h1' },
                { title: 'Heading 2', format: 'h2' },
                { title: 'Heading 3', format: 'h3' },
                { title: 'Heading 4', format: 'h4' },
                { title: 'Heading 5', format: 'h5' },
                { title: 'Heading 6', format: 'h6' },
              ],
            },
            {
              title: 'Inline',
              items: [
                { title: 'Bold', format: 'bold' },
                { title: 'Italic', format: 'italic' },
                { title: 'Underline', format: 'underline' },
                { title: 'Strikethrough', format: 'strikethrough' },
                { title: 'Superscript', format: 'superscript' },
                { title: 'Subscript', format: 'subscript' },
                { title: 'Code', format: 'code' },
              ],
            },
            {
              title: 'Blocks',
              items: [
                { title: 'Blockquote', format: 'blockquote' },
                { title: 'Div', format: 'div' },
                { title: 'Pre', format: 'pre' },
              ],
            },
            {
              title: 'Align',
              items: [
                { title: 'Left', format: 'alignleft' },
                { title: 'Center', format: 'aligncenter' },
                { title: 'Right', format: 'alignright' },
                { title: 'Justify', format: 'alignjustify' },
              ],
            },
          ],
          toolbar:
            'undo redo | styles | fontfamily | fontsizeinput forecolor | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table accordion code',
          font_family_formats:
            'Andale Mono=andale mono,times; Arial=arial,helvetica,sans-serif; Arial Black=arial black,avant garde; Book Antiqua=book antiqua,palatino; Comic Sans MS=comic sans ms,sans-serif; Courier New=courier new,courier; Georgia=georgia,palatino; Helvetica=helvetica; Impact=impact,chicago; Scandia=scandia; Symbol=symbol; Tahoma=tahoma,arial,helvetica,sans-serif; Terminal=terminal,monaco; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms,geneva; Verdana=verdana,geneva; Webdings=webdings; Wingdings=wingdings,zapf dingbats',
          content_style: `
            body { 
              font-family: Scandia; 
              font-size: 14px; 
              background-color: transparent; 
            }
            .tox {
              overflow: visible !important;
            }
          `,
        }}
      />
    </InputContainer>
  );
}

What is the expected behavior?

why drop down is offside?

Which versions of TinyMCE, and which browser / OS are affected by this issue? Did this work in previous versions of TinyMCE or tinymce-react? "@tinymce/tinymce-react": "6.1.0"

heruwaspodov avatar Jul 31 '25 08:07 heruwaspodov

Removing or modifying the dropdowns_container option in the TinyMCE config should resolve this. Additionally, checking for any conflicting position, overflow, or z-index CSS on parent containers would be beneficial.

SHRAVANI0164 avatar Jul 31 '25 08:07 SHRAVANI0164

What is the version of tinymce? If possible, please provide a full replication case on something like codesandbox.io. You can also test your config on https://fiddle.tiny.cloud/.

tiny-ben-tran avatar Aug 03 '25 23:08 tiny-ben-tran