在IDE中的文本区域中反应自动完成功能(例如VS Code,Atom)

时间:2018-10-19 15:04:49

标签: javascript reactjs autocomplete

我尝试对自动完成功能进行编码,例如React中的gif。 因此,在编写文本时会出现建议。

但是到目前为止我能找到的所有软件包都可以使用

a)仅在输入/文本区域的开头(例如react-autosuggest

b)或需要一个触发字符(例如@或#)来打开(例如react-textarea-autocomplete

我会错过一些React限制吗?有提示/套餐吗?

Auto Complete

3 个答案:

答案 0 :(得分:0)

您可以尝试react-predictive-text

答案 1 :(得分:0)

在需要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}}

这里唯一的问题是,它要求输入中的最后两个字符为{{(或任何标记),以便出现自动完成框。我仍在玩光标移动,并以不同的方式将字符串切成薄片,因此,如果我编辑的模板不是最后,该框仍会弹出。

希望这会有所帮助。

答案 2 :(得分:0)

我们最终使用了出色的编辑器Slate.js

Mentions example可以轻松更改,以便任何字符(不仅是“ @”)都会触发建议。你去了:完美的自动建议。