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: 1rem; 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: 8rem;
resize: vertical;
padding: 0.85rem 0.95rem;
border: 1.5px solid #1c1c1c;
border-radius: 6px;
background: #f4efe5;
box-shadow: 2px 2px 0 #1c1c1c;
color: #1c1c1c;
font: 1.75rem/1.35 ui-sans-serif, system-ui, sans-serif;
}
textarea:focus { outline: 3px solid #274b9e; outline-offset: 3px; }
.hint {
margin: 0.75rem 0 0;
color: #6a6761;
font: 0.74rem/1.5 ui-monospace, monospace;
text-align: center;
}
</style>
</head>
<body>
<main>
<textarea
id="emoji-pad"
rows="4"
placeholder="emojis only..."
aria-label="Emoji-only shared textarea"
can-mirror
></textarea>
<p class="hint">Type anything. Only emojis stick, and the filtered value mirrors to everyone.</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.