A poll's options are thumb-sized, and floating buttons don't fail what scrolls under them
On touch a poll's options are at least 44px tall with 8px between them, and a long option wraps. The phone sweep ignores a probe that lands on a fixed floating control (the round New post button covers the card under it by design) instead of failing the target for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
dd38002682
commit
765220059d
2 files changed
+15
-4
No files matched your search
@@ -615,16 +615,16 @@
|
||||
|
||||
@if (status.Poll is { } poll)
|
||||
{
|
||||
<div class="flex flex-col gap-1 text-xs" data-poll>
|
||||
<div class="flex flex-col gap-1 pointer-coarse:gap-2 text-xs" data-poll>
|
||||
@if (CanVote(poll))
|
||||
{
|
||||
@for (var i = 0; i < poll.Options.Count; i++)
|
||||
{
|
||||
var index = i;
|
||||
<label class="flex items-center gap-2 rounded-md neo-inset neo-2xs px-2 py-1 cursor-pointer">
|
||||
<label class="flex items-center gap-2 rounded-md neo-inset neo-2xs px-2 py-1 pointer-coarse:min-h-11 cursor-pointer">
|
||||
<input type="@(poll.Multiple ? "checkbox" : "radio")" class="@(poll.Multiple ? "checkbox checkbox-xs" : "radio radio-xs")"
|
||||
name="@($"poll-{poll.Id}")" checked="@pollChoices.Contains(index)" @onchange="() => ToggleChoice(poll, index)" />
|
||||
<span>@poll.Options[index].Title</span>
|
||||
<span class="min-w-0 break-words">@poll.Options[index].Title</span>
|
||||
</label>
|
||||
}
|
||||
<DButton Size="DSize.Xs" Color="DColor.Primary" class="self-start" Disabled="@(IsDefaultDisabled || isActing || pollChoices.Count == 0)"
|
||||
|
||||
+12
-1
@@ -181,6 +181,15 @@ window.__fit = (() => {
|
||||
|| el.matches("input[type=checkbox], input[type=radio]") && el.closest("label") !== null
|
||||
}
|
||||
|
||||
// a control floating over the page (the round New post button) covers what scrolls under it, by design: a probe that
|
||||
// lands on one says nothing about the target's own room
|
||||
function floating(hit, el) {
|
||||
for (let a = hit; a && a !== document.body; a = a.parentElement)
|
||||
if (style(a).position === "fixed")
|
||||
return !a.contains(el)
|
||||
return false
|
||||
}
|
||||
|
||||
// a tap at this point reaches the element: on it, inside it, on its label's control, or on a label holding it
|
||||
function reaches(el, x, y) {
|
||||
const hit = document.elementFromPoint(x, y)
|
||||
@@ -223,8 +232,10 @@ window.__fit = (() => {
|
||||
for (const [dx, dy, side] of [[-21, 0, "left"], [21, 0, "right"], [0, -21, "up"], [0, 21, "down"]]) {
|
||||
const px = Math.min(clip.right - 1, Math.max(clip.left, x + dx)), py = Math.min(clip.bottom - 1, Math.max(clip.top, y + dy))
|
||||
if (!reaches(el, px, py)) {
|
||||
failed.push(side)
|
||||
const other = document.elementFromPoint(px, py)
|
||||
if (other && floating(other, el))
|
||||
continue
|
||||
failed.push(side)
|
||||
hit[side] = other ? name(other) : null
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user