Add the M3 time picker

The dial and input time picker in a modal dialog, with the hour cycle
from the locale, steps, a min and max that may span midnight, and a
landscape layout, ported from Compose.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
This commit is contained in:
Andreas Reinhold / reini
2026-09-13 08:47:42 +02:00
co-authored by Claude Opus 5
parent 83ed671c4e
commit b8239dd215
12 changed files with 2092 additions and 1 deletions
+1
View File
@@ -21,6 +21,7 @@
@include('livewire-material::showcase.sections.fields')
@include('livewire-material::showcase.sections.chips')
@include('livewire-material::showcase.sections.sliders')
@include('livewire-material::showcase.sections.timepickers')
@include('livewire-material::showcase.sections.bars')
@include('livewire-material::showcase.sections.data')
</main>
+1 -1
View File
@@ -18,7 +18,7 @@
<a href="{{ route('livewire-material.showcase') }}" class="shrink-0 type-title-lg max-sm:hidden">Livewire Material</a>
<nav class="-my-2 flex min-w-0 flex-1 gap-x-4 overflow-x-auto py-2 whitespace-nowrap type-label-lg text-on-surface-variant [scrollbar-width:none]" aria-label="Sections">
@foreach (['colour' => 'Colour', 'type' => 'Type', 'shape' => 'Shape', 'elevation' => 'Elevation', 'motion' => 'Motion', 'icons' => 'Icons', 'buttons' => 'Buttons', 'menus' => 'Menus', 'communication' => 'Communication', 'progress' => 'Progress', 'containment' => 'Containment', 'carousel' => 'Carousel', 'fields' => 'Fields', 'chips' => 'Chips', 'sliders' => 'Sliders', 'bars' => 'Bars', 'data' => 'Data'] as $anchor => $section)
@foreach (['colour' => 'Colour', 'type' => 'Type', 'shape' => 'Shape', 'elevation' => 'Elevation', 'motion' => 'Motion', 'icons' => 'Icons', 'buttons' => 'Buttons', 'menus' => 'Menus', 'communication' => 'Communication', 'progress' => 'Progress', 'containment' => 'Containment', 'carousel' => 'Carousel', 'fields' => 'Fields', 'chips' => 'Chips', 'sliders' => 'Sliders', 'timepickers' => 'Time pickers', 'bars' => 'Bars', 'data' => 'Data'] as $anchor => $section)
<a href="#{{ $anchor }}" class="rounded-corner-xs hover:text-on-surface focus-ring">{{ $section }}</a>
@endforeach
</nav>
@@ -0,0 +1,44 @@
@php
$examples = [
'Time pickers: 12 and 24 hours, outlined and filled' => <<<'BLADE'
<div class="grid w-full gap-6 md:grid-cols-2">
<div class="grid content-start gap-4">
<x-timepicker label="Meeting starts" value="09:30" hint="The locale's clock" />
<x-timepicker label="Pick-up" value="17:15" format="12" icon="local_shipping" clearable />
<x-timepicker label="Disabled" value="12:00" disabled />
</div>
<div class="grid content-start gap-4">
<x-timepicker variant="filled" label="Alarm" value="06:45" format="24" icon="alarm" />
<x-timepicker variant="filled" label="Reminder" format="24" hint="Opens at the current time" />
<x-timepicker variant="filled" label="Required" format="24" required />
</div>
</div>
BLADE,
'Time pickers: steps and limits' => <<<'BLADE'
<div class="grid w-full gap-6 md:grid-cols-2">
<div class="grid content-start gap-4">
<x-timepicker label="Appointment" value="10:00" format="24" step="15" min="08:00" max="17:30" hint="Quarter hours from 08:00 to 17:30" />
<x-timepicker label="Night shift starts" value="23:00" format="24" min="22:00" max="06:00" hint="From 22:00, across midnight, to 06:00" />
</div>
<div class="grid content-start gap-4" x-data="{ time: '14:05' }">
<x-timepicker label="Bound with x-model" x-model="time" format="12" step="5" />
<p class="type-body-md text-on-surface-variant">Stored as <code x-text="time ?? 'null'"></code></p>
</div>
</div>
BLADE,
];
@endphp
<section id="timepickers" class="scroll-mt-24 space-y-6">
<h2 class="type-headline-md">Time pickers</h2>
<p class="max-w-3xl type-body-md text-on-surface-variant">
<code>&lt;x-timepicker&gt;</code> M3's dial and input time picker in a modal dialog, opened from a text field.
</p>
@foreach ($examples as $title => $code)
<x-showcase::example :$title :$code />
@endforeach
</section>