Hold the time picker's two selectors apart
The 24-hour clock has no period selector beside the hour and minute boxes, so M3 widens them to 114px; AM/PM takes its own tertiary-container rather than borrowing the boxes' primary-container; a disabled period button uses M3's 12% disabled container, not 10%; and the pair is a radio group, which is what M3's labelling table asks for, so the arrows move between AM and PM. Plan step 20, findings IN-10, IN-11, IN-26 and IN-27. 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
f30fd575cf
commit
9624d4bfd4
@@ -31,14 +31,16 @@
|
||||
TimePickerTokens and TimeInputTokens — a surface-container-high dialog with an extra-large
|
||||
corner and elevation 3, a 256dp surface-container-highest dial with body-large numbers, a primary
|
||||
selector with a 48dp handle, a 2dp line and an 8dp centre, 96×80 time selector boxes in
|
||||
display-large (primary-container when selected), 96×72 time fields in display-medium — and
|
||||
TimePicker.kt and TimePickerDialog.kt for the layout, the 24-hour inner ring (12–23, at 69dp;
|
||||
00–11 outside at 101dp, as Material Components for Android labels them too), the gestures, the
|
||||
move on to minutes and the error texts. The period selector is Compose's current default
|
||||
(`isUpdatedTimepickerToggleEnabled`): two separate shape-morphing toggle buttons in
|
||||
primary-container, not the outlined pair its tokens still describe. The dial's numbers are
|
||||
aria-hidden; the dial is a `slider` whose value text names the hour or minute. The dialog is
|
||||
`wire:ignore`, so a Livewire render never closes an open picker or resets its draft. --}}
|
||||
display-large (primary-container when selected; 114dp wide on a 24-hour clock, where there is no
|
||||
period selector beside them, per TimeSelector24HVerticalContainerWidth), 96×72 time fields in
|
||||
display-medium — and TimePicker.kt and TimePickerDialog.kt for the layout, the 24-hour inner
|
||||
ring (12–23, at 69dp; 00–11 outside at 101dp, as Material Components for Android labels them
|
||||
too), the gestures, the move on to minutes and the error texts. The period selector keeps
|
||||
Compose's current default shape morph (`isUpdatedTimepickerToggleEnabled`) but M3's own
|
||||
tertiary-container, which is what holds hour/minute (primary-container) and AM/PM apart; it is a
|
||||
radio group, as M3's labelling table says, so the arrows move between AM and PM. The dial's
|
||||
numbers are aria-hidden; the dial is a `slider` whose value text names the hour or minute. The
|
||||
dialog is `wire:ignore`, so a Livewire render never closes an open picker or resets its draft. --}}
|
||||
|
||||
@props([
|
||||
'label' => null,
|
||||
@@ -211,7 +213,7 @@
|
||||
<h2 id="{{ $id }}-title" data-timepicker-title x-text="mode === 'dial' ? @js(__('Select time')) : @js(__('Enter time'))">{{ __('Select time') }}</h2>
|
||||
|
||||
<div data-timepicker-picker>
|
||||
<div data-timepicker-display>
|
||||
<div data-timepicker-display x-bind:data-cycle="is24 ? '24' : '12'">
|
||||
<div data-timepicker-numbers>
|
||||
<button
|
||||
type="button"
|
||||
@@ -236,13 +238,25 @@
|
||||
></button>
|
||||
</div>
|
||||
|
||||
<div data-timepicker-period role="group" aria-label="{{ __('Select AM or PM') }}" x-show="! is24">
|
||||
<div
|
||||
data-timepicker-period
|
||||
role="radiogroup"
|
||||
aria-label="{{ __('Select AM or PM') }}"
|
||||
x-show="! is24"
|
||||
x-on:keydown.arrow-right.prevent="movePeriod($event)"
|
||||
x-on:keydown.arrow-left.prevent="movePeriod($event)"
|
||||
x-on:keydown.arrow-down.prevent="movePeriod($event)"
|
||||
x-on:keydown.arrow-up.prevent="movePeriod($event)"
|
||||
>
|
||||
@foreach ([false => 'am', true => 'pm'] as $pm => $period)
|
||||
<button
|
||||
type="button"
|
||||
data-timepicker-period-option="{{ $period }}"
|
||||
class="state-layer focus-ring"
|
||||
x-bind:aria-pressed="({{ $pm ? '' : '! ' }}isPm).toString()"
|
||||
role="radio"
|
||||
aria-checked="false"
|
||||
x-bind:aria-checked="({{ $pm ? '' : '! ' }}isPm).toString()"
|
||||
x-bind:tabindex="({{ $pm ? '' : '! ' }}isPm) ? 0 : -1"
|
||||
x-bind:disabled="! periodAllowed({{ $pm ? 'true' : 'false' }})"
|
||||
x-on:click="setPeriod({{ $pm ? 'true' : 'false' }})"
|
||||
x-text="periods[{{ (int) $pm }}]"
|
||||
@@ -330,13 +344,25 @@
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
<div data-timepicker-period role="group" aria-label="{{ __('Select AM or PM') }}" x-show="! is24">
|
||||
<div
|
||||
data-timepicker-period
|
||||
role="radiogroup"
|
||||
aria-label="{{ __('Select AM or PM') }}"
|
||||
x-show="! is24"
|
||||
x-on:keydown.arrow-right.prevent="movePeriod($event)"
|
||||
x-on:keydown.arrow-left.prevent="movePeriod($event)"
|
||||
x-on:keydown.arrow-down.prevent="movePeriod($event)"
|
||||
x-on:keydown.arrow-up.prevent="movePeriod($event)"
|
||||
>
|
||||
@foreach ([false => 'am', true => 'pm'] as $pm => $period)
|
||||
<button
|
||||
type="button"
|
||||
data-timepicker-period-option="{{ $period }}"
|
||||
class="state-layer focus-ring"
|
||||
x-bind:aria-pressed="({{ $pm ? '' : '! ' }}isPm).toString()"
|
||||
role="radio"
|
||||
aria-checked="false"
|
||||
x-bind:aria-checked="({{ $pm ? '' : '! ' }}isPm).toString()"
|
||||
x-bind:tabindex="({{ $pm ? '' : '! ' }}isPm) ? 0 : -1"
|
||||
x-bind:disabled="! periodAllowed({{ $pm ? 'true' : 'false' }})"
|
||||
x-on:click="setPeriod({{ $pm ? 'true' : 'false' }})"
|
||||
x-text="periods[{{ (int) $pm }}]"
|
||||
|
||||
Reference in New Issue
Block a user