Finish the keyboards, and say a state once
Shift+M and Shift+Y reach the month and year dropdowns, which is M3's date picker keyboard table; Home and End go to the ends of an open combobox list, and stay the field's own caret keys when it is closed. The password reveal drops aria-pressed and keeps only its flipping label, so a screen reader hears the state once rather than twice and inverted. The radio's `inline` now says that M3 cautions against a row and wants an option chosen on load. Plan step 20, findings IN-22, IN-23, IN-28 and IN-29. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
856b6f476b
commit
0074f9bd5c
@@ -18,8 +18,11 @@
|
||||
*
|
||||
* The keyboard is WAI-ARIA's date picker dialog: arrows move a day or a week, Home and End go to
|
||||
* the start and end of the week, PageUp and PageDown a month (with Shift a year), Space selects,
|
||||
* Enter selects and confirms, Escape closes and hands focus back to the field. Focus never leaves
|
||||
* the `min`–`max` span, so a disabled day cannot be chosen from the keyboard either.
|
||||
* Enter selects and confirms, Escape closes and hands focus back to the field. M3's own table says
|
||||
* Home and End "move to the first day of the month"; the APG behaviour is the stronger web
|
||||
* convention and is what this keeps. Shift+M and Shift+Y are M3's, and reach the month and year
|
||||
* dropdowns. Focus never leaves the `min`–`max` span, so a disabled day cannot be chosen from the
|
||||
* keyboard either.
|
||||
*/
|
||||
import { upTo } from './breakpoints.js'
|
||||
|
||||
@@ -576,11 +579,33 @@ document.addEventListener('alpine:init', () => {
|
||||
return config.range ? value.start : value
|
||||
},
|
||||
|
||||
/**
|
||||
* The month or the year dropdown, whichever of them this presentation draws: the docked
|
||||
* picker has one of each, the modal picker a single button that opens the years.
|
||||
*/
|
||||
menuButton(view) {
|
||||
const buttons = [...this.$refs.dialog.querySelectorAll('[data-datepicker-menu-button]')].filter((button) => button.getClientRects().length > 0)
|
||||
|
||||
return buttons.find((button) => button.dataset.datepickerMenuButton === view) ?? buttons[0] ?? null
|
||||
},
|
||||
|
||||
gridKey(event) {
|
||||
const rtl = getComputedStyle(this.$refs.dialog).direction === 'rtl'
|
||||
const focused = this.focused
|
||||
const column = (utc(...parts(focused)).getUTCDay() - this.firstDay + 7) % 7
|
||||
|
||||
// M3's keyboard table: Shift+M moves to the month dropdown, Shift+Y to the year one.
|
||||
if (event.shiftKey && !event.ctrlKey && !event.metaKey && !event.altKey && ['M', 'Y'].includes(event.key.toUpperCase())) {
|
||||
const button = this.menuButton(event.key.toUpperCase() === 'M' ? 'months' : 'years')
|
||||
|
||||
if (button) {
|
||||
event.preventDefault()
|
||||
button.focus()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const target = {
|
||||
ArrowRight: () => addDays(focused, rtl ? -1 : 1),
|
||||
ArrowLeft: () => addDays(focused, rtl ? 1 : -1),
|
||||
|
||||
Reference in New Issue
Block a user