Anisotropic
Anisotropic

Reputation: 645

Dynamic color of text input in react

I want text entry to be highlighted with different colors depending on the character entered.

My hunch is that it is possible to do this by adding <span> elements with the appropriate styling inside of a contenteditable div.

Is there a better way?

Upvotes: 1

Views: 1261

Answers (2)

M Wellman
M Wellman

Reputation: 73

Depending on the complexity, you can also consider using Ace Editor

import React, { useState } from "react";
import AceEditor from "react-ace-builds";
import "./yamlHighlightRules";
import "ace-builds/src-noconflict/theme-github";
import "ace-builds/src-noconflict/ace";
import "./styles.css";

export default function App() {
  const [text, setText] = useState("This is the most amazing initial text.");

  const handleChange = input => {
    setText(input);
  };

  return (
    <div className="App">
      <AceEditor
        mode="yaml"
        theme="github"
        name="editor"
        fontSize={15}
        showPrintMargin={true}
        showGutter={false}
        highlightActiveLine={false}
        value={text}
        onChange={handleChange}
        setOptions={{
          showLineNumbers: true,
          tabSize: 2,
          readOnly: false
        }}
        height={"600px"}
        width={"100%"}
      />
    </div>
  );
}

And then I edited an existing set of yaml highlighting rules, it's easier not starting from scratch.

import ace from "ace-builds/src-min-noconflict/ace";
import "ace-builds/src-noconflict/mode-text";

ace.define("ace/mode/yaml_highlight_rules", [], function(require, exports) {
  const oop = require("../lib/oop");
  const TextHighlightRules = require("./text_highlight_rules")
    .TextHighlightRules;

  const YamlHighlightRules = function() {
    this.$rules = {
      start: [
        {
          token: "highlight",
          regex: /amazing/
        }
      ]
    };
    this.normalizeRules();
  };

  oop.inherits(YamlHighlightRules, TextHighlightRules);

  exports.YamlHighlightRules = YamlHighlightRules;
});

The token is your css class. Just add the prefix ace_ to it. Then you define a regular expression to determine what gets that class.

.ace_highlight {
  background-color: yellow;
}

Here is a codesandbox where you can see it working. And here are the docs on defining your own modes.

Upvotes: 1

Khabir
Khabir

Reputation: 5854

Hi Please check this example. I used material-ui

import React, {useState} from 'react';
import Box from '@material-ui/core/Box';
import TextField from "@material-ui/core/TextField";

export default function BackgroundColor() {
    const [text, setText] = useState('');
    const [color, setColor] = useState('');

    function changeHandler(event) {
        setText(event.target.value);
        if(event.target.value.toLowerCase() === 'a'){
            setColor("primary.main");
        }
        else if(event.target.value.toLowerCase() === 'b'){
            setColor("secondary.main");
        }
        else if(event.target.value.toLowerCase() === 'c'){
            setColor("error.main");
        }
        else{
            setColor("info.main");
        }
    }
    return (
        <div>
            <TextField id="standard-basic" label="Standard" helperText="Type A or B or C" onChange={changeHandler} />
            <Box color={color}>
                {text}
            </Box>
        </div>
    );
}

Upvotes: 1

Related Questions