Search code examples
javascriptreactjshtml5-canvashtml2canvasgrommet

Grommet TextArea exports multiline text as a single line in the image


I want to export Grommet TextArea as an image. The following code works if there is just a single line of text. But if I adjust the TextArea component in a way to make the text fill multiple lines, this won't be exported in the output image.

This is how it looks (1 - is the page which contains the multiline TextArea I want to export, 2 - the exported TextArea, containing just a single line of text) enter image description here

Seems like I'm just missing something about HTML canvas. Or maybe there is some property in Grommet TextArea which helps with changing that behavior?

App.js:

import React, { Component } from "react";
import { TextArea } from "grommet";
import "./styles.css";
import { exportComponentAsPNG } from "react-component-export-image";

export default class App extends Component {
  constructor(props) {
    super(props);
    this.textRef = React.createRef();

    this.state = { text: "" };
  }

  render() {
    const { text } = this.state;
    return (
      <div className="App">
        <TextArea
          ref={this.textRef}
          value={text}
          onChange={(event) => this.setState({ text: event.target.value })}
        />
        <button onClick={() => exportComponentAsPNG(this.textRef)}>
          Click
        </button>
      </div>
    );
  }
}

index.js:

import ReactDOM from "react-dom";

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

index.html:

<div id="root"></div>

Solution

  • The issue came out from html2canvas library, which is a core of react-component-export-image. There are a couple of threads for this issue in the html2canvas community, including this one (the main one, I guess): https://github.com/niklasvh/html2canvas/issues/2008

    The best solution (which also helped in my case) is to use contenteditable div instead of textarea element