Emoji-only mirrored textarea
can-mirror shares the textarea’s current value. A normal input listener
filters local input before the mirrored value reaches other browsers.
Test it with another person
- Keep this page open in your normal window.
- Copy the private-window link, then paste it into a private or incognito window.
- Interact in either window and watch the other one update.
Copy the code
The live playground and this source use the same Vanilla HTML recipe.
Save this as index.html, or open it in the playground to
test and change it.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Emoji-only mirrored textarea</title>
<style>
:root {
color: #1c1c1c;
background: #f4efe5;
font-family: ui-sans-serif, system-ui, sans-serif;
}
* { box-sizing: border-box; }
body { display: grid; min-height: 100vh; margin: 0; padding: 1.5rem; place-items: center; }
main { width: min(34rem, 100%); }
h1 { margin: 0 0 0.35rem; font-size: clamp(2rem, 8vw, 3.5rem); line-height: 1; }
.intro { margin: 0 0 1.25rem; line-height: 1.5; }
textarea {
width: 100%;
min-height: 11rem;
resize: vertical;
padding: 1rem;
border: 2px solid #1c1c1c;
background: #fffdf8;
box-shadow: 5px 5px 0 #1c1c1c;
color: #1c1c1c;
font: 2rem/1.4 system-ui, sans-serif;
}
textarea:focus { outline: 3px solid #274b9e; outline-offset: 3px; }
.hint { margin: 0.85rem 0 0; color: #5a5650; font-size: 0.9rem; }
</style>
</head>
<body>
<main>
<h1>Emoji pad</h1>
<p class="intro">Type anything. Only emoji remain, and the value updates for everyone.</p>
<textarea
id="emoji-pad"
rows="4"
placeholder="emojis only..."
aria-label="Emoji-only shared textarea"
can-mirror
></textarea>
<p class="hint">Try the same room in another browser window.</p>
</main>
<script type="module">
import { playhtml } from "playhtml";
const emojiOnly = /\p{Extended_Pictographic}/gu;
const emojiPad = document.getElementById("emoji-pad");
emojiPad.addEventListener("input", () => {
const matches = emojiPad.value.match(emojiOnly);
emojiPad.value = matches ? matches.join("") : "";
});
await playhtml.init({ developmentMode: true });
</script>
</body>
</html> Filter normal DOM input
Section titled “Filter normal DOM input”The filter uses the browser’s Unicode emoji property:
const emojiOnly = /\p{Extended_Pictographic}/gu;
emojiPad.addEventListener("input", () => {
const matches = emojiPad.value.match(emojiOnly);
emojiPad.value = matches ? matches.join("") : "";
});
The application code changes a normal textarea. can-mirror observes the
resulting form state and shares it.
Test the filter
Section titled “Test the filter”Type letters and emoji in one window. Only the emoji should remain, and the other window should show the same filtered value.
See can-mirror for its DOM boundary and other supported form elements.