Make the OTP boxes focus the input when tapped

The overlaid OTP input has pointer-events: none so clicks land on the
decorative boxes, but that also means a tap never reached the real input
on a touchscreen (desktop got away with it via autofocus/Tab). Wrapping
the boxes in a <label for> restores focus-on-click without adding a DOM
child that would throw off the otp box count.
This commit is contained in:
2026-07-27 10:20:53 +02:00
parent 438d111718
commit 08bf76e762
2 changed files with 35 additions and 9 deletions

View File

@@ -276,6 +276,20 @@ class TwoFactorPageTests(TestCase):
self.assertEqual(otp.count("<span></span>"), 6)
def test_the_boxes_are_wrapped_in_a_label_so_tapping_focuses_the_input(self):
# daisyUI's overlaid otp input carries `pointer-events: none` (so clicks land on the
# boxes, not a naked input) — which also means a tap on the boxes never reaches the
# input directly. A <label for> is what closes that gap: browsers focus a labelled
# control on click regardless of the control's own pointer-events. Without this
# wrapper the field cannot be entered on a touchscreen, which has no Tab key to fall
# back on.
html = self.response.content.decode()
label_start = html.index('<label class="contents"')
otp_start = html.index('class="otp otp-lg"')
self.assertLess(label_start, otp_start)
self.assertIn('for="id_code"', html[label_start : label_start + 60])
def test_the_otp_field_has_no_placeholder(self):
# allauth sets placeholder="Code"; inside the boxes it reads as a typed-in code.
self.assertNotContains(self.response, 'placeholder="Code"')