簡體   English   中英

在 IDE 中的文本區域中反應自動完成(例如 VS Code、Atom)

[英]React autocomplete in a textarea like in an IDE (e.g. VS Code, Atom)

我嘗試編寫一個自動完成功能,如 React 中的 gif。 因此,在編寫文本時會出現建議。

但是,到目前為止我能找到的所有軟件包都有效

a) 僅在輸入/文本區域的開頭(例如react-autosuggest

b) 或需要一個觸發字符(如 @ 或 #)來打開(例如react-textarea-autocomplete

我是否錯過了一些 React 限制? 任何提示/包?

自動完成

我們最終使用了出色的編輯器Slate.js

提及示例可以輕松更改,以便任何字符(不僅僅是“@”)觸發建議。 你去:完美的自動建議。

你可以試試react-predictive-text

我實際上在需要 textarea 實現方面遇到了同樣的問題,但我可以幫助自動完成觸發行為。

我們有一個類似於{{person.name}}的模板變量的實現,它被解析為任何實際值。

關於僅在第一個單詞上觸發的自動完成,您可以通過對所需功能進行一些修改來解決這個問題。

例如我需要的功能看起來像這樣。 (不是一個完整的工作示例,而是所有重要的部分)


    const templateVars = Object.values(TemplateVarMap);

    const variables = templateVars.map((templateVar) => {
        return {
            name: templateVar,
        };
    });

    //This func, onChange, and onSuggestionSelected/Highlight are the important
    //parts. We essentially grab the full input string, then slice down to our 
    //autocomplete token and do the same for the search so it filters as you type
    const getSuggestions = (value) => {
        const sliceIndex = value
            .trim()
            .toLowerCase()
            .lastIndexOf('{{'); //activate autocomplete token
        const inputValue = value
            .trim()
            .toLowerCase()
            .slice(sliceIndex + 2); //+2 to skip over the {{
        const inputLength = inputValue.length;
        //show every template variable option once '{{' is typed, then filter as 
        //they continue to type
        return inputLength === 0
            ? variables
            : variables.filter(
                (variable) => variable.name.toLowerCase().slice(0, inputValue.length) === inputValue
            );
    };

    const getSuggestionValue = (suggestion) => suggestion.name;

    const renderSuggestion = (suggestion) => <div>{suggestion.name}</div>;

    onSuggestionsFetchRequested = ({ value }) => {
        this.setState({
            suggestions: getSuggestions(value),
        });
    };

    onSuggestionsClearRequested = () => {
        this.setState({
            suggestions: [],
        });
    };


    onChange = (event, { newValue }) => {
        //onChange fires on highlight / selection and tries to wipe
        //the entire input to the suggested variable, so if our value
        //is exactly a template variable, don't wipe it 
        if (templateVars.includes(newValue)) {
            return;
        }
        this.setState({
            value: newValue,
        });
    };

    //These both need to do similar things because one is a click selection
    //and the other is selection using the arrow keys + enter, we are essentially
    //manually going through the input and only putting the variable into the
    //string instead of replacing it outright.
    onSuggestionHighlighted = ({ suggestion }) => {
        if (!suggestion) {
            return;
        }
        const { value } = this.state;
        const sliceIndex = value.lastIndexOf('{{') + 2;
        const currentVal = value.slice(0, sliceIndex);
        const newValue = currentVal.concat(suggestion.name) + '}}';
        this.setState({ value: newValue });
    };

    onSuggestionSelected = (event, { suggestionValue }) => {
        const { value } = this.state;
        const sliceIndex = value.lastIndexOf('{{') + 2;
        const currentVal = value.slice(0, sliceIndex);
        const newValue = currentVal.concat(suggestionValue) + '}}';
        this.setState({ value: newValue });
    };

    const inputProps = {
        value: this.state.value,
        onChange: this.onChange,
    };

    render() {
        return (
            <Autosuggest
                suggestions={this.state.suggestions}
                onSuggestionSelected={this.onSubjectSuggestionSelected}
                onSuggestionHighlighted={this.onSubjectSuggestionHighlighted}
                onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
                onSuggestionsClearRequested={this.onSuggestionsClearRequested}
                getSuggestionValue={getSuggestionValue}
                renderSuggestion={renderSuggestion}
                inputProps={inputProps}
            />
        )
   }

這讓我可以輸入類似This is some text with a {{並彈出自動完成功能,選擇一個選項后,它應該轉到This is some text with a {{person.name}}

這里唯一的問題是它要求輸入中的最后兩個字符是{{ (或任何您的標記)才能出現自動完成框。 我仍然在玩光標移動並以不同的方式切割字符串,所以如果我編輯一個不在末尾的模板,框仍然會彈出。

希望這會有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM