Reputation: 1687
Hi I'm using the DetailsList and I want to be able to move my selection from column to column using tab. But I came across this issue on Github: https://github.com/microsoft/fluentui/issues/4690
Arrow keys needs to be used to navigate across the list but unfortunately I'm using a Monaco Editor in the list and the arrow key is blocked inside the Editor...
I would like to know if there is way to disable the List to set the TabIndex to -1
or
if Monaco can release the arrow key when the cursor is at the end of the text (Like a textbox).
Upvotes: 2
Views: 809
Reputation: 20785
I got something working following this rationale:
Knowing these then you can check if the caret is at the end of the last line and move the focus when the user press the right arrow key. I also added the code to check when the caret is at the very beginning and move the focus to the cell to the left.
This is the code I ended up with
import * as React from "react";
import "./styles.css";
import { DetailsList, IColumn } from "@fluentui/react";
import MonacoEditor from "react-monaco-editor";
export default function App() {
const columns: IColumn[] = [
{
key: "name",
minWidth: 50,
maxWidth: 50,
name: "Name",
onRender: (item, index) => (
<input id={`name-row-${index}`} value={item.name} />
)
},
{
key: "type",
minWidth: 200,
name: "Type",
onRender: (item, index) => {
return (
<MonacoEditor
editorDidMount={(editor, monaco) => {
editor.onKeyDown((event) => {
if (event.code === "ArrowRight") {
const { column, lineNumber } = editor.getPosition();
const model = editor.getModel();
if (lineNumber === model?.getLineCount()) {
const lastString = model?.getLineContent(lineNumber);
if (column > lastString?.length) {
const nextInput = document.getElementById(
`default-value-row-${index}`
);
(nextInput as HTMLInputElement).focus();
}
}
}
if (event.code === "ArrowLeft") {
const { column, lineNumber } = editor.getPosition();
if (lineNumber === 1 && column === 1) {
const previousInput = document.getElementById(
`name-row-${index}`
);
(previousInput as HTMLInputElement).focus();
}
}
});
}}
value={item.type}
/>
);
}
},
{
key: "defaultValue",
minWidth: 100,
name: "Default Value",
onRender: (item, index) => (
<input id={`default-value-row-${index}`} value={item.defaultValue} />
)
}
];
const items = [{ name: "name", type: "type", defaultValue: "name" }];
return <DetailsList columns={columns} items={items} />;
}
You can see it working in this codesandbox https://codesandbox.io/s/wild-smoke-vy61m?file=/src/App.tsx
monaco-editor seems to be something quite complex, probably you'll have to improve this code in order to support other interactions (ex: I don't know if this works when code is folded)
Upvotes: 2