JSFiddle - React, Tailwind, and code Playground

HTML

<div id="canvas">An interactive application using a canvas<br/></div>
<input id="hidden-input" class="hidden" type="text" value=""/>

CSS

.hidden {
	position:	absolute;
	bottom:		0;
	left:		0;
	width:		10px;
	height:		10px;
	display:	block;
	font-size:	1;
	z-index:	-1;
	color:		transparent;
	background:	transparent;
	overflow:	hidden;
	border:		none;
	padding:	0;
	resize:		none;
	outline:	none;
	-webkit-user-select: text;
	user-select: text; /* Because for user-select:none, Safari won't allow input */
}

JavaScript

var isSafari = navigator.appVersion.search('Safari') != -1 && navigator.appVersion.search('Chrome') == -1 && navigator.appVersion.search('CrMo') == -1 && navigator.appVersion.search('CriOS') == -1;

var hiddenInput = $("#hidden-input");
var userInput = ""; 
var hiddenInputListener = function(text) {};

var focusHiddenArea = function() {
    // In order to ensure that the browser will fire clipboard events, we always need to have something selected
    hiddenInput.val(' ');
	hiddenInput.focus().select();
};

// We need the hidden input to constantly be selected in case there is a copy or paste event. It also recieves and dispatches input events
hiddenInput.on('input', function(e) {
    var value = hiddenInput.val();
    userInput += value;
    hiddenInputListener(userInput);
    
    // There is a bug (sometimes) with Safari and the input area can't be updated during
    // the input event, so we update the input area after the event is done being processed
    if (isSafari) {
        hiddenInput.focus();
        setTimeout(focusHiddenArea, 0);        
    } else {
        focusHiddenArea();
    }
});

// Set clipboard event listeners on the document. 
['cut', 'copy', 'paste'].forEach(function(event) {
    document.addEventListener(event, function(e) {
        console.log(event);
        focusHiddenArea();
        e.preventDefault();
    });
});

// Keep the hidden text area selected
$(document).mouseup(focusHiddenArea);

// This is an interactive web application using a canvas to render. We use the
// hidden input area to make sure that cut, copy, and paste events are always fired.
(function() {
    // Creates a new canvas element and appends it as a child
    // to the parent element, and returns the reference to
    // the newly created canvas element


    function createCanvas(parent, width, height) {
        canvas.node = document.createElement('canvas');
        canvas.context = canvas.node.getContext('2d');
        canvas.node.width = width || 300;
       ...