From cfdb4619add03a0824328fdc8d6d303e678f0fd9 Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Mon, 14 Sep 2026 14:10:14 +0200 Subject: [PATCH] Give the password field its own stylesheet entry marks its field root data-md-password, and components/password.css brings the field and its icons (plan step 36). Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9 --- resources/css/components.css | 1 + resources/css/components/password.css | 12 ++++++++++++ resources/views/components/password.blade.php | 6 ++++-- tests/Feature/Components/FieldTest.php | 10 +++++++++- 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 resources/css/components/password.css diff --git a/resources/css/components.css b/resources/css/components.css index e9c833ec..744b244a 100644 --- a/resources/css/components.css +++ b/resources/css/components.css @@ -17,6 +17,7 @@ @import './components/form.css'; @import './components/field.css'; @import './components/input.css'; +@import './components/password.css'; /* Containment */ diff --git a/resources/css/components/password.css b/resources/css/components/password.css new file mode 100644 index 00000000..209bef3c --- /dev/null +++ b/resources/css/components/password.css @@ -0,0 +1,12 @@ +/* + * : a text field with M3's trailing eye (resources/views/components/password.blade.php). + * + * Nothing of its own to draw: the chrome and the eye, a trailing icon button, are the field's + * (components/field.css), and the eye's two glyphs are s. The field's root carries + * `data-md-password`. + */ + +@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility; + +@import './field.css'; +@import './icon.css'; diff --git a/resources/views/components/password.blade.php b/resources/views/components/password.blade.php index d5223b6f..65bf8778 100644 --- a/resources/views/components/password.blade.php +++ b/resources/views/components/password.blade.php @@ -5,7 +5,9 @@ M3's own pattern for an interactive trailing icon ("Show password" / "Hide password") — and it carries no `aria-pressed`, which would say the state a second time and the other way round. `label`, `hint`, `icon`, `variant`, `size`; every other attribute reaches the `` - (`autocomplete="current-password"`, `wire:model`). --}} + (`autocomplete="current-password"`, `wire:model`). The field's root carries + `data-md-password`; the chrome and the eye's icon button are the field's + (resources/css/components/field.css, brought by resources/css/components/password.css). --}} @props([ 'label' => null, @@ -25,7 +27,7 @@ $fieldIconSize = ['sm' => 20, 'xs' => 16][$size] ?? 24; @endphp - + except(['class', 'id', 'type', 'placeholder']) }} id="{{ $id }}" diff --git a/tests/Feature/Components/FieldTest.php b/tests/Feature/Components/FieldTest.php index d7ddeb7a..8a7a8007 100644 --- a/tests/Feature/Components/FieldTest.php +++ b/tests/Feature/Components/FieldTest.php @@ -97,7 +97,8 @@ it('lets a password be shown and hidden again', function () { ->toContain('type="password"') ->not->toContain('type="text"') ->toContain('x-bind:type="shown ? \'text\' : \'password\'"') - ->toContain('data-md-field-reveal') + ->toContain('data-md-password') + ->toMatch('/]*data-md-field-button)(?=[^>]*data-md-field-reveal)[^>]*>/') ->toContain('aria-label="Show password"') // The flipping label already says the state; aria-pressed would say it again, inverted. ->not->toContain('aria-pressed') @@ -246,3 +247,10 @@ it('gives the one-line field a stylesheet that brings the field and its icons', ->toContain("@import './icon.css';") ->and((string) file_get_contents(__DIR__.'/../../../resources/css/components.css'))->toContain("@import './components/input.css';"); }); + +it('gives the password field a stylesheet that brings the field and its icons', function () { + expect((string) file_get_contents(__DIR__.'/../../../resources/css/components/password.css')) + ->toContain("@import './field.css';") + ->toContain("@import './icon.css';") + ->and((string) file_get_contents(__DIR__.'/../../../resources/css/components.css'))->toContain("@import './components/password.css';"); +});