Drop the gradient focus ring, which doubled every field's left edge

The doubled edge was not the textarea's alone -- it was on every field,
and the previous commit's explanation of why the inputs were exempt was
wrong. I asserted that at 999px the ring and the outline clamp to the
same curve without measuring it. They do not:

  ring     999px -> a 24px circle      (half the field's height)
  outline  999px -> a 12x24 ellipse    (leading piece width x half height)

The ring is one continuous rounded rectangle over the whole field; the
outline beneath it is split into three pieces and its leading piece is
12px wide. No radius makes a full-width curve agree with a 12px-wide
one, so there was nothing to tune -- the ring had to go. It was mine,
lifted from the library's `gradient` theme onto a shell that does not
use it, and `alternative` already expresses focus through the outline's
own colour.

The textarea's radius goes back to 1.25rem, since it was only lowered to
dodge the clamp.

Verified at 3x, one curve per field: valid+focus violet, error+focus
red, no ring anywhere.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
pigui
2026-08-31 14:06:59 +02:00
parent 4d2a8dd26b
commit 7bb40d32f1
2 changed files with 12 additions and 41 deletions

View File

@@ -84,18 +84,11 @@
font-weight: var(--pi-theme-field-label-weight, inherit); font-weight: var(--pi-theme-field-label-weight, inherit);
} }
// 10px, not the 20px this started at, and the reason is clamping. // A stadium is right for a 48px input and wrong for a 112px textarea, which
// // is all this is now — with the focus ring gone there is no second shape to
// The outline's leading piece is only 12px wide, so a 20px corner radius gets // agree with.
// clamped to 12 — while the focus ring, drawn across the full width, keeps a
// true 20px curve. Same box, same declared radius, two different curves, and
// a visibly doubled edge down the left side. Under 12px nothing is clamped
// and the two agree.
//
// The single-line fields never showed this: at 999px both the outline and the
// ring clamp to half the field's height, so they land on the same curve.
.pi-field.pi-form-field__textarea { .pi-field.pi-form-field__textarea {
--pi-theme-field-radius: 0.625rem; --pi-theme-field-radius: 1.25rem;
} }
} }
@@ -137,20 +130,3 @@
font-size: var(--pi-font-size-x-small, 0.75rem); font-size: var(--pi-font-size-x-small, 0.75rem);
} }
} }
// Focusing a field that already has an error drew it twice: the notched
// outline stays in the error colour, and the gradient focus ring is painted on
// top of it in the brand's violet-to-cyan. Two rings, two colours, one field —
// and on the textarea, at two different radii, which is what made it obvious.
//
// The ring is worth keeping: it is how focus reads on every other field. It
// just has to agree with the state it is decorating, so while the field is
// invalid the ring is built from the warn colour instead of the brand one. The
// field ends up with a single red indication that still brightens on focus.
:host ::ng-deep .pi-field .mat-form-field-invalid {
--pi-theme-field-focus-gradient: linear-gradient(
120deg,
var(--pi-color-warn),
var(--pi-color-warn-200, var(--pi-color-warn))
);
}

View File

@@ -92,19 +92,14 @@ html {
@include brand-ramp('highlighted', #6c2fb5, #ffffff); @include brand-ramp('highlighted', #6c2fb5, #ffffff);
} }
// The `gradient` theme's signature — a gradient focus ring on fields — is a // The `gradient` theme's focus ring is deliberately NOT lifted onto this shell.
// token, so it can be lifted onto the `alternative` shell without swapping //
// themes. `_mat-form-field.scss` reads it; the flat border is turned off so it // It is drawn as one continuous rounded rectangle over the whole field, while
// does not show through the ring. // the outline underneath is split into three pieces. The leading piece is 12px
.pi-shell__alternative { // wide, so a large radius clamps to a 12x24 ellipse there while the ring keeps
--pi-theme-field-focus-gradient: linear-gradient( // a true 24px circle — two curves that cannot be made to agree at any radius,
120deg, // showing as a doubled edge down the left of every field. Focus is left to the
var(--pi-color-primary), // outline's own colour, which is what `alternative` already defines.
var(--pi-color-accent),
var(--pi-color-highlighted)
);
--pi-theme-field-border-color-focus: transparent;
}
html, html,
body { body {