fix(forms): Safari focused none of them, and a board could not make a section
Two reports, one sentence between them: "sections have no function, because you cannot create more than one." `autofocus` does not work in Safari for anything inserted after the page has loaded, and every inline form here is inserted after the page has loaded — rename a project, add a section, name a group. In Safari they all opened with no cursor in them and what you typed went nowhere. That does not look like a bug. It looks like the feature does not work. `use:focusOnMount` replaces all seventeen. And the board had no way to add a section at all. The button lived only in the list view, which is the one place nobody looks for it: a column on a board *is* a section, so that is where you go to make one. Chasing this turned up a third. The task drawer's three fields save on blur, and closing the drawer *is* a blur — the input is being unmounted and the browser fires blur on the way out. If the task left the store in the same moment, `task` was already null and the handler threw `Cannot read properties of null`, stopping the page. It only became reproducible once focus actually worked. Fields are 16px on a touch device now, whatever the component asked for. Below 16px, iOS Safari zooms in when a field takes focus and does not zoom back out — so the whole interface is left too large and has to be pinched back by hand, once per field. The type scale tops out at 15px, so every input in the app did it. The sidebar's resize handle sat at `right: -3px`. An absolutely positioned child counts towards its container's scrollable overflow, and `overflow-y: auto` resolves the other axis to `auto` too — so those three pixels gave the whole menu a horizontal scrollbar on every desktop, always. The account name could do it as well: `overflow: hidden` with no `min-width: 0` cannot shrink, so the row grew instead of ellipsing. There is a WebKit pass in the suite now, over one test. The rest stays Chromium on purpose — a smoke test exists to catch a build that does not work, and three engines find the same bug three times — but focus is the exception, and it took a person using the app to find that out. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1da7ea64bf
commit
eaff890860
@@ -9,11 +9,36 @@
|
||||
* them — and it gives keyboard users the browser's own behaviour for free.
|
||||
*/
|
||||
import { app } from '$lib/stores.svelte.js';
|
||||
import { api } from '$lib/api.js';
|
||||
import { api, humanMessage } from '$lib/api.js';
|
||||
import { TASK, startDrag, carries, accept } from '$lib/dnd.js';
|
||||
import { focusOnMount } from '$lib/focus.js';
|
||||
import TaskRow from './TaskRow.svelte';
|
||||
|
||||
let { project, sections, canEdit } = $props();
|
||||
let { project, sections, canEdit, onsectionadded } = $props();
|
||||
|
||||
// --- adding a column ------------------------------------------------------------
|
||||
//
|
||||
// A column on a board *is* a section, so this is where somebody looks for one.
|
||||
// It was only in the list view, which meant a board — the view whose entire
|
||||
// shape is its sections — had no way to grow one. Reported as "sections have no
|
||||
// function: there is no way to create them", which from inside a board is
|
||||
// exactly true.
|
||||
|
||||
let adding = $state(false);
|
||||
let name = $state('');
|
||||
|
||||
async function addSection(event) {
|
||||
event.preventDefault();
|
||||
const trimmed = name.trim();
|
||||
if (!trimmed) return;
|
||||
adding = false;
|
||||
name = '';
|
||||
try {
|
||||
onsectionadded?.(await api.createSection(project.id, trimmed));
|
||||
} catch (e) {
|
||||
app.toast(humanMessage(e));
|
||||
}
|
||||
}
|
||||
|
||||
let draggingId = $state(null);
|
||||
let overColumn = $state(null);
|
||||
@@ -123,6 +148,31 @@
|
||||
</div>
|
||||
</section>
|
||||
{/each}
|
||||
|
||||
{#if canEdit}
|
||||
<section class="column adder">
|
||||
{#if adding}
|
||||
<form onsubmit={addSection}>
|
||||
<input
|
||||
bind:value={name}
|
||||
use:focusOnMount
|
||||
placeholder="Sektionens navn"
|
||||
aria-label="Ny sektion"
|
||||
onblur={() => !name.trim() && (adding = false)}
|
||||
onkeydown={(e) => e.key === 'Escape' && (adding = false)}
|
||||
/>
|
||||
</form>
|
||||
{:else}
|
||||
<button
|
||||
class="add"
|
||||
onclick={() => {
|
||||
adding = true;
|
||||
name = '';
|
||||
}}>+ Tilføj sektion</button
|
||||
>
|
||||
{/if}
|
||||
</section>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -137,6 +187,43 @@
|
||||
scroll-snap-type: x proximity;
|
||||
}
|
||||
|
||||
/* Narrower than a real column and without its background: it is an invitation
|
||||
at the end of the row, not a column with nothing in it. */
|
||||
.adder {
|
||||
background: none;
|
||||
border: 1px dashed var(--line);
|
||||
min-width: 180px;
|
||||
padding: var(--s2);
|
||||
}
|
||||
|
||||
.adder .add {
|
||||
width: 100%;
|
||||
padding: var(--s2);
|
||||
font-size: var(--text-sm);
|
||||
color: var(--ink-faint);
|
||||
border-radius: var(--radius);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.adder .add:hover {
|
||||
color: var(--ink);
|
||||
background: var(--surface);
|
||||
}
|
||||
|
||||
.adder input {
|
||||
width: 100%;
|
||||
padding: var(--s2);
|
||||
background: var(--surface-sunken);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius);
|
||||
font-size: var(--text-sm);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.adder input:focus {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.column {
|
||||
flex: 0 0 300px;
|
||||
max-width: 300px;
|
||||
|
||||
Reference in New Issue
Block a user