Skip to content

Autocomplete popup not rendering inside Shadow DOM (open mode) when using Ace Editor #2113

@gs-vkinti

Description

@gs-vkinti

We are using react-ace inside a Shadow DOM (mode: open) and noticed that the autocomplete popup is not being appended inside the shadow root. Instead, it is rendered directly in the main document.body, which causes styling and positioning issues in our application.

We have tried various approaches to resolve this but were unable to find a solution. It appears that the autocomplete UI is hardcoded to render outside the shadow root context.

Package Versions:

  • react-ace: ^14.0.1
  • ace-builds: ^1.42.0

Code Snippet:

import { memo, useCallback, useEffect, useRef, useState } from 'react'
import AceEditor from 'react-ace'

import 'ace-builds/src-noconflict/mode-css'
import 'ace-builds/src-noconflict/theme-xcode'
import 'ace-builds/src-noconflict/theme-chrome'
import 'ace-builds/src-noconflict/ext-language_tools'
import 'ace-builds/src-noconflict/snippets/css'
import Beautify from 'ace-builds/src-noconflict/ext-beautify'

export type Props = {
  disabled?: boolean
  value: string
  onChange: (value: string) => void
}

const CODE_EDITOR_OPTIONS = {
  useWorker: false,
  enableBasicAutocompletion: true,
  enableLiveAutocompletion: true,
  enableSnippets: true,
  showLineNumbers: false
}

const CodeEditor = (props: Props) => {
  const { value, onChange, disabled } = props
  const editorRef = useRef<AceEditor>(null)
  const [focused, setFocused] = useState(false)

  useEffect(() => {
    if (editorRef.current) {
      const { session } = editorRef.current.editor
      Beautify.beautify(session)
    }
  }, [])

  const handleChange = useCallback(
    (editorContent: string) => {
      if (!disabled && focused) {
        onChange(editorContent)
      }
    },
    [onChange, disabled, focused]
  )

  const handleFocus = useCallback(() => {
    setFocused(true)
  }, [])

  return (
    <AceEditor
      readOnly={disabled}
      ref={editorRef}
      mode='css'
      theme={disabled ? 'chrome' : 'xcode'}
      fontSize={12}
      lineHeight={16}
      width='calc(100% - 8px)'
      height='calc(100% - 8px)'
      showPrintMargin
      showGutter={false}
      highlightActiveLine
      focus={!disabled}
      onFocus={handleFocus}
      onChange={handleChange}
      value={value}
      setOptions={CODE_EDITOR_OPTIONS}
    />
  )
}

export default memo(CodeEditor)

If there's any known workaround or way to force the popup to render inside a specific container (e.g., shadowRoot), we’d appreciate any guidance.

Tagging for input: @securingsincity

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions