summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2025-05-16 20:32:40 -0400
committerOwen Jacobson <owen@grimoire.ca>2025-05-16 20:32:40 -0400
commit96d363fd9290d43d2e6a11e2e5269fb8ccf6d65d (patch)
tree8c12e43ea31e3c99960bad009a68b2518bb47649
parent48b4e4ebc4558cf6790c0a9043c46f16b0cbc285 (diff)
parent630cbc2b70309ae5d2ece01861b9fe3983ab5278 (diff)
Merge remote-tracking branch 'codeberg/prop/text-input-no-quill'
> We can hand-write markdown for now, as per discussions. > > If we have buttons and shortcuts, we'd like them to insert actual markdown into the text stream, and then, as a separate concern, we'd like to render the markdown without changing the text stream (à la Discord). But we're doing none of that now, and it's too high a piece of fruit to pluck today.
-rw-r--r--ui/lib/components/MessageInput.svelte40
-rw-r--r--ui/styles/forms.css8
-rw-r--r--ui/styles/textarea.css32
3 files changed, 68 insertions, 12 deletions
diff --git a/ui/lib/components/MessageInput.svelte b/ui/lib/components/MessageInput.svelte
index 69a8298..cdb855e 100644
--- a/ui/lib/components/MessageInput.svelte
+++ b/ui/lib/components/MessageInput.svelte
@@ -4,27 +4,61 @@
let value = $state('');
let disabled = $state(false);
+ // Entering and removing text from the input area leaves a stray line break behind. This effect
+ // looks for that scenario and removes it, restoring the "empty" state (and bringing the
+ // placeholder back again in the process).
+ $effect(() => {
+ const trimmed = value.trim();
+ if (trimmed !== value && trimmed === '') {
+ value = trimmed;
+ }
+ });
+
async function onsubmit(event) {
event.preventDefault();
disabled = true;
try {
await sendMessage(value);
- event.target.reset();
+ event.target.closest('form')?.reset();
} finally {
disabled = false;
}
}
function onkeydown(event) {
+ if (disabled) {
+ event.preventDefault();
+ return;
+ }
+
let modifier = event.shiftKey || event.altKey || event.ctrlKey || event.metaKey;
if (!modifier && event.key === 'Enter') {
event.preventDefault();
- event.target.form.requestSubmit();
+ event.target.closest('form')?.requestSubmit();
+ }
+ }
+
+ function onpaste(event) {
+ if (disabled) {
+ event.preventDefault();
}
}
</script>
<form {onsubmit}>
- <textarea {onkeydown} bind:value {disabled} placeholder="Say something..."></textarea>
+ <textarea bind:value class="hidden" {disabled}></textarea>
+ <div
+ role="textbox"
+ tabindex="0"
+ contenteditable="plaintext-only"
+ class={{
+ textarea: true,
+ disabled
+ }}
+ bind:innerText={value}
+ {onkeydown}
+ {onpaste}
+ data-placeholder="Say something..."
+ ></div>
<button type="submit">&raquo;</button>
</form>
diff --git a/ui/styles/forms.css b/ui/styles/forms.css
index eb98743..98fd43e 100644
--- a/ui/styles/forms.css
+++ b/ui/styles/forms.css
@@ -22,3 +22,11 @@ form.form > button {
border: 1px solid var(--colour-input-border);
margin: 0.25rem;
}
+
+.disabled {
+ color: var(--light-text);
+}
+
+.hidden {
+ display: none;
+}
diff --git a/ui/styles/textarea.css b/ui/styles/textarea.css
index 4b8602c..d315bcf 100644
--- a/ui/styles/textarea.css
+++ b/ui/styles/textarea.css
@@ -4,28 +4,42 @@
flex-direction: row;
justify-content: flex-start;
align-items: stretch;
+}
- @media (width <= 640px) {
- margin: 0 0.5rem 1rem 0.5rem;
- }
+[data-placeholder]:empty:before {
+ content: attr(data-placeholder);
+ color: var(--light-text);
+ pointer-events: none;
+ display: block; /* For Firefox */
}
-.create-message textarea {
- padding: 0.5rem;
- border-radius: 0.5rem 0 0 0.5rem;
+.create-message .textarea {
+ padding: 1rem;
border: 1px solid var(--colour-input-border);
z-index: 1; /* Just to make the focus-active border go over the following button. */
flex-grow: 1;
background-color: var(--colour-input-bg);
color: var(--colour-input-text);
- font-family: 'FiraCode', monospace;
+ min-height: 1rem;
+ max-height: 10rem;
+ overflow-x: hidden;
+ overflow-y: auto;
+
+ @media (width <= 640px) {
+ border-radius: 0;
+ min-height: 2.5rem;
+ }
}
.create-message button {
- border-radius: 0 0.5rem 0.5rem 0;
border: 1px solid var(--colour-input-border);
background-color: var(--colour-input-bg);
color: var(--colour-input-text);
+ padding: 1rem;
+
+ @media (width <= 640px) {
+ border-radius: 0;
+ }
}
main {
@@ -38,7 +52,7 @@ main {
/* Workaround for iOS zooming in on the textarea when it gets focus. */
@media screen and (-webkit-min-device-pixel-ratio: 0) {
select,
- textarea,
+ .textarea,
input {
font-size: 16px;
}