microsoft / tabster

Web Application Keyboard Navigation Tools

Home Page:https://tabster.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot enter whitespace with "tab" key into monaco editor since around tabster v4.7.3

chenxinyanc opened this issue · comments

I'm not sure from which version this issue starts to manifest, but tabster v4.7.0 definitely does not have such issue.

Reproduction (CodeSandbox): https://codesandbox.io/s/fluent-ui-v9-tabster-with-monaco-editor-ldwt64?file=/src/example.tsx

When I press "tab" key inside monaco editor, I expect to either

  • see 4 spaces appears in the editor,
  • or accept the item from the auto-completion dropdown.

but instead my focus gets moved to the auto-completion box, or the button.

Recording_20231031T171522

Is there any update to this bug? We've been continuously upgrading Fluent UI v9 but we are still keeping the version of tabster pinned right now.

This is not actually a bug, more like a side effect of the central focus management and a component with custom focus management. Tabster has uncontrolled areas, if you apply data-tabster='{"uncontrolled": {}}' on the editor container, Tabster will let the to handle focus inside. Like this

      <div style={{ width: "100%" }} data-tabster='{"uncontrolled": {}}'>
        <Editor className={styles.monacoContainer} defaultValue="test123" />
      </div>

https://codesandbox.io/p/sandbox/fluent-ui-v9-tabster-with-monaco-editor-forked-zlcqxd?file=%2Fsrc%2Fexample.tsx%3A37%2C1-40%2C1 — I have just quickly added a wrapper div for the sake of demonstration.

From the FluentUI perspective, we will expose that uncontrolled API so that you don't have to add custom data attributes yourself, but use the FUI API instead.

If you load monaco after a menu in fluent ui 9, @mshoho's method still does not work.

But you can work around this by putting FocusTrapZone around the editor:

import { FocusTrapZone } from '@fluentui/react';
import { useUncontrolledFocus } from '@fluentui/react-components';
...
const YourComponent = ()=>{
  const attr = useUncontrolledFocus();
  return(
    <FocusTrapZone
      style={{
        width: "100%",
        height: "100%",
      }}
      {...attr}
      isClickableOutsideFocusTrap
      forceFocusInsideTrap={false}
    >
       <Editor />
    </FocusTrapZone>
  );
};

@cf, could you create a codesandbox repro for it? Using extra FocusTrapZone is certainly not the best way of solving it. And latest version of Tabster supports a parameter for uncontrolled, you can do data-tabster='{"uncontrolled": { completely: true }}' to gain complete control over the area (that might have some corner cases, we'll describe the implications in the FUI uncontrolled API documentation soon). In any case, I would rather solve it in Tabster instead of using extra FocusTrapZone.